From dc59c0246fb407dcf035afc224f63fcf0da8244e Mon Sep 17 00:00:00 2001 From: Wei Fu Date: Wed, 12 Feb 2025 21:39:59 -0500 Subject: [PATCH] proxy: should add PingPeriod for websocket translator IIUC, before using the translator handler, the ping data can be delivered from the client to the runtime side since kube-apiserver does not parse any client data. However, with WebSocket, the server responds with a pong to the client without forwarding the data to the runtime side. If a proxy is present, it may close the connection due to inactivity. SPDY's PingPeriod can help address this issue. Signed-off-by: Wei Fu Co-authored-by: Antonio Ojea --- .../apiserver/pkg/util/proxy/streamtranslator.go | 3 ++- test/e2e/kubectl/kubectl.go | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/staging/src/k8s.io/apiserver/pkg/util/proxy/streamtranslator.go b/staging/src/k8s.io/apiserver/pkg/util/proxy/streamtranslator.go index 6dabc1c7b4a..6593a3ed966 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/proxy/streamtranslator.go +++ b/staging/src/k8s.io/apiserver/pkg/util/proxy/streamtranslator.go @@ -21,6 +21,7 @@ import ( "net/http" "net/url" "strconv" + "time" "github.com/mxk/go-flowrate/flowrate" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -70,7 +71,7 @@ func (h *StreamTranslatorHandler) ServeHTTP(w http.ResponseWriter, req *http.Req defer websocketStreams.conn.Close() // Creating SPDY executor, ensuring redirects are not followed. - spdyRoundTripper, err := spdy.NewRoundTripperWithConfig(spdy.RoundTripperConfig{UpgradeTransport: h.Transport}) + spdyRoundTripper, err := spdy.NewRoundTripperWithConfig(spdy.RoundTripperConfig{UpgradeTransport: h.Transport, PingPeriod: 5 * time.Second}) if err != nil { websocketStreams.writeStatus(apierrors.NewInternalError(err)) //nolint:errcheck metrics.IncStreamTranslatorRequest(req.Context(), strconv.Itoa(http.StatusInternalServerError)) diff --git a/test/e2e/kubectl/kubectl.go b/test/e2e/kubectl/kubectl.go index 7012a7c7b0b..5017d45f062 100644 --- a/test/e2e/kubectl/kubectl.go +++ b/test/e2e/kubectl/kubectl.go @@ -501,6 +501,16 @@ var _ = SIGDescribe("Kubectl client", func() { } }) + // https://issues.k8s.io/128314 + f.It(f.WithSlow(), "should support exec idle connections", func(ctx context.Context) { + ginkgo.By("executing a command in the container") + + execOutput := e2ekubectl.RunKubectlOrDie(ns, "exec", podRunningTimeoutArg, simplePodName, "--", "/bin/sh", "-c", "sleep 320 && echo running in container") + if expected, got := "running in container", strings.TrimSpace(execOutput); expected != got { + framework.Failf("Unexpected kubectl exec output. Wanted %q, got %q", expected, got) + } + }) + ginkgo.It("should support exec through kubectl proxy", func(ctx context.Context) { _ = getTestContextHost()