From bbeb6f9df0d193e441091c3c040cd455b6b8a50f 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 a837a646d6..45f549c2a1 100644 --- a/cmd/kubelet/app/BUILD +++ b/cmd/kubelet/app/BUILD @@ -133,6 +133,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 69f0e35d0a..e5557ead4e 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -54,6 +54,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" @@ -560,6 +561,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) @@ -795,8 +799,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