From 695fb7440e106fba63fc485ed12bf0cc251fcc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20K=C3=A4ldstr=C3=B6m?= Date: Mon, 23 Jan 2017 21:45:48 +0200 Subject: [PATCH] Fix up the misunderstanding about the apiserver kubelet client cert --- cmd/kubeadm/app/cmd/join.go | 2 +- cmd/kubeadm/app/constants/constants.go | 4 +++ cmd/kubeadm/app/master/manifests.go | 4 +-- cmd/kubeadm/app/master/manifests_test.go | 16 +++++------ cmd/kubeadm/app/phases/certs/certs.go | 35 +++++++++++++++++++++--- 5 files changed, 46 insertions(+), 15 deletions(-) diff --git a/cmd/kubeadm/app/cmd/join.go b/cmd/kubeadm/app/cmd/join.go index fef38c594ee..987c2b3cfe3 100644 --- a/cmd/kubeadm/app/cmd/join.go +++ b/cmd/kubeadm/app/cmd/join.go @@ -146,7 +146,7 @@ func (j *Join) Run(out io.Writer) error { // Write the ca certificate to disk so kubelet can use it for authentication cluster := cfg.Contexts[cfg.CurrentContext].Cluster - caCertFile := filepath.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeadmconstants.CACertName) + caCertFile := filepath.Join(kubeadmapi.GlobalEnvParams.HostPKIPath, kubeadmconstants.CACertName) err = certutil.WriteCert(caCertFile, cfg.Clusters[cluster].CertificateAuthorityData) if err != nil { return fmt.Errorf("couldn't save the CA certificate to disk: %v", err) diff --git a/cmd/kubeadm/app/constants/constants.go b/cmd/kubeadm/app/constants/constants.go index 6851df8129f..c25ee19014f 100644 --- a/cmd/kubeadm/app/constants/constants.go +++ b/cmd/kubeadm/app/constants/constants.go @@ -24,4 +24,8 @@ const ( APIServerCertAndKeyBaseName = "apiserver" APIServerCertName = "apiserver.crt" APIServerKeyName = "apiserver.key" + + APIServerKubeletClientCertAndKeyBaseName = "apiserver-kubelet-client" + APIServerKubeletClientCertName = "apiserver-kubelet-client.crt" + APIServerKubeletClientKeyName = "apiserver-kubelet-client.key" ) diff --git a/cmd/kubeadm/app/master/manifests.go b/cmd/kubeadm/app/master/manifests.go index bf44fadeda8..b234b700ed5 100644 --- a/cmd/kubeadm/app/master/manifests.go +++ b/cmd/kubeadm/app/master/manifests.go @@ -322,8 +322,8 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted bool) [ "--client-ca-file="+getCertFilePath(kubeadmconstants.CACertName), "--tls-cert-file="+getCertFilePath(kubeadmconstants.APIServerCertName), "--tls-private-key-file="+getCertFilePath(kubeadmconstants.APIServerKeyName), - "--kubelet-client-certificate="+getCertFilePath(kubeadmconstants.APIServerCertName), - "--kubelet-client-key="+getCertFilePath(kubeadmconstants.APIServerKeyName), + "--kubelet-client-certificate="+getCertFilePath(kubeadmconstants.APIServerKubeletClientCertName), + "--kubelet-client-key="+getCertFilePath(kubeadmconstants.APIServerKubeletClientKeyName), "--token-auth-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/tokens.csv", fmt.Sprintf("--secure-port=%d", cfg.API.Port), "--allow-privileged", diff --git a/cmd/kubeadm/app/master/manifests_test.go b/cmd/kubeadm/app/master/manifests_test.go index 41b41919040..b20d70b9a1b 100644 --- a/cmd/kubeadm/app/master/manifests_test.go +++ b/cmd/kubeadm/app/master/manifests_test.go @@ -376,8 +376,8 @@ func TestGetAPIServerCommand(t *testing.T) { "--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt", "--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt", "--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key", - "--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt", - "--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key", + "--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.crt", + "--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.key", "--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv", fmt.Sprintf("--secure-port=%d", 123), "--allow-privileged", @@ -399,8 +399,8 @@ func TestGetAPIServerCommand(t *testing.T) { "--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt", "--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt", "--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key", - "--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt", - "--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key", + "--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.crt", + "--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.key", "--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv", fmt.Sprintf("--secure-port=%d", 123), "--allow-privileged", @@ -424,8 +424,8 @@ func TestGetAPIServerCommand(t *testing.T) { "--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt", "--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt", "--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key", - "--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt", - "--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key", + "--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.crt", + "--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.key", "--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv", fmt.Sprintf("--secure-port=%d", 123), "--allow-privileged", @@ -451,8 +451,8 @@ func TestGetAPIServerCommand(t *testing.T) { "--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt", "--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt", "--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key", - "--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt", - "--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key", + "--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.crt", + "--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.key", "--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv", fmt.Sprintf("--secure-port=%d", 123), "--allow-privileged", diff --git a/cmd/kubeadm/app/phases/certs/certs.go b/cmd/kubeadm/app/phases/certs/certs.go index 78d5533a293..2cff7b49fda 100644 --- a/cmd/kubeadm/app/phases/certs/certs.go +++ b/cmd/kubeadm/app/phases/certs/certs.go @@ -110,7 +110,7 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiDir string) error { // If at least one of them exists, we should try to load them // In the case that only one exists, there will most likely be an error anyway if pkiutil.CertOrKeyExist(pkiDir, kubeadmconstants.APIServerCertAndKeyBaseName) { - // Try to load ca.crt and ca.key from the PKI directory + // Try to load apiserver.crt and apiserver.key from the PKI directory apiCert, apiKey, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, kubeadmconstants.APIServerCertAndKeyBaseName) if err != nil || apiCert == nil || apiKey == nil { return fmt.Errorf("certificate and/or key existed but they could not be loaded properly") @@ -123,9 +123,7 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiDir string) error { config := certutil.Config{ CommonName: "kube-apiserver", AltNames: altNames, - // This makes the apiserver allowed to talk to the kubelets in the cluster - Organization: []string{"system:masters"}, - Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, } apiCert, apiKey, err := pkiutil.NewCertAndKey(caCert, caKey, config) if err != nil { @@ -138,6 +136,35 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiDir string) error { fmt.Println("[certificates] Generated API server certificate and key.") } + // If at least one of them exists, we should try to load them + // In the case that only one exists, there will most likely be an error anyway + if pkiutil.CertOrKeyExist(pkiDir, kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName) { + // Try to load apiserver-kubelet-client.crt and apiserver-kubelet-client.key from the PKI directory + apiCert, apiKey, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName) + if err != nil || apiCert == nil || apiKey == nil { + return fmt.Errorf("certificate and/or key existed but they could not be loaded properly") + } + + fmt.Println("[certificates] Using the existing API Server kubelet client certificate and key.") + } else { + // The certificate and the key did NOT exist, let's generate them now + // TODO: Add a test case to verify that this cert has the x509.ExtKeyUsageClientAuth flag + config := certutil.Config{ + CommonName: "kube-apiserver-kubelet-client", + Organization: []string{"system:masters"}, + Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, + } + apiClientCert, apiClientKey, err := pkiutil.NewCertAndKey(caCert, caKey, config) + if err != nil { + return fmt.Errorf("failure while creating API server kubelet client key and certificate [%v]", err) + } + + if err = pkiutil.WriteCertAndKey(pkiDir, kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName, apiClientCert, apiClientKey); err != nil { + return fmt.Errorf("failure while saving API server kubelet client certificate and key [%v]", err) + } + fmt.Println("[certificates] Generated API server kubelet client certificate and key.") + } + fmt.Printf("[certificates] Valid certificates and keys now exist in %q\n", pkiDir) return nil