From eef381f83f99c0fba7fc1d63d26dca8112c5df3e Mon Sep 17 00:00:00 2001 From: rambohe Date: Thu, 9 Sep 2021 09:17:12 +0800 Subject: [PATCH] bugfix: prepare yurthub server tls config panic (#457) --- pkg/yurthub/gc/gc.go | 4 +-- pkg/yurthub/kubernetes/rest/config.go | 33 +++++++++++++--------- pkg/yurthub/kubernetes/rest/config_test.go | 2 +- pkg/yurthub/server/server.go | 7 ++++- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/pkg/yurthub/gc/gc.go b/pkg/yurthub/gc/gc.go index 6d400ebf2a5..c7f5039a99e 100644 --- a/pkg/yurthub/gc/gc.go +++ b/pkg/yurthub/gc/gc.go @@ -73,7 +73,7 @@ func (m *GCManager) Run() { go wait.JitterUntil(func() { klog.V(2).Infof("start gc events after waiting %v from previous gc", time.Since(m.lastTime)) m.lastTime = time.Now() - cfg := m.restConfigManager.GetRestConfig() + cfg := m.restConfigManager.GetRestConfig(true) if cfg == nil { klog.Errorf("could not get rest config, so skip gc") return @@ -96,7 +96,7 @@ func (m *GCManager) gcPodsWhenRestart() error { } klog.Infof("list pod keys from storage, total: %d", len(localPodKeys)) - cfg := m.restConfigManager.GetRestConfig() + cfg := m.restConfigManager.GetRestConfig(true) if cfg == nil { klog.Errorf("could not get rest config, so skip gc pods when restart") return err diff --git a/pkg/yurthub/kubernetes/rest/config.go b/pkg/yurthub/kubernetes/rest/config.go index 05eaf8f3f00..f0399d7c97f 100644 --- a/pkg/yurthub/kubernetes/rest/config.go +++ b/pkg/yurthub/kubernetes/rest/config.go @@ -52,25 +52,29 @@ func NewRestConfigManager(cfg *config.YurtHubConfiguration, certMgr interfaces.Y } // GetRestConfig gets rest client config according to the mode of certificateManager -func (rcm *RestConfigManager) GetRestConfig() *rest.Config { +func (rcm *RestConfigManager) GetRestConfig(needHealthyServer bool) *rest.Config { certMgrMode := rcm.certMgrMode switch certMgrMode { case util.YurtHubCertificateManagerName: - return rcm.getHubselfRestConfig() + return rcm.getHubselfRestConfig(needHealthyServer) case util.KubeletCertificateManagerName: - return rcm.getKubeletRestConfig(rcm.kubeletRootCAFilePath, rcm.kubeletPairFilePath) + return rcm.getKubeletRestConfig(rcm.kubeletRootCAFilePath, rcm.kubeletPairFilePath, needHealthyServer) default: return nil } } // getKubeletRestConfig gets rest client config from kubelet.conf -func (rcm *RestConfigManager) getKubeletRestConfig(kubeletRootCAFilePath, kubeletPairFilePath string) *rest.Config { - healthyServer := rcm.getHealthyServer() - if healthyServer == nil { - klog.Infof("all of remote servers are unhealthy, so return nil for rest config") - return nil +func (rcm *RestConfigManager) getKubeletRestConfig(kubeletRootCAFilePath, kubeletPairFilePath string, needHealthyServer bool) *rest.Config { + healthyServer := rcm.remoteServers[0] + if needHealthyServer { + healthyServer = rcm.getHealthyServer() + if healthyServer == nil { + klog.Infof("all of remote servers are unhealthy, so return nil for rest config") + return nil + } } + cfg, err := util.LoadKubeletRestClientConfig(healthyServer, kubeletRootCAFilePath, kubeletPairFilePath) if err != nil { klog.Errorf("could not load kubelet rest client config, %v", err) @@ -80,11 +84,14 @@ func (rcm *RestConfigManager) getKubeletRestConfig(kubeletRootCAFilePath, kubele } // getHubselfRestConfig gets rest client config from hub agent conf file. -func (rcm *RestConfigManager) getHubselfRestConfig() *rest.Config { - healthyServer := rcm.getHealthyServer() - if healthyServer == nil { - klog.Infof("all of remote servers are unhealthy, so return nil for rest config") - return nil +func (rcm *RestConfigManager) getHubselfRestConfig(needHealthyServer bool) *rest.Config { + healthyServer := rcm.remoteServers[0] + if needHealthyServer { + healthyServer = rcm.getHealthyServer() + if healthyServer == nil { + klog.Infof("all of remote servers are unhealthy, so return nil for rest config") + return nil + } } // certificate expired, rest config can not be used to connect remote server, diff --git a/pkg/yurthub/kubernetes/rest/config_test.go b/pkg/yurthub/kubernetes/rest/config_test.go index 82d8c68d303..1453e1e2bc8 100644 --- a/pkg/yurthub/kubernetes/rest/config_test.go +++ b/pkg/yurthub/kubernetes/rest/config_test.go @@ -134,7 +134,7 @@ func TestGetRestConfig(t *testing.T) { } var rc *rest.Config - rc = rcm.GetRestConfig() + rc = rcm.GetRestConfig(true) if tt.mode == "hubself" { if rc.Host != u.String() || rc.TLSClientConfig.CertFile != yurthubCurrent || rc.TLSClientConfig.KeyFile != yurthubCurrent { t.Errorf("The information in rest.Config is not correct: %s", tt.mode) diff --git a/pkg/yurthub/server/server.go b/pkg/yurthub/server/server.go index 963183bd2d1..f5c0f815939 100644 --- a/pkg/yurthub/server/server.go +++ b/pkg/yurthub/server/server.go @@ -172,7 +172,12 @@ func healthz(w http.ResponseWriter, _ *http.Request) { // create a certificate manager for the yurthub server and run the csr approver for both yurthub // and generate a TLS configuration func GenUseCertMgrAndTLSConfig(restConfigMgr *rest.RestConfigManager, certificateMgr interfaces.YurtCertificateManager, certDir, proxyServerSecureDummyAddr string, stopCh <-chan struct{}) (*tls.Config, error) { - clientSet, err := kubernetes.NewForConfig(restConfigMgr.GetRestConfig()) + cfg := restConfigMgr.GetRestConfig(false) + if cfg == nil { + return nil, fmt.Errorf("failed to prepare rest config based ong hub agent client certificate") + } + + clientSet, err := kubernetes.NewForConfig(cfg) if err != nil { return nil, err }