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
Aggregator uses the regular transport when handling upgrade requests #104985
Aggregator uses the regular transport when handling upgrade requests #104985
Conversation
/triage accepted |
/cc @deads2k |
4843ab7
to
2f40c5b
Compare
@@ -178,6 +174,8 @@ func (r *proxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { | |||
} | |||
|
|||
handler := proxy.NewUpgradeAwareHandler(location, proxyRoundTripper, true, upgrade, &responder{w: w}) | |||
handler.InterceptRedirects = utilfeature.DefaultFeatureGate.Enabled(genericfeatures.StreamingProxyRedirects) | |||
handler.RequireSameHostRedirects = utilfeature.DefaultFeatureGate.Enabled(genericfeatures.ValidateProxyRedirects) |
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.
These two flags only affect upgraded requests. I added them here because the removed maybeWrapForConnectionUpgrades
function used to set them for the SPDY transport.
They should have no effect as they are deprecated in 1.22 (kubernetes/enhancements#1558). I keep them just for consistency.
/cc @jkh52 |
2f40c5b
to
224bcf6
Compare
followRedirects := utilfeature.DefaultFeatureGate.Enabled(genericfeatures.StreamingProxyRedirects) | ||
requireSameHostRedirects := utilfeature.DefaultFeatureGate.Enabled(genericfeatures.ValidateProxyRedirects) | ||
upgradeRoundTripper := spdy.NewRoundTripper(tlsConfig, followRedirects, requireSameHostRedirects) | ||
wrappedRT, err := restclient.HTTPWrappersForConfig(restConfig, upgradeRoundTripper) |
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.
doesn't this call set up the front proxy headers for the connections we re-establish?
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.
Is the front proxy header
the same as the auth proxy headers that are set here? Since we now use the same proxyRoundTripper
to handle both upgrade/non-upgrade requests, those auth proxy headers are applied to upgrade requests as well.
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.
Thanks. yes, that's the one I was looking for.
I think that this is the key, no? |
@aojea I don't think aggregator->aggregated needs SPDY at any time. Even if the client request contains upgrade headers, aggregator's job is i) establishing a transport layer connection to the aggregated API server, ii) using http hijacking to get control of the transport layer connection from the client, and iii) then stitching these two connections together to form a tunnel. Aggregator itself does not need to understand SPDY. Only the client and the aggregated API server need to speak SPDY. |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: caesarxuchao, deads2k The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
it's missing the release note @caesarxuchao :) |
Thanks, @aojea |
shouldn't there be a test exercising the issue this is fixing? |
Yeah, there should be a test :) I had thought of two ways to test this but both seemed to be a lot of work. Approach 1, we expand the sampleapiserver to handle websocket/spdy, then we exercise the upgrades in the existing aggregator e2e tests. Approach 2, in the e2e test, we deploy the I think approach 1 makes more sense. Definitely please let me know if you see a cheaper 3rd option. |
we've done upgrade proxy testing before in unit tests (e.g. in staging/src/k8s.io/apimachinery/pkg/util/proxy/upgradeaware_test.go)... my first thought would be to try to capture the heart of the bug in a unit test that exercises both the custom dialer (should fail on master) and direct dialer (should pass on master) cases, then make sure this PR fixes the custom dialer case and doesn't break the direct dialer case |
@liggitt @caesarxuchao let me see if I can do it, that sounds like a good opportunity to me to get familiar with this code |
@aojea thanks for offering help. Free free to ping me on Slack (handler is also "caesarxuchao") when you have a PR. |
} | ||
proxyRoundTripper := handlingInfo.proxyRoundTripper | ||
upgrade := httpstream.IsUpgradeRequest(req) | ||
|
||
proxyRoundTripper = transport.NewAuthProxyRoundTripper(user.GetName(), user.GetGroups(), user.GetExtra(), proxyRoundTripper) | ||
|
||
// if we are upgrading, then the upgrade path tries to use this request with the TLS config we provide, but it does |
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.
is this comment / block still accurate with this change? commenting out the transport.SetAuthProxyHeaders
line doesn't fail any unit tests before or after this PR, so it's unclear whether it is needed / effective
/sig api-machinery
/kind bug
/assign
/release-note none
Currently aggregator creates a SPDY transport to the remote if the request contains upgrade headers. This seems wrong to me:
This PR let's the aggregator use the original normal transport for upgrade requests. As a side-effect, this fixes #71808, which points out that that the SPDY transport doesn't honor the custom dialer in the original transport. The consequence of #71808 is that upgraded requests to aggregated APIs do not work if SSH tunnels or Konnectivity is used. A real life issue we met is that virtctl console(similar to
kubectl exec
) doesn't work when Konnectivity is used. We verified that this PR fixed thevirtctl console
use case.Side note: how upgrade requests for aggregated apis worked with the SPDY transport when there was NO ssh tunnels or konnectivity involved
It worked because SPDY transport was only used here:
kubernetes/staging/src/k8s.io/apimachinery/pkg/util/proxy/dial.go
Lines 38 to 41 in 35ae8c9
utilnet.DialerFor
will return an empty dialer and error, because it doesn't recognize a SPDY transport.dialURL
then uses the default golang net.Dialer. So the SPDY transport never actually gets used.(Supersedes #104763)
Fixes #71808