-
Notifications
You must be signed in to change notification settings - Fork 100
support http2 protocol (#1523) #2306
Changes from 1 commit
f1e3179
160eab9
02b82ac
3e0e94f
7ca4aa3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
package service | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/acorn-io/baaah/pkg/router" | ||
v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" | ||
"github.com/acorn-io/runtime/pkg/ports" | ||
"github.com/acorn-io/runtime/pkg/publish" | ||
"github.com/acorn-io/runtime/pkg/services" | ||
) | ||
|
@@ -13,25 +16,58 @@ func RenderServices(req router.Request, resp router.Response) error { | |
// reset, should get repopulated | ||
svcInstance.Status.Endpoints = nil | ||
|
||
objs, _, err := services.ToK8sService(req, svcInstance) | ||
if err != nil { | ||
return err | ||
} | ||
resp.Objects(objs...) | ||
svcInstance.Status.HasService = len(objs) > 0 | ||
var svcList []*v1.ServiceInstance | ||
http2Ports := ports.ByProtocol(svcInstance.Spec.Ports, true, v1.ProtocolHTTP2) | ||
StrongMonkey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
httpPorts := ports.ByProtocol(svcInstance.Spec.Ports, true, v1.ProtocolHTTP) | ||
// If we have both types of ports we need to create a separate service with the annotation | ||
if len(http2Ports) > 0 && len(httpPorts) > 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll put some explanation on this, since we paired up to work on this yesterday and I still feel like this is a good and simple solution that can be a little confusing. The background is that we have to put a traefik annotation on the K8s Service for http2 support (h2c). With that service we'd break the traffic for "normal" http traefik to other ports listed in that service though. However, all the code further down the stream is specific to a single service and even re-uses the ServiceInstance name in a lot of places. The DeepCopies are necessary to leave the original serviceInstance object untouched during that process and we only have to populated actively modified status fields on it. |
||
svcCopy := svcInstance.DeepCopy() | ||
svcCopy.Spec.Ports = ports.ByProtocol(svcInstance.Spec.Ports, false, v1.ProtocolHTTP2) // filter out http2 ports | ||
svcList = append(svcList, svcCopy) | ||
|
||
objs, err = publish.ServiceLoadBalancer(req, svcInstance) | ||
if err != nil { | ||
return err | ||
svcCopyHttp2 := svcInstance.DeepCopy() | ||
svcCopyHttp2.Spec.Ports = http2Ports | ||
svcCopyHttp2.Name = fmt.Sprintf("%s-%s", svcInstance.Name, v1.ProtocolHTTP2) | ||
if svcCopyHttp2.Spec.Annotations == nil { | ||
svcCopyHttp2.Spec.Annotations = map[string]string{} | ||
} | ||
svcCopyHttp2.Spec.Annotations["traefik.ingress.kubernetes.io/service.serversscheme"] = "h2c" | ||
svcList = append(svcList, svcCopyHttp2) | ||
} else if len(http2Ports) > 0 { | ||
svcCopyHttp2 := svcInstance.DeepCopy() | ||
if svcCopyHttp2.Spec.Annotations == nil { | ||
svcCopyHttp2.Spec.Annotations = map[string]string{} | ||
} | ||
svcCopyHttp2.Spec.Annotations["traefik.ingress.kubernetes.io/service.serversscheme"] = "h2c" | ||
svcList = append(svcList, svcCopyHttp2) | ||
} else { | ||
svcList = []*v1.ServiceInstance{svcInstance} | ||
} | ||
resp.Objects(objs...) | ||
svcInstance.Status.HasService = svcInstance.Status.HasService || len(objs) > 0 | ||
|
||
objs, err = publish.Ingress(req, svcInstance) | ||
if err != nil { | ||
return err | ||
for _, svc := range svcList { | ||
objs, _, err := services.ToK8sService(req, svc) | ||
if err != nil { | ||
return err | ||
} | ||
resp.Objects(objs...) | ||
svcInstance.Status.HasService = svcInstance.Status.HasService || len(objs) > 0 | ||
|
||
objs, err = publish.ServiceLoadBalancer(req, svc) | ||
if err != nil { | ||
return err | ||
} | ||
resp.Objects(objs...) | ||
svcInstance.Status.HasService = svcInstance.Status.HasService || len(objs) > 0 | ||
|
||
objs, err = publish.Ingress(req, svc) | ||
if err != nil { | ||
return err | ||
} | ||
resp.Objects(objs...) | ||
|
||
// Copy all modifications made by the above publish.Ingress call | ||
svcInstance.Status.Endpoints = append(svcInstance.Status.Endpoints, svc.Status.Endpoints...) | ||
} | ||
resp.Objects(objs...) | ||
|
||
resp.Objects(svcInstance) | ||
return nil | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: all of these cases can be put on the same line: