From 204d994aca210e1ef20ea947ae0555df7b70a994 Mon Sep 17 00:00:00 2001 From: xuzhonghu Date: Mon, 14 May 2018 20:11:43 +0800 Subject: [PATCH] Enable kubectl proxy to set tcp keepalive --- pkg/kubectl/cmd/proxy.go | 5 ++++- pkg/kubectl/proxy/proxy_server.go | 23 ++++++++--------------- pkg/kubectl/proxy/proxy_server_test.go | 2 +- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/pkg/kubectl/cmd/proxy.go b/pkg/kubectl/cmd/proxy.go index 59291241697..6400636e277 100644 --- a/pkg/kubectl/cmd/proxy.go +++ b/pkg/kubectl/cmd/proxy.go @@ -93,6 +93,7 @@ func NewCmdProxy(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra. cmd.Flags().StringP("address", "", "127.0.0.1", "The IP address on which to serve on.") cmd.Flags().Bool("disable-filter", false, "If true, disable request filtering in the proxy. This is dangerous, and can leave you vulnerable to XSRF attacks, when used with an accessible port.") cmd.Flags().StringP("unix-socket", "u", "", "Unix socket on which to run the proxy.") + cmd.Flags().Duration("keepalive", 0, "keepalive specifies the keep-alive period for an active network connection. Set to 0 to disable keepalive.") return cmd } @@ -141,7 +142,9 @@ func RunProxy(f cmdutil.Factory, out io.Writer, cmd *cobra.Command) error { filter = nil } - server, err := proxy.NewServer(staticDir, apiProxyPrefix, staticPrefix, filter, clientConfig) + keepalive := cmdutil.GetFlagDuration(cmd, "keepalive") + + server, err := proxy.NewServer(staticDir, apiProxyPrefix, staticPrefix, filter, clientConfig, keepalive) // Separate listening from serving so we can report the bound port // when it is chosen by os (eg: port == 0) diff --git a/pkg/kubectl/proxy/proxy_server.go b/pkg/kubectl/proxy/proxy_server.go index f127c697896..e60ebf0b58a 100644 --- a/pkg/kubectl/proxy/proxy_server.go +++ b/pkg/kubectl/proxy/proxy_server.go @@ -158,7 +158,7 @@ func (r *responder) Error(w http.ResponseWriter, req *http.Request, err error) { // makeUpgradeTransport creates a transport that explicitly bypasses HTTP2 support // for proxy connections that must upgrade. -func makeUpgradeTransport(config *rest.Config) (proxy.UpgradeRequestRoundTripper, error) { +func makeUpgradeTransport(config *rest.Config, keepalive time.Duration) (proxy.UpgradeRequestRoundTripper, error) { transportConfig, err := config.TransportConfig() if err != nil { return nil, err @@ -169,7 +169,12 @@ func makeUpgradeTransport(config *rest.Config) (proxy.UpgradeRequestRoundTripper } rt := utilnet.SetOldTransportDefaults(&http.Transport{ TLSClientConfig: tlsConfig, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: keepalive, + }).DialContext, }) + upgrader, err := transport.HTTPWrappersForConfig(transportConfig, proxy.MirrorRequest) if err != nil { return nil, err @@ -179,7 +184,7 @@ func makeUpgradeTransport(config *rest.Config) (proxy.UpgradeRequestRoundTripper // NewServer creates and installs a new Server. // 'filter', if non-nil, protects requests to the api only. -func NewServer(filebase string, apiProxyPrefix string, staticPrefix string, filter *FilterServer, cfg *rest.Config) (*Server, error) { +func NewServer(filebase string, apiProxyPrefix string, staticPrefix string, filter *FilterServer, cfg *rest.Config, keepalive time.Duration) (*Server, error) { host := cfg.Host if !strings.HasSuffix(host, "/") { host = host + "/" @@ -194,7 +199,7 @@ func NewServer(filebase string, apiProxyPrefix string, staticPrefix string, filt if err != nil { return nil, err } - upgradeTransport, err := makeUpgradeTransport(cfg) + upgradeTransport, err := makeUpgradeTransport(cfg, keepalive) if err != nil { return nil, err } @@ -252,18 +257,6 @@ func newFileHandler(prefix, base string) http.Handler { return http.StripPrefix(prefix, http.FileServer(http.Dir(base))) } -func singleJoiningSlash(a, b string) string { - aslash := strings.HasSuffix(a, "/") - bslash := strings.HasPrefix(b, "/") - switch { - case aslash && bslash: - return a + b[1:] - case !aslash && !bslash: - return a + "/" + b - } - return a + b -} - // like http.StripPrefix, but always leaves an initial slash. (so that our // regexps will work.) func stripLeaveSlash(prefix string, h http.Handler) http.Handler { diff --git a/pkg/kubectl/proxy/proxy_server_test.go b/pkg/kubectl/proxy/proxy_server_test.go index 5f46af991cf..a596ba61099 100644 --- a/pkg/kubectl/proxy/proxy_server_test.go +++ b/pkg/kubectl/proxy/proxy_server_test.go @@ -452,7 +452,7 @@ func TestPathHandling(t *testing.T) { for _, tt := range table { t.Run(tt.name, func(t *testing.T) { - p, err := NewServer("", tt.prefix, "/not/used/for/this/test", nil, cc) + p, err := NewServer("", tt.prefix, "/not/used/for/this/test", nil, cc, 0) if err != nil { t.Fatalf("%#v: %v", tt, err) }