From b860e634db9828dabb2fe47662f69e8bc05bf988 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Steenis Date: Wed, 24 Jul 2019 22:25:14 +0200 Subject: [PATCH] Add per node kubelet server certificate --- cluster/certificates.go | 26 ++++++----- cluster/plan.go | 41 ++++++++-------- cluster/reconcile.go | 2 +- cluster/validation.go | 10 ++-- cmd/cert.go | 48 ++++++++++--------- hosts/hosts.go | 10 ++++ pki/constants.go | 1 + pki/deploy.go | 2 +- pki/pki.go | 15 ++---- pki/services.go | 65 ++++++++++++++++++++++++-- pki/util.go | 101 +++++++++++++++++++++++++--------------- services/etcd.go | 2 +- 12 files changed, 210 insertions(+), 113 deletions(-) diff --git a/cluster/certificates.go b/cluster/certificates.go index c35f1602..e502c66b 100644 --- a/cluster/certificates.go +++ b/cluster/certificates.go @@ -59,7 +59,7 @@ func GetClusterCertsFromKubernetes(ctx context.Context, kubeCluster *Cluster) (m } for _, etcdHost := range kubeCluster.EtcdHosts { - etcdName := pki.GetEtcdCrtName(etcdHost.InternalAddress) + etcdName := pki.GetCrtNameForAddress(etcdHost.InternalAddress, pki.EtcdCertName) certificatesNames = append(certificatesNames, etcdName) } @@ -154,13 +154,13 @@ func RotateRKECertificates(ctx context.Context, c *Cluster, flags ExternalFlags, var ( serviceAccountTokenKey string ) - componentsCertsFuncMap := map[string]pki.GenFunc{ - services.KubeAPIContainerName: pki.GenerateKubeAPICertificate, - services.KubeControllerContainerName: pki.GenerateKubeControllerCertificate, - services.SchedulerContainerName: pki.GenerateKubeSchedulerCertificate, - services.KubeproxyContainerName: pki.GenerateKubeProxyCertificate, - services.KubeletContainerName: pki.GenerateKubeNodeCertificate, - services.EtcdContainerName: pki.GenerateEtcdCertificates, + componentsCertsFuncMap := map[string][]pki.GenFunc{ + services.KubeAPIContainerName: []pki.GenFunc{pki.GenerateKubeAPICertificate}, + services.KubeControllerContainerName: []pki.GenFunc{pki.GenerateKubeControllerCertificate}, + services.SchedulerContainerName: []pki.GenFunc{pki.GenerateKubeSchedulerCertificate}, + services.KubeproxyContainerName: []pki.GenFunc{pki.GenerateKubeProxyCertificate}, + services.KubeletContainerName: []pki.GenFunc{pki.GenerateKubeNodeCertificate, pki.GenerateKubeletCertificate}, + services.EtcdContainerName: []pki.GenFunc{pki.GenerateEtcdCertificates}, } rotateFlags := c.RancherKubernetesEngineConfig.RotateCertificates if rotateFlags.CACertificates { @@ -171,10 +171,12 @@ func RotateRKECertificates(ctx context.Context, c *Cluster, flags ExternalFlags, rotateFlags.Services = nil } for _, k8sComponent := range rotateFlags.Services { - genFunc := componentsCertsFuncMap[k8sComponent] - if genFunc != nil { - if err := genFunc(ctx, c.Certificates, c.RancherKubernetesEngineConfig, flags.ClusterFilePath, flags.ConfigDir, true); err != nil { - return err + genFunctions := componentsCertsFuncMap[k8sComponent] + if genFunctions != nil { + for _, genFunc := range genFunctions { + if err := genFunc(ctx, c.Certificates, c.RancherKubernetesEngineConfig, flags.ClusterFilePath, flags.ConfigDir, true); err != nil { + return err + } } } } diff --git a/cluster/plan.go b/cluster/plan.go index 3a6ff8c7..8e8f0ca8 100644 --- a/cluster/plan.go +++ b/cluster/plan.go @@ -123,24 +123,25 @@ func (c *Cluster) BuildKubeAPIProcess(host *hosts.Host, prefixPath string, svcOp } CommandArgs := map[string]string{ - "client-ca-file": pki.GetCertPath(pki.CACertName), - "cloud-provider": c.CloudProvider.Name, - "etcd-cafile": etcdCAClientCert, - "etcd-certfile": etcdClientCert, - "etcd-keyfile": etcdClientKey, - "etcd-prefix": etcdPathPrefix, - "etcd-servers": etcdConnectionString, - "kubelet-client-certificate": pki.GetCertPath(pki.KubeAPICertName), - "kubelet-client-key": pki.GetKeyPath(pki.KubeAPICertName), - "proxy-client-cert-file": pki.GetCertPath(pki.APIProxyClientCertName), - "proxy-client-key-file": pki.GetKeyPath(pki.APIProxyClientCertName), - "requestheader-allowed-names": pki.APIProxyClientCertName, - "requestheader-client-ca-file": pki.GetCertPath(pki.RequestHeaderCACertName), - "service-account-key-file": pki.GetKeyPath(pki.ServiceAccountTokenKeyName), - "service-cluster-ip-range": c.Services.KubeAPI.ServiceClusterIPRange, - "service-node-port-range": c.Services.KubeAPI.ServiceNodePortRange, - "tls-cert-file": pki.GetCertPath(pki.KubeAPICertName), - "tls-private-key-file": pki.GetKeyPath(pki.KubeAPICertName), + "client-ca-file": pki.GetCertPath(pki.CACertName), + "cloud-provider": c.CloudProvider.Name, + "etcd-cafile": etcdCAClientCert, + "etcd-certfile": etcdClientCert, + "etcd-keyfile": etcdClientKey, + "etcd-prefix": etcdPathPrefix, + "etcd-servers": etcdConnectionString, + "kubelet-client-certificate": pki.GetCertPath(pki.KubeAPICertName), + "kubelet-client-key": pki.GetKeyPath(pki.KubeAPICertName), + "kubelet-certificate-authority": pki.GetCertPath(pki.CACertName), + "proxy-client-cert-file": pki.GetCertPath(pki.APIProxyClientCertName), + "proxy-client-key-file": pki.GetKeyPath(pki.APIProxyClientCertName), + "requestheader-allowed-names": pki.APIProxyClientCertName, + "requestheader-client-ca-file": pki.GetCertPath(pki.RequestHeaderCACertName), + "service-account-key-file": pki.GetKeyPath(pki.ServiceAccountTokenKeyName), + "service-cluster-ip-range": c.Services.KubeAPI.ServiceClusterIPRange, + "service-node-port-range": c.Services.KubeAPI.ServiceNodePortRange, + "tls-cert-file": pki.GetCertPath(pki.KubeAPICertName), + "tls-private-key-file": pki.GetKeyPath(pki.KubeAPICertName), } if len(c.CloudProvider.Name) > 0 { CommandArgs["cloud-config"] = cloudConfigFileName @@ -347,6 +348,8 @@ func (c *Cluster) BuildKubeletProcess(host *hosts.Host, prefixPath string, svcOp "fail-swap-on": strconv.FormatBool(c.Services.Kubelet.FailSwapOn), "hostname-override": host.HostnameOverride, "kubeconfig": pki.GetConfigPath(pki.KubeNodeCertName), + "tls-cert-file": pki.GetCertPath(pki.GetCrtNameForAddress(host.InternalAddress, pki.KubeletCertName)), + "tls-private-key-file": pki.GetCertPath(fmt.Sprintf("%s-key", pki.GetCrtNameForAddress(host.InternalAddress, pki.KubeletCertName))), "pod-infra-container-image": c.Services.Kubelet.InfraContainerImage, "root-dir": path.Join(prefixPath, "/var/lib/kubelet"), } @@ -659,7 +662,7 @@ func (c *Cluster) BuildSidecarProcess() v3.Process { } func (c *Cluster) BuildEtcdProcess(host *hosts.Host, etcdHosts []*hosts.Host, prefixPath string) v3.Process { - nodeName := pki.GetEtcdCrtName(host.InternalAddress) + nodeName := pki.GetCrtNameForAddress(host.InternalAddress, pki.EtcdCertName) initCluster := "" architecture := "amd64" if len(etcdHosts) == 0 { diff --git a/cluster/reconcile.go b/cluster/reconcile.go index 71c8737c..43749ab0 100644 --- a/cluster/reconcile.go +++ b/cluster/reconcile.go @@ -328,7 +328,7 @@ func restartComponentsWhenCertChanges(ctx context.Context, currentCluster, kubeC } for _, host := range kubeCluster.EtcdHosts { - etcdCertName := pki.GetEtcdCrtName(host.Address) + etcdCertName := pki.GetCrtNameForAddress(host.Address, pki.EtcdCertName) certMap := map[string]bool{ etcdCertName: false, } diff --git a/cluster/validation.go b/cluster/validation.go index 0dadc9f8..9ef0d9b1 100644 --- a/cluster/validation.go +++ b/cluster/validation.go @@ -168,10 +168,12 @@ func validateIngressOptions(c *Cluster) error { func ValidateHostCount(c *Cluster) error { if len(c.EtcdHosts) == 0 && len(c.Services.Etcd.ExternalURLs) == 0 { - failedEtcdHosts := []string{} - for _, host := range c.InactiveHosts { - if host.IsEtcd { - failedEtcdHosts = append(failedEtcdHosts, host.Address) + if len(c.InactiveHosts) > 0 { + failedEtcdHosts := []string{} + for _, host := range c.InactiveHosts { + if host.IsEtcd { + failedEtcdHosts = append(failedEtcdHosts, host.Address) + } } return fmt.Errorf("Cluster must have at least one etcd plane host: failed to connect to the following etcd host(s) %v", failedEtcdHosts) } diff --git a/cmd/cert.go b/cmd/cert.go index 8bb30a31..7348a249 100644 --- a/cmd/cert.go +++ b/cmd/cert.go @@ -15,6 +15,30 @@ import ( ) func CertificateCommand() cli.Command { + rotateFlags := []cli.Flag{ + cli.StringFlag{ + Name: "config", + Usage: "Specify an alternate cluster YAML file", + Value: pki.ClusterConfig, + EnvVar: "RKE_CONFIG", + }, + cli.StringSliceFlag{ + Name: "service", + Usage: fmt.Sprintf("Specify a k8s service to rotate certs, (allowed values: %s, %s, %s, %s, %s, %s)", + services.KubeAPIContainerName, + services.KubeControllerContainerName, + services.SchedulerContainerName, + services.KubeletContainerName, + services.KubeproxyContainerName, + services.EtcdContainerName, + ), + }, + cli.BoolFlag{ + Name: "rotate-ca", + Usage: "Rotate all certificates including CA certs", + }, + } + rotateFlags = append(rotateFlags, commonFlags...) return cli.Command{ Name: "cert", Usage: "Certificates management for RKE cluster", @@ -23,29 +47,7 @@ func CertificateCommand() cli.Command { Name: "rotate", Usage: "Rotate RKE cluster certificates", Action: rotateRKECertificatesFromCli, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config", - Usage: "Specify an alternate cluster YAML file", - Value: pki.ClusterConfig, - EnvVar: "RKE_CONFIG", - }, - cli.StringSliceFlag{ - Name: "service", - Usage: fmt.Sprintf("Specify a k8s service to rotate certs, (allowed values: %s, %s, %s, %s, %s, %s)", - services.KubeAPIContainerName, - services.KubeControllerContainerName, - services.SchedulerContainerName, - services.KubeletContainerName, - services.KubeproxyContainerName, - services.EtcdContainerName, - ), - }, - cli.BoolFlag{ - Name: "rotate-ca", - Usage: "Rotate all certificates including CA certs", - }, - }, + Flags: rotateFlags, }, cli.Command{ Name: "generate-csr", diff --git a/hosts/hosts.go b/hosts/hosts.go index 1389920e..a5e7b78b 100644 --- a/hosts/hosts.go +++ b/hosts/hosts.go @@ -272,6 +272,16 @@ func buildCleanerConfig(host *Host, toCleanDirs []string, cleanerImage string) ( func NodesToHosts(rkeNodes []v3.RKEConfigNode, nodeRole string) []*Host { hostList := make([]*Host, 0) + // Return all nodes if there is no noderole passed to the function + if nodeRole == "" { + for _, node := range rkeNodes { + newHost := Host{ + RKEConfigNode: node, + } + hostList = append(hostList, &newHost) + } + return hostList + } for _, node := range rkeNodes { for _, role := range node.Role { if role == nodeRole { diff --git a/pki/constants.go b/pki/constants.go index 4adf9189..7d53cf47 100644 --- a/pki/constants.go +++ b/pki/constants.go @@ -21,6 +21,7 @@ const ( KubeSchedulerCertName = "kube-scheduler" KubeProxyCertName = "kube-proxy" KubeNodeCertName = "kube-node" + KubeletCertName = "kube-kubelet" EtcdCertName = "kube-etcd" EtcdClientCACertName = "kube-etcd-client-ca" EtcdClientCertName = "kube-etcd-client" diff --git a/pki/deploy.go b/pki/deploy.go index 6ee69aa2..10655783 100644 --- a/pki/deploy.go +++ b/pki/deploy.go @@ -176,7 +176,7 @@ func FetchCertificatesFromHost(ctx context.Context, extraHosts []*hosts.Host, ho for _, etcdHost := range extraHosts { // Fetch etcd certificates - crtList[GetEtcdCrtName(etcdHost.InternalAddress)] = false + crtList[GetCrtNameForAddress(etcdHost.InternalAddress, EtcdCertName)] = false } for certName, config := range crtList { diff --git a/pki/pki.go b/pki/pki.go index eb994d78..22c5967d 100644 --- a/pki/pki.go +++ b/pki/pki.go @@ -66,18 +66,11 @@ func GenerateRKENodeCerts(ctx context.Context, rkeConfig v3.RancherKubernetesEng for _, node := range rkeConfig.Nodes { if node.Address == nodeAddress { for _, role := range node.Role { - switch role { - case controlRole: - keys := getControlCertKeys() - crtKeys = append(crtKeys, keys...) + if role == controlRole { removeCAKey = false - case workerRole: - keys := getWorkerCertKeys() - crtKeys = append(crtKeys, keys...) - case etcdRole: - keys := getEtcdCertKeys(rkeConfig.Nodes, etcdRole) - crtKeys = append(crtKeys, keys...) } + keys := getCertKeys(rkeConfig.Nodes, role) + crtKeys = append(crtKeys, keys...) } break } @@ -112,7 +105,7 @@ func RegenerateEtcdCertificate( if err != nil { return nil, err } - etcdName := GetEtcdCrtName(etcdHost.InternalAddress) + etcdName := GetCrtNameForAddress(etcdHost.InternalAddress, EtcdCertName) crtMap[etcdName] = ToCertObject(etcdName, "", "", etcdCrt, etcdKey, nil) log.Infof(ctx, "[certificates] Successfully generated new etcd-%s certificate and key", etcdHost.InternalAddress) return crtMap, nil diff --git a/pki/services.go b/pki/services.go index d0cb4485..1fc69e4b 100644 --- a/pki/services.go +++ b/pki/services.go @@ -372,7 +372,7 @@ func GenerateEtcdCertificates(ctx context.Context, certs map[string]CertificateP sort.Strings(ips) for _, host := range etcdHosts { - etcdName := GetEtcdCrtName(host.InternalAddress) + etcdName := GetCrtNameForAddress(host.InternalAddress, EtcdCertName) if _, ok := certs[etcdName]; ok && certs[etcdName].CertificatePEM != "" && !rotate { cert := certs[etcdName].Certificate if cert != nil && len(dnsNames) == len(cert.DNSNames) && len(ips) == len(cert.IPAddresses) { @@ -396,7 +396,7 @@ func GenerateEtcdCertificates(ctx context.Context, certs map[string]CertificateP if !rotate { serviceKey = certs[etcdName].Key } - log.Infof(ctx, "[certificates] Generating etcd-%s certificate and key", host.InternalAddress) + log.Infof(ctx, "[certificates] Generating %s certificate and key", etcdName) etcdCrt, etcdKey, err := GenerateSignedCertAndKey(caCrt, caKey, true, EtcdCertName, etcdAltNames, serviceKey, nil) if err != nil { return err @@ -415,7 +415,7 @@ func GenerateEtcdCSRs(ctx context.Context, certs map[string]CertificatePKI, rkeC etcdHosts := hosts.NodesToHosts(rkeConfig.Nodes, etcdRole) etcdAltNames := GetAltNames(etcdHosts, clusterDomain, kubernetesServiceIP, []string{}) for _, host := range etcdHosts { - etcdName := GetEtcdCrtName(host.InternalAddress) + etcdName := GetCrtNameForAddress(host.InternalAddress, EtcdCertName) etcdCrt := certs[etcdName].Certificate etcdCSRPEM := certs[etcdName].CSRPEM if etcdCSRPEM != "" { @@ -484,6 +484,63 @@ func GenerateRKERequestHeaderCACert(ctx context.Context, certs map[string]Certif return nil } +func GenerateKubeletCertificate(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error { + // generate kubelet certificate and key + caCrt := certs[CACertName].Certificate + caKey := certs[CACertName].Key + if caCrt == nil || caKey == nil { + return fmt.Errorf("CA Certificate or Key is empty") + } + log.Infof(ctx, "[certificates] Generating Kubernetes Kubelet certificates") + allHosts := hosts.NodesToHosts(rkeConfig.Nodes, "") + for _, host := range allHosts { + kubeletName := GetCrtNameForAddress(host.InternalAddress, KubeletCertName) + kubeletCert := certs[kubeletName].Certificate + if kubeletCert != nil && !rotate { + return nil + } + kubeletAltNames := GetIPHostAltnamesForHost(host) + if kubeletCert != nil && + reflect.DeepEqual(kubeletAltNames.DNSNames, kubeletCert.DNSNames) && + deepEqualIPsAltNames(kubeletAltNames.IPs, kubeletCert.IPAddresses) && !rotate { + return nil + } + var serviceKey *rsa.PrivateKey + if !rotate { + serviceKey = certs[kubeletName].Key + } + log.Infof(ctx, "[certificates] Generating %s certificate and key", kubeletName) + kubeletCrt, kubeletKey, err := GenerateSignedCertAndKey(caCrt, caKey, true, kubeletName, kubeletAltNames, serviceKey, nil) + if err != nil { + return err + } + certs[kubeletName] = ToCertObject(kubeletName, "", "", kubeletCrt, kubeletKey, nil) + } + return nil +} + +func GenerateKubeletCSR(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig) error { + allHosts := hosts.NodesToHosts(rkeConfig.Nodes, "") + for _, host := range allHosts { + kubeletName := GetCrtNameForAddress(host.InternalAddress, KubeletCertName) + kubeletCert := certs[kubeletName].Certificate + oldKubeletCSR := certs[kubeletName].CSR + kubeletAltNames := GetIPHostAltnamesForHost(host) + if oldKubeletCSR != nil && + reflect.DeepEqual(kubeletAltNames.DNSNames, oldKubeletCSR.DNSNames) && + deepEqualIPsAltNames(kubeletAltNames.IPs, oldKubeletCSR.IPAddresses) { + return nil + } + log.Infof(ctx, "[certificates] Generating %s Kubernetes Kubelet csr", kubeletName) + kubeletCSR, kubeletKey, err := GenerateCertSigningRequestAndKey(true, kubeletName, kubeletAltNames, certs[kubeletName].Key, nil) + if err != nil { + return err + } + certs[kubeletName] = ToCertObject(kubeletName, "", "", kubeletCert, kubeletKey, kubeletCSR) + } + return nil +} + func GenerateRKEServicesCerts(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error { RKECerts := []GenFunc{ GenerateKubeAPICertificate, @@ -495,6 +552,7 @@ func GenerateRKEServicesCerts(ctx context.Context, certs map[string]CertificateP GenerateKubeAdminCertificate, GenerateAPIProxyClientCertificate, GenerateEtcdCertificates, + GenerateKubeletCertificate, } for _, gen := range RKECerts { if err := gen(ctx, certs, rkeConfig, configPath, configDir, rotate); err != nil { @@ -517,6 +575,7 @@ func GenerateRKEServicesCSRs(ctx context.Context, certs map[string]CertificatePK GenerateKubeAdminCSR, GenerateAPIProxyClientCSR, GenerateEtcdCSRs, + GenerateKubeletCSR, } for _, csr := range RKECerts { if err := csr(ctx, certs, rkeConfig); err != nil { diff --git a/pki/util.go b/pki/util.go index 350d6770..e8c8d887 100644 --- a/pki/util.go +++ b/pki/util.go @@ -136,6 +136,34 @@ func GenerateCACertAndKey(commonName string, privateKey *rsa.PrivateKey) (*x509. return kubeCACert, rootKey, nil } +func GetIPHostAltnamesForHost(host *hosts.Host) *cert.AltNames { + ips := []net.IP{} + dnsNames := []string{} + // Check if node address is a valid IP + if nodeIP := net.ParseIP(host.Address); nodeIP != nil { + ips = append(ips, nodeIP) + } else { + dnsNames = append(dnsNames, host.Address) + } + + // Check if node internal address is a valid IP + if len(host.InternalAddress) != 0 && host.InternalAddress != host.Address { + if internalIP := net.ParseIP(host.InternalAddress); internalIP != nil { + ips = append(ips, internalIP) + } else { + dnsNames = append(dnsNames, host.InternalAddress) + } + } + // Add hostname to the ALT dns names + if len(host.HostnameOverride) != 0 && host.HostnameOverride != host.Address { + dnsNames = append(dnsNames, host.HostnameOverride) + } + return &cert.AltNames{ + IPs: ips, + DNSNames: dnsNames, + } +} + func GetAltNames(cpHosts []*hosts.Host, clusterDomain string, KubernetesServiceIP net.IP, SANs []string) *cert.AltNames { ips := []net.IP{} dnsNames := []string{} @@ -225,9 +253,9 @@ func getConfigEnvFromEnv(env string) string { return fmt.Sprintf("KUBECFG_%s", env) } -func GetEtcdCrtName(address string) string { +func GetCrtNameForAddress(address string, prefix string) string { newAddress := strings.Replace(address, ".", "-", -1) - return fmt.Sprintf("%s-%s", EtcdCertName, newAddress) + return fmt.Sprintf("%s-%s", prefix, newAddress) } func GetCertPath(name string) string { @@ -280,7 +308,7 @@ func ToCertObject(componentName, commonName, ouName string, certificate *x509.Ce }) } - if componentName != CACertName && componentName != KubeAPICertName && !strings.Contains(componentName, EtcdCertName) && componentName != ServiceAccountTokenKeyName { + if componentName != CACertName && componentName != KubeAPICertName && !strings.Contains(componentName, EtcdCertName) && !strings.Contains(componentName, KubeletCertName) && componentName != ServiceAccountTokenKeyName { config = getKubeConfigX509("https://127.0.0.1:6443", "local", componentName, caCertPath, path, keyPath) configPath = GetConfigPath(componentName) configEnvName = getConfigEnvFromEnv(envName) @@ -310,42 +338,39 @@ func getDefaultCN(name string) string { return fmt.Sprintf("system:%s", name) } -func getControlCertKeys() []string { - return []string{ - CACertName, - KubeAPICertName, - ServiceAccountTokenKeyName, - KubeControllerCertName, - KubeSchedulerCertName, - KubeProxyCertName, - KubeNodeCertName, - EtcdClientCertName, - EtcdClientCACertName, - RequestHeaderCACertName, - APIProxyClientCertName, +func getCertKeys(rkeNodes []v3.RKEConfigNode, nodeRole string) []string { + // static certificates each node needs + certList := []string{CACertName, KubeProxyCertName, KubeNodeCertName} + allHosts := hosts.NodesToHosts(rkeNodes, "") + for _, host := range allHosts { + // Add per node kubelet certificates (used for kube-api -> kubelet connection) + certList = append(certList, GetCrtNameForAddress(host.InternalAddress, KubeletCertName)) } -} - -func getWorkerCertKeys() []string { - return []string{ - CACertName, - KubeProxyCertName, - KubeNodeCertName, + // etcd + if nodeRole == etcdRole { + etcdHosts := hosts.NodesToHosts(rkeNodes, nodeRole) + for _, host := range etcdHosts { + certList = append(certList, GetCrtNameForAddress(host.InternalAddress, EtcdCertName)) + } + return certList } -} - -func getEtcdCertKeys(rkeNodes []v3.RKEConfigNode, etcdRole string) []string { - certList := []string{ - CACertName, - KubeProxyCertName, - KubeNodeCertName, - } - etcdHosts := hosts.NodesToHosts(rkeNodes, etcdRole) - for _, host := range etcdHosts { - certList = append(certList, GetEtcdCrtName(host.InternalAddress)) + // control + if nodeRole == controlRole { + controlCertList := []string{ + KubeAPICertName, + ServiceAccountTokenKeyName, + KubeControllerCertName, + KubeSchedulerCertName, + EtcdClientCertName, + EtcdClientCACertName, + RequestHeaderCACertName, + APIProxyClientCertName, + } + certList = append(certList, controlCertList...) + return certList } + // worker return certList - } func GetKubernetesServiceIP(serviceClusterRange string) (net.IP, error) { @@ -407,7 +432,7 @@ func populateCertMap(tmpCerts map[string]CertificatePKI, localConfigPath string, certs[KubeAdminCertName] = kubeAdminCertObj // etcd for _, host := range extraHosts { - etcdName := GetEtcdCrtName(host.InternalAddress) + etcdName := GetCrtNameForAddress(host.InternalAddress, EtcdCertName) etcdCrt, etcdKey := tmpCerts[etcdName].Certificate, tmpCerts[etcdName].Key certs[etcdName] = ToCertObject(etcdName, "", "", etcdCrt, etcdKey, nil) } @@ -710,7 +735,7 @@ func ValidateBundleContent(rkeConfig *v3.RancherKubernetesEngineConfig, certBund } etcdHosts := hosts.NodesToHosts(rkeConfig.Nodes, etcdRole) for _, host := range etcdHosts { - etcdName := GetEtcdCrtName(host.InternalAddress) + etcdName := GetCrtNameForAddress(host.InternalAddress, EtcdCertName) if certBundle[etcdName].Certificate == nil || certBundle[etcdName].Key == nil { return fmt.Errorf("Failed to find etcd [%s] Certificate or Key", etcdName) } @@ -747,7 +772,7 @@ func validateCAIssuer(rkeConfig *v3.RancherKubernetesEngineConfig, certBundle ma } etcdHosts := hosts.NodesToHosts(rkeConfig.Nodes, etcdRole) for _, host := range etcdHosts { - etcdName := GetEtcdCrtName(host.InternalAddress) + etcdName := GetCrtNameForAddress(host.InternalAddress, EtcdCertName) ComponentsCerts = append(ComponentsCerts, etcdName) } for _, componentCert := range ComponentsCerts { diff --git a/services/etcd.go b/services/etcd.go index 030923ad..aca19cd5 100644 --- a/services/etcd.go +++ b/services/etcd.go @@ -425,7 +425,7 @@ func DownloadEtcdSnapshotFromS3(ctx context.Context, etcdHost *hosts.Host, prsMa func RestoreEtcdSnapshot(ctx context.Context, etcdHost *hosts.Host, prsMap map[string]v3.PrivateRegistry, etcdRestoreImage, snapshotName, initCluster string, es v3.ETCDService) error { log.Infof(ctx, "[etcd] Restoring [%s] snapshot on etcd host [%s]", snapshotName, etcdHost.Address) - nodeName := pki.GetEtcdCrtName(etcdHost.InternalAddress) + nodeName := pki.GetCrtNameForAddress(etcdHost.InternalAddress, pki.EtcdCertName) snapshotPath := fmt.Sprintf("%s%s", EtcdSnapshotPath, snapshotName) // make sure that restore path is empty otherwise etcd restore will fail