-
Notifications
You must be signed in to change notification settings - Fork 365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Downstream QUIC/HTTP3 Support #2111
Conversation
81a92c0
to
8a6b240
Compare
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #2111 +/- ##
==========================================
+ Coverage 64.54% 64.58% +0.04%
==========================================
Files 112 112
Lines 15949 16072 +123
==========================================
+ Hits 10294 10380 +86
- Misses 5007 5040 +33
- Partials 648 652 +4 ☔ View full report in Codecov by Sentry. |
thanks for building this out @tanujd11 ! , will start reviewing this post the v0.6 release |
hey @LanceEa can you help review this one ( since you have experience building this out before :) ) |
// EnableHTTP3 enables HTTP/3 support on the listener. | ||
// Disabled by default. | ||
// +optional | ||
EnableHTTP3 bool `json:"enableHTTP3,omitempty"` |
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.
lets make this *bool
since its optional
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.
I would recommend making it an object instead of a bool
. This will future proof you more to provide addtional overrides.
For example, in the generated config you have AlpnProtocols: []string{"h3"}
hard coded. Not all clients will recognize or support that. If you look at a simple google home page you can see their web server is configured to support h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
.
Other examples, are setting different ports to listen for the QUIC traffic on because many cloud providers do not support listening on the same incoming address. TBH, this is the tricky part to setting up H3 and the Envoy config is quite straight forward.
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.
Note: you could start with an empty object and check for existence or not if you want to hold off on allow customizations right away but at least an object future proofs you to add going forward without breaking changes.
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.
I would love to just have a enable knob, but agree with @LanceEa, an empty struct maybe a good call for this API because some user may want to modify the listening port, and everyone loves tweaking port values to adhere with corp perimeter policies
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.
I will defer to the maintainers on code coverage and general style but for the most part it looks good. I have left some feedback on the design and recommendations for future proofing it because support for mixedprotocols on the LoadBalancer Service and cloud vendors was limited last I looked.
// EnableHTTP3 enables HTTP/3 support on the listener. | ||
// Disabled by default. | ||
// +optional | ||
EnableHTTP3 bool `json:"enableHTTP3,omitempty"` |
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.
I would recommend making it an object instead of a bool
. This will future proof you more to provide addtional overrides.
For example, in the generated config you have AlpnProtocols: []string{"h3"}
hard coded. Not all clients will recognize or support that. If you look at a simple google home page you can see their web server is configured to support h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
.
Other examples, are setting different ports to listen for the QUIC traffic on because many cloud providers do not support listening on the same incoming address. TBH, this is the tricky part to setting up H3 and the Envoy config is quite straight forward.
// EnableHTTP3 enables HTTP/3 support on the listener. | ||
// Disabled by default. | ||
// +optional | ||
EnableHTTP3 bool `json:"enableHTTP3,omitempty"` |
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.
Note: you could start with an empty object and check for existence or not if you want to hold off on allow customizations right away but at least an object future proofs you to add going forward without breaking changes.
|
||
proxyListener := &ir.ProxyListener{ | ||
Name: irHTTPListenerName(listener), | ||
Ports: []ir.ListenerPort{infraPort}, |
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.
If I'm understanding this correctly we are only supporting a single port for this listener and then using the HTTP/3 flag to instruct the single ir.ProxyListener to generate a secondary listener for UDP/QUIC. This means the second listener would inherit the port correct?
If so you are more than likely going to want to allow that to be configurable because most cloud vendors were not supporting this last I knew (6+ months ago was the last time I looked so could have changed)
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.
This comment is referring to mixed protocols on a single Service of type Loadbalancer
.
Append: &wrapperspb.BoolValue{Value: true}, | ||
Header: &corev3.HeaderValue{ | ||
Key: "alt-svc", | ||
Value: strings.Join([]string{fmt.Sprintf(`%s=":%d"; ma=86400`, "h3", port)}, ", "), |
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.
You are going to want this to be configurable in the future, see my previous comment on the design of the ClientTrafficPolicy.
- append: true | ||
header: | ||
key: alt-svc | ||
value: h3=":10443"; ma=86400 |
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.
This port needs to be the port exposed externally outside the cluster to the client. So, in most cases involving a browser it is more than likely going to be :443
and not the listener port. The LoadBalancer of type Service
then needs to point traffic to 10443. That is what I was referring to as the tricky part because a single Service doesn't always allow for MixedProtocol. note: that might have change since last time I looked into this but it is the more nuanced part to the setup.
8a6b240
to
62082e2
Compare
62082e2
to
4b1c286
Compare
Also it would be great if someone from @envoyproxy/gateway-reviewers / @envoyproxy/gateway-maintainers can try out the feature |
/retest |
1 similar comment
/retest |
if httpIR.TLS != nil && policySpec.HTTP3 != nil { | ||
httpIR.HTTP3 = &ir.HTTP3Settings{} | ||
var proxyListenerIR *ir.ProxyListener | ||
for _, proxyListener := range infraIR[irKey].Proxy.Listeners { |
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: can we reuse irListenerName
and also check if irListenerName.Proxy != 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.
Hi, I did not get this point. It seems irListenerName is a string. I need to get infraIR from the corresponding IrListenerName that's why I iterated listeners for a gateway.
@@ -20,7 +20,7 @@ func TestValidateInfra(t *testing.T) { | |||
{ | |||
name: "default", | |||
infra: NewInfra(), | |||
expect: false, | |||
expect: true, |
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.
why is this true
?
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.
As we removed NewProxyListener by default and only add it when needed(Since we replaced only 1 listener supported to multiple listener), there is no error generated in this test case, hence false. Before any empty listener was there which failed the validate function.
@@ -80,6 +80,18 @@ func (r *ResourceRender) Service() (*corev1.Service, error) { | |||
TargetPort: target, | |||
} | |||
ports = append(ports, p) | |||
|
|||
if port.Protocol == ir.HTTPSProtocolType { |
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.
should this live here on in the Gateway API layer ?
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.
This is for opening UDP ports for only those ports which have HTTPS configured, That's a requirement for quic. So this condition is added here.
@@ -137,6 +163,10 @@ func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irL | |||
} | |||
} | |||
|
|||
if http3Listener { | |||
mgr.CodecType = hcmv3.HttpConnectionManager_HTTP3 |
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.
will auto work ?
is there a way for us to support http3 but also support something else in case the client doesnt support it ?
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.
Hi Arko, If HTTP3 is not supported then the other listener will be used. We have created a mirror UDP listener and the connection would be upgraded to HTTP3 according to the alt-svc header. So even if HTTP3 is not supported HTTP/HTTP2 will be used
internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml
Outdated
Show resolved
Hide resolved
/retest |
1 similar comment
/retest |
Hi @arkodg , welcome back from the vacation. Your reviews on this will be greatly appreciated. Thanks. |
🚀 Deployed on https://gateway-pr-2111-preview--eg-preview.netlify.app |
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.
LGTM, thanks for adding this feature !
Signed-off-by: tanujd11 <[email protected]>
Signed-off-by: tanujd11 <[email protected]>
Signed-off-by: tanujd11 <[email protected]>
Signed-off-by: tanujd11 <[email protected]>
Signed-off-by: tanujd11 <[email protected]>
Signed-off-by: tanujd11 <[email protected]>
Signed-off-by: tanujd11 <[email protected]>
50250c3
to
83cbc59
Compare
/retest |
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.
Great! Thanks for working on it : )
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.
lgtm
/cc @arkodg |
What type of PR is this?
Feature
What this PR does / why we need it:
Adds HTTP3 support in envoy gateway
Which issue(s) this PR fixes:
Fixes #422