-
Notifications
You must be signed in to change notification settings - Fork 360
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
api: Enable controlling the HTTP version used to connect to the backend #2433
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2433 +/- ##
==========================================
+ Coverage 66.51% 66.82% +0.31%
==========================================
Files 161 163 +2
Lines 22673 23274 +601
==========================================
+ Hits 15080 15554 +474
- Misses 6720 6812 +92
- Partials 873 908 +35 ☔ View full report in Codecov by Sentry. |
hey @liorokman can you raise a GH issue to define the use case ? would like to get input from the community to be understand if this is needed or not |
Opened #2437 |
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. Please feel free to give a status update now, ping for review, when it's ready. Thank you for your contributions! |
/retest |
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. Please feel free to give a status update now, ping for review, when it's ready. Thank you for your contributions! |
b0442cf
to
6804cf9
Compare
LGTM. Maybe we need to update the description with an up-to-date example of the API. |
Done |
@@ -98,6 +103,15 @@ type BackendTrafficPolicySpec struct { | |||
Compression []*Compression `json:"compression,omitempty"` | |||
} | |||
|
|||
type HTTPOptions struct { | |||
// UseClientProtocol configures Envoy to prefer sending requests to TLS enabled backends using |
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.
can you elaborate on why preference this given to TLS enabled backend ?
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.
The goal is to use Envoy Proxy's use_downstream_protocol_config feature.
If the underlying transport socket supports TLS, it also supports ALPN. This makes it possible for Envoy to try to use both HTTP/1.1 and HTTP/2 as needed when connecting to it. If TLS is not enabled, then Envoy Proxy will either use HTTP/1.1 or HTTP/2. This means that if the downstream client is using the "wrong" protocol, the connection will simply fail.
It's easier to restrict this feature to TLS enabled upstreams where selection can be done based on ALPN than to try to force the downstream to have the right protocol. Fixing the client protocol selection is hard because:
-
If the Gateway has multiple HTTPRoutes, each one to a different upstream cluster with different supported protocols, then it's not possible to fix the Listener level ALPN array correctly. The route to be used is based on things that come later (e.g. the request path), so it's possible that one HTTPRoute has an upstream that supports only HTTP/2 and is matched on the
/first
path, while the other HTTPRoute attached to the same Gateway supports only HTTP/1.1 and is matched on the/second
path. Envoy can't know which path is going to be used before the protocol is selected and the request actually sent to Envoy, and by that point it's too late to change the protocol. -
If the downstream socket (the Gateway) is not TLS enabled, then there's no ALPN available to affect the client's selection anyways, and there would be a large chance of a misconfiguration that makes some HTTPRoutes unusable.
@@ -98,6 +103,15 @@ type BackendTrafficPolicySpec struct { | |||
Compression []*Compression `json:"compression,omitempty"` | |||
} | |||
|
|||
type HTTPOptions struct { |
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.
there are already some HTTP only fields at the top level like FaultInjection
, so vote to keep this at a top level
will bring this up in the next envoy gateway community meeting
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.
OK. Will wait for the decision before changing this PR.
@@ -98,6 +103,15 @@ type BackendTrafficPolicySpec struct { | |||
Compression []*Compression `json:"compression,omitempty"` | |||
} | |||
|
|||
type HTTPOptions struct { | |||
// UseClientProtocol configures Envoy to prefer sending requests to TLS enabled backends using | |||
// the same HTTP protocol that the incoming request used. Defaults to false, which means |
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.
prefer if we added a line in here saying something along the lines of - this is especially useful when the client (connecting to the gateway) and backend support multiple HTTP versions (e.g. http/1.1 and http/2), and users would like to force the backend to use the same version the client is using
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.
OK. Effectively this means that the backend must be TLS enabled, or it can't support multiple HTTP versions.
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.
can you elaborate on how TLS / ALPN is related here ?
as far as in understand, this knob is proactively deciding the upstream protocol version to use based on downstream connection, so it even applies to non TLS (like h2c to upstream, if downstream is h2c or h2)
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.
A backend without TLS will either support HTTP/1.1 or HTTP/2, but never both. That's the point of h2c
- it requires pre-knowledge on the part of the client that the server requires HTTP/2.
Since HTTP/2 is a binary protocol, if a client like Envoy Proxy starts a connection by sending a textual HTTP/1.1 request to an HTTP/2 over clear-text server, the server will disconnect it.
Since HTTP/1.1 is a textual protocol, if a client like Envoy Proxy starts a connection by sending an HTTP/2 cleartext request to an HTTP/1.1 server, the server will disconnect it.
Without TLS + ALPN, there is no way for a client like Envoy Proxy to negotiate with the server which protocol it can use, and this means that effectively upstream can't support multiple versions of HTTP without TLS+ALPN.
(like h2c to upstream, if downstream is h2c or h2)
We can configure the Envoy Proxy client to try to connect to upstream with the downstream protocol even without TLS on the upstream protocol. What it would do is automatically fail all requests where the downstream protocol doesn't match the single upstream protocol that is possible without upstream TLS.
Signed-off-by: Lior Okman <lior.okman@sap.com>
community meetings. Signed-off-by: Lior Okman <lior.okman@sap.com>
API. Signed-off-by: Lior Okman <lior.okman@sap.com>
upstream TLS backend. Signed-off-by: Lior Okman <lior.okman@sap.com>
02a6dd1
to
2f20364
Compare
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 !
What this PR does / why we need it:
This PR proposes adding an API to control the HTTP version that will be used when connecting to a backend configured via an
HTTPRoute
.The current behavior is that HTTP/2 is explicitly used if the route is a GRPC route, and it's possible to force HTTP/2-over-cleartext (
h2c
) by setting theappProtocol
field in the backend Kubernetes Service tokubernetes.io/h2c
. In all other cases EnvoyGateway generates configuration that forces HTTP/1.1 to the upstream.The proposed API would allow configuring Envoy Proxy to use the same HTTP protocol version when connecting to the backend as was used by the downstream client.