From 4add125beb3b3dc53fecca5d2332a3cfa6c392e8 Mon Sep 17 00:00:00 2001 From: andyvandy Date: Wed, 8 Apr 2026 22:00:04 -0400 Subject: [PATCH 1/2] Migrate kubectl exec to WebSockets from SPDY Per [KEP-4006](https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/4006-transition-spdy-to-websockets), prioritize trying WebSockets first given it has been the default for 4 versions now and will be the standard going forward. Use a NewFallbackExecutor as is suggested in the KEP to avoid breaking existing use cases. --- pkg/driver/kubernetes/client.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pkg/driver/kubernetes/client.go b/pkg/driver/kubernetes/client.go index d5aeb8b0a3..615e91807f 100644 --- a/pkg/driver/kubernetes/client.go +++ b/pkg/driver/kubernetes/client.go @@ -7,6 +7,7 @@ import ( "os" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" @@ -115,7 +116,16 @@ func (c *Client) Exec(ctx context.Context, options *ExecStreamOptions) error { Stderr: options.Stderr != nil, }, scheme.ParameterCodec) - exec, err := remotecommand.NewSPDYExecutor(c.config, "POST", execRequest.URL()) + // Use WebSocket executor which is the default as of Kubernetes 1.31. Fall back to SPDY for older clusters. + websocketExec, err := remotecommand.NewWebSocketExecutor(c.config, "GET", execRequest.URL().String()) + if err != nil { + return err + } + spdyExec, err := remotecommand.NewSPDYExecutor(c.config, "POST", execRequest.URL()) + if err != nil { + return err + } + exec, err := remotecommand.NewFallbackExecutor(websocketExec, spdyExec, httpstream.IsUpgradeFailure) if err != nil { return err } From 2b0cedf9ece7b94baa53dee3abf3838303b074a3 Mon Sep 17 00:00:00 2001 From: andyvandy Date: Tue, 19 May 2026 21:27:59 -0400 Subject: [PATCH 2/2] Include SDPY fallback handling for HTTPSProxy Errors pick up the same additional error handling that was introduced by this commit to the kubectl client. https://github.com/kubernetes/kubectl/commit/2c588bc5edf38e0e0627ccaf5f23856b7bdb1ee5 Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- pkg/driver/kubernetes/client.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/driver/kubernetes/client.go b/pkg/driver/kubernetes/client.go index 615e91807f..8d1112634d 100644 --- a/pkg/driver/kubernetes/client.go +++ b/pkg/driver/kubernetes/client.go @@ -125,7 +125,9 @@ func (c *Client) Exec(ctx context.Context, options *ExecStreamOptions) error { if err != nil { return err } - exec, err := remotecommand.NewFallbackExecutor(websocketExec, spdyExec, httpstream.IsUpgradeFailure) + exec, err := remotecommand.NewFallbackExecutor(websocketExec, spdyExec, func(err error) bool { + return httpstream.IsUpgradeFailure(err) || httpstream.IsHTTPSProxyError(err) + }) if err != nil { return err }