From 1d07d303059ef3b2378cec1548f2611ec7022c5d Mon Sep 17 00:00:00 2001 From: Rong Gao Date: Thu, 16 May 2019 16:15:11 +0800 Subject: [PATCH] fix: failed to close kubelet->API connections on heartbeat failure --- cmd/kubelet/app/BUILD | 1 + cmd/kubelet/app/server.go | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/cmd/kubelet/app/BUILD b/cmd/kubelet/app/BUILD index a8b13f757ff..3c54efc5f16 100644 --- a/cmd/kubelet/app/BUILD +++ b/cmd/kubelet/app/BUILD @@ -135,6 +135,7 @@ go_library( "//staging/src/k8s.io/client-go/tools/record:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library", "//staging/src/k8s.io/client-go/util/certificate:go_default_library", + "//staging/src/k8s.io/client-go/util/connrotation:go_default_library", "//staging/src/k8s.io/client-go/util/keyutil:go_default_library", "//staging/src/k8s.io/cloud-provider:go_default_library", "//staging/src/k8s.io/component-base/cli/flag:go_default_library", diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 4ce3e470373..92c77448405 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -57,6 +57,7 @@ import ( "k8s.io/client-go/tools/record" certutil "k8s.io/client-go/util/cert" "k8s.io/client-go/util/certificate" + "k8s.io/client-go/util/connrotation" "k8s.io/client-go/util/keyutil" cloudprovider "k8s.io/cloud-provider" cliflag "k8s.io/component-base/cli/flag" @@ -567,6 +568,9 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, stopCh <-chan if err != nil { return err } + if closeAllConns == nil { + return errors.New("closeAllConns must be a valid function other than nil") + } kubeDeps.OnHeartbeatFailure = closeAllConns kubeDeps.KubeClient, err = clientset.NewForConfig(clientConfig) @@ -806,8 +810,21 @@ func buildKubeletClientConfig(s *options.KubeletServer, nodeName types.NodeName) } kubeClientConfigOverrides(s, clientConfig) + closeAllConns, err := updateDialer(clientConfig) + if err != nil { + return nil, nil, err + } + return clientConfig, closeAllConns, nil +} - return clientConfig, nil, nil +// updateDialer instruments a restconfig with a dial. the returned function allows forcefully closing all active connections. +func updateDialer(clientConfig *restclient.Config) (func(), error) { + if clientConfig.Transport != nil || clientConfig.Dial != nil { + return nil, fmt.Errorf("there is already a transport or dialer configured") + } + d := connrotation.NewDialer((&net.Dialer{Timeout: 30 * time.Second, KeepAlive: 30 * time.Second}).DialContext) + clientConfig.Dial = d.DialContext + return d.CloseAll, nil } // buildClientCertificateManager creates a certificate manager that will use certConfig to request a client certificate