diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go index 5b1db1d06a6..10d78f734de 100644 --- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go +++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go @@ -43,6 +43,8 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { obj.AuthorizationModes = []string{"foo"} obj.CertificatesDir = "foo" obj.APIServerCertSANs = []string{"foo"} + obj.Etcd.ServerCertSANs = []string{"foo"} + obj.Etcd.PeerCertSANs = []string{"foo"} obj.Token = "foo" obj.CRISocket = "foo" obj.Etcd.Image = "foo" diff --git a/cmd/kubeadm/app/apis/kubeadm/types.go b/cmd/kubeadm/app/apis/kubeadm/types.go index 70edf13f39a..cf6c9db3a1f 100644 --- a/cmd/kubeadm/app/apis/kubeadm/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/types.go @@ -178,6 +178,12 @@ type Etcd struct { Image string // SelfHosted holds configuration for self-hosting etcd. SelfHosted *SelfHostedEtcd + // ServerCertSANs sets extra Subject Alternative Names for the etcd server + // signing cert. This is currently used for the etcd static-pod. + ServerCertSANs []string + // PeerCertSANs sets extra Subject Alternative Names for the etcd peer + // signing cert. This is currently used for the etcd static-pod. + PeerCertSANs []string } // SelfHostedEtcd describes options required to configure self-hosted etcd. diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go index 066dd7979cf..4d94ad7f208 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go @@ -170,6 +170,10 @@ type Etcd struct { Image string `json:"image"` // SelfHosted holds configuration for self-hosting etcd. SelfHosted *SelfHostedEtcd `json:"selfHosted,omitempty"` + // ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert. + ServerCertSANs []string `json:"serverCertSANs,omitempty"` + // PeerCertSANs sets extra Subject Alternative Names for the etcd peer signing cert. + PeerCertSANs []string `json:"peerCertSANs,omitempty"` } // SelfHostedEtcd describes options required to configure self-hosted etcd. diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.conversion.go index 80c47bf9b90..1f5b4d2d0a0 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.conversion.go @@ -122,6 +122,8 @@ func autoConvert_v1alpha1_Etcd_To_kubeadm_Etcd(in *Etcd, out *kubeadm.Etcd, s co out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) out.Image = in.Image out.SelfHosted = (*kubeadm.SelfHostedEtcd)(unsafe.Pointer(in.SelfHosted)) + out.ServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ServerCertSANs)) + out.PeerCertSANs = *(*[]string)(unsafe.Pointer(&in.PeerCertSANs)) return nil } @@ -139,6 +141,8 @@ func autoConvert_kubeadm_Etcd_To_v1alpha1_Etcd(in *kubeadm.Etcd, out *Etcd, s co out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) out.Image = in.Image out.SelfHosted = (*SelfHostedEtcd)(unsafe.Pointer(in.SelfHosted)) + out.ServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ServerCertSANs)) + out.PeerCertSANs = *(*[]string)(unsafe.Pointer(&in.PeerCertSANs)) return nil } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.deepcopy.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.deepcopy.go index 4eb4e008641..578c431af99 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.deepcopy.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.deepcopy.go @@ -92,6 +92,16 @@ func (in *Etcd) DeepCopyInto(out *Etcd) { **out = **in } } + if in.ServerCertSANs != nil { + in, out := &in.ServerCertSANs, &out.ServerCertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PeerCertSANs != nil { + in, out := &in.PeerCertSANs, &out.PeerCertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/validation.go b/cmd/kubeadm/app/apis/kubeadm/validation/validation.go index 27c31e0157a..3e8aa557515 100644 --- a/cmd/kubeadm/app/apis/kubeadm/validation/validation.go +++ b/cmd/kubeadm/app/apis/kubeadm/validation/validation.go @@ -72,7 +72,9 @@ func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList allErrs = append(allErrs, ValidateCloudProvider(c.CloudProvider, field.NewPath("cloudprovider"))...) allErrs = append(allErrs, ValidateAuthorizationModes(c.AuthorizationModes, field.NewPath("authorization-modes"))...) allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...) - allErrs = append(allErrs, ValidateAPIServerCertSANs(c.APIServerCertSANs, field.NewPath("cert-altnames"))...) + allErrs = append(allErrs, ValidateCertSANs(c.APIServerCertSANs, field.NewPath("api-server-cert-altnames"))...) + allErrs = append(allErrs, ValidateCertSANs(c.Etcd.ServerCertSANs, field.NewPath("etcd-server-cert-altnames"))...) + allErrs = append(allErrs, ValidateCertSANs(c.Etcd.PeerCertSANs, field.NewPath("etcd-peer-cert-altnames"))...) allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificates-dir"))...) allErrs = append(allErrs, ValidateNodeName(c.NodeName, field.NewPath("node-name"))...) allErrs = append(allErrs, ValidateToken(c.Token, field.NewPath("token"))...) @@ -228,8 +230,8 @@ func ValidateToken(t string, fldPath *field.Path) field.ErrorList { return allErrs } -// ValidateAPIServerCertSANs validates alternative names -func ValidateAPIServerCertSANs(altnames []string, fldPath *field.Path) field.ErrorList { +// ValidateCertSANs validates alternative names +func ValidateCertSANs(altnames []string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} for _, altname := range altnames { if len(validation.IsDNS1123Subdomain(altname)) != 0 && net.ParseIP(altname) == nil { diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go b/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go index 331ad37609d..29262a998c1 100644 --- a/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go +++ b/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go @@ -134,7 +134,7 @@ func TestValidateCloudProvider(t *testing.T) { } } -func TestValidateAPIServerCertSANs(t *testing.T) { +func TestValidateCertSANs(t *testing.T) { var tests = []struct { sans []string expected bool @@ -148,10 +148,10 @@ func TestValidateAPIServerCertSANs(t *testing.T) { {[]string{"my-hostname2", "my.other.subdomain", "2001:db8::10"}, true}, // supported } for _, rt := range tests { - actual := ValidateAPIServerCertSANs(rt.sans, nil) + actual := ValidateCertSANs(rt.sans, nil) if (len(actual) == 0) != rt.expected { t.Errorf( - "failed ValidateAPIServerCertSANs:\n\texpected: %t\n\t actual: %t", + "failed ValidateCertSANs:\n\texpected: %t\n\t actual: %t", rt.expected, (len(actual) == 0), ) diff --git a/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go b/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go index 93775c57a21..30c6c6c5d92 100644 --- a/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go +++ b/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go @@ -92,6 +92,16 @@ func (in *Etcd) DeepCopyInto(out *Etcd) { **out = **in } } + if in.ServerCertSANs != nil { + in, out := &in.ServerCertSANs, &out.ServerCertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PeerCertSANs != nil { + in, out := &in.PeerCertSANs, &out.PeerCertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/cmd/kubeadm/app/cmd/phases/certs.go b/cmd/kubeadm/app/cmd/phases/certs.go index 5d4e040d7e3..564b8754749 100644 --- a/cmd/kubeadm/app/cmd/phases/certs.go +++ b/cmd/kubeadm/app/cmd/phases/certs.go @@ -60,8 +60,8 @@ var ( apiServerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(` Generates the API server serving certificate and key and saves them into %s and %s files. - The certificate includes default subject alternative names and additional sans eventually provided by the user; - default sans are: , , kubernetes, kubernetes.default, kubernetes.default.svc, + The certificate includes default subject alternative names and additional SANs provided by the user; + default SANs are: , , kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc., (that is the .10 address in address space). If both files already exist, kubeadm skips the generation step and existing files will be used. @@ -74,27 +74,25 @@ var ( If both files already exist, kubeadm skips the generation step and existing files will be used. `+cmdutil.AlphaDisclaimer), kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName) - etcdCertLongDesc = fmt.Sprintf(normalizer.LongDesc(` + etcdServerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(` Generates the etcd serving certificate and key and saves them into %s and %s files. - The certificate includes default subject alternative names and additional sans eventually provided by the user; - default sans are: , , kubernetes, kubernetes.default, kubernetes.default.svc, - kubernetes.default.svc., (that is the .10 address in address space). + The certificate includes default subject alternative names and additional SANs provided by the user; + default SANs are: localhost, 127.0.0.1. If both files already exist, kubeadm skips the generation step and existing files will be used. - `+cmdutil.AlphaDisclaimer), kubeadmconstants.EtcdCertName, kubeadmconstants.EtcdKeyName) + `+cmdutil.AlphaDisclaimer), kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName) etcdPeerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(` Generates the etcd peer certificate and key and saves them into %s and %s files. - The certificate includes default subject alternative names and additional sans eventually provided by the user; - default sans are: , , kubernetes, kubernetes.default, kubernetes.default.svc, - kubernetes.default.svc., (that is the .10 address in address space). + The certificate includes default subject alternative names and additional SANs provided by the user; + default SANs are: , . If both files already exist, kubeadm skips the generation step and existing files will be used. `+cmdutil.AlphaDisclaimer), kubeadmconstants.EtcdPeerCertName, kubeadmconstants.EtcdPeerKeyName) - apiServerEtcdCertLongDesc = fmt.Sprintf(normalizer.LongDesc(` + apiServerEtcdServerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(` Generates the client certificate for the API server to connect to etcd securely and the respective key, and saves them into %s and %s files. @@ -187,8 +185,8 @@ func getCertsSubCommands(defaultKubernetesVersion string) []*cobra.Command { { use: "etcd-server", short: "Generates etcd serving certificate and key", - long: etcdCertLongDesc, - cmdFunc: certsphase.CreateEtcdCertAndKeyFiles, + long: etcdServerCertLongDesc, + cmdFunc: certsphase.CreateEtcdServerCertAndKeyFiles, }, { use: "etcd-peer", @@ -199,7 +197,7 @@ func getCertsSubCommands(defaultKubernetesVersion string) []*cobra.Command { { use: "apiserver-etcd-client", short: "Generates client certificate for the API server to connect to etcd securely", - long: apiServerEtcdCertLongDesc, + long: apiServerEtcdServerCertLongDesc, cmdFunc: certsphase.CreateAPIServerEtcdClientCertAndKeyFiles, }, { diff --git a/cmd/kubeadm/app/constants/constants.go b/cmd/kubeadm/app/constants/constants.go index a7bd2e52ed5..c2986240744 100644 --- a/cmd/kubeadm/app/constants/constants.go +++ b/cmd/kubeadm/app/constants/constants.go @@ -65,21 +65,21 @@ const ( // APIServerKubeletClientCertCommonName defines kubelet client certificate common name (CN) APIServerKubeletClientCertCommonName = "kube-apiserver-kubelet-client" - // EtcdCertAndKeyBaseName defines etcd's server certificate and key base name - EtcdCertAndKeyBaseName = "etcd-server" - // EtcdCertName defines etcd's server certificate name - EtcdCertName = "etcd-server.crt" - // EtcdKeyName defines etcd's server key name - EtcdKeyName = "etcd-server.key" - // EtcdCertCommonName defines etcd's server certificate common name (CN) - EtcdCertCommonName = "kube-etcd" + // EtcdServerCertAndKeyBaseName defines etcd's server certificate and key base name + EtcdServerCertAndKeyBaseName = "etcd/server" + // EtcdServerCertName defines etcd's server certificate name + EtcdServerCertName = "etcd/server.crt" + // EtcdServerKeyName defines etcd's server key name + EtcdServerKeyName = "etcd/server.key" + // EtcdServerCertCommonName defines etcd's server certificate common name (CN) + EtcdServerCertCommonName = "kube-etcd" // EtcdPeerCertAndKeyBaseName defines etcd's peer certificate and key base name - EtcdPeerCertAndKeyBaseName = "etcd-peer" + EtcdPeerCertAndKeyBaseName = "etcd/peer" // EtcdPeerCertName defines etcd's peer certificate name - EtcdPeerCertName = "etcd-peer.crt" + EtcdPeerCertName = "etcd/peer.crt" // EtcdPeerKeyName defines etcd's peer key name - EtcdPeerKeyName = "etcd-peer.key" + EtcdPeerKeyName = "etcd/peer.key" // EtcdPeerCertCommonName defines etcd's peer certificate common name (CN) EtcdPeerCertCommonName = "kube-etcd-peer" diff --git a/cmd/kubeadm/app/phases/certs/BUILD b/cmd/kubeadm/app/phases/certs/BUILD index 617c57d09c7..3ac7c0fab75 100644 --- a/cmd/kubeadm/app/phases/certs/BUILD +++ b/cmd/kubeadm/app/phases/certs/BUILD @@ -30,8 +30,6 @@ go_library( "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", - "//pkg/registry/core/service/ipallocator:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//vendor/k8s.io/client-go/util/cert:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/certs/certs.go b/cmd/kubeadm/app/phases/certs/certs.go index 8d0cff3c8c8..4c7df216944 100644 --- a/cmd/kubeadm/app/phases/certs/certs.go +++ b/cmd/kubeadm/app/phases/certs/certs.go @@ -20,16 +20,13 @@ import ( "crypto/rsa" "crypto/x509" "fmt" - "net" "os" "path/filepath" - "k8s.io/apimachinery/pkg/util/validation" certutil "k8s.io/client-go/util/cert" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" - "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" ) // CreatePKIAssets will create and write to disk all PKI assets necessary to establish the control plane. @@ -40,7 +37,7 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration) error { CreateCACertAndKeyfiles, CreateAPIServerCertAndKeyFiles, CreateAPIServerKubeletClientCertAndKeyFiles, - CreateEtcdCertAndKeyFiles, + CreateEtcdServerCertAndKeyFiles, CreateEtcdPeerCertAndKeyFiles, CreateAPIServerEtcdClientCertAndKeyFiles, CreateServiceAccountKeyAndPublicKeyFiles, @@ -125,27 +122,27 @@ func CreateAPIServerKubeletClientCertAndKeyFiles(cfg *kubeadmapi.MasterConfigura ) } -// CreateEtcdCertAndKeyFiles create a new certificate and key file for etcd. +// CreateEtcdServerCertAndKeyFiles create a new certificate and key file for etcd. // If the etcd serving certificate and key file already exist in the target folder, they are used only if evaluated equal; otherwise an error is returned. // It assumes the cluster CA certificate and key file exist in the CertificatesDir -func CreateEtcdCertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error { +func CreateEtcdServerCertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error { caCert, caKey, err := loadCertificateAuthorithy(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName) if err != nil { return err } - etcdCert, etcdKey, err := NewEtcdCertAndKey(cfg, caCert, caKey) + etcdServerCert, etcdServerKey, err := NewEtcdServerCertAndKey(cfg, caCert, caKey) if err != nil { return err } return writeCertificateFilesIfNotExist( cfg.CertificatesDir, - kubeadmconstants.EtcdCertAndKeyBaseName, + kubeadmconstants.EtcdServerCertAndKeyBaseName, caCert, - etcdCert, - etcdKey, + etcdServerCert, + etcdServerKey, ) } @@ -271,7 +268,7 @@ func NewCACertAndKey() (*x509.Certificate, *rsa.PrivateKey, error) { // NewAPIServerCertAndKey generate CA certificate for apiserver, signed by the given CA. func NewAPIServerCertAndKey(cfg *kubeadmapi.MasterConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) { - altNames, err := getAltNames(cfg) + altNames, err := pkiutil.GetAPIServerAltNames(cfg) if err != nil { return nil, nil, fmt.Errorf("failure while composing altnames for API server: %v", err) } @@ -305,31 +302,31 @@ func NewAPIServerKubeletClientCertAndKey(caCert *x509.Certificate, caKey *rsa.Pr return apiClientCert, apiClientKey, nil } -// NewEtcdCertAndKey generate CA certificate for etcd, signed by the given CA. -func NewEtcdCertAndKey(cfg *kubeadmapi.MasterConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) { +// NewEtcdServerCertAndKey generate CA certificate for etcd, signed by the given CA. +func NewEtcdServerCertAndKey(cfg *kubeadmapi.MasterConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) { - altNames, err := getAltNames(cfg) + altNames, err := pkiutil.GetEtcdAltNames(cfg) if err != nil { return nil, nil, fmt.Errorf("failure while composing altnames for etcd: %v", err) } config := certutil.Config{ - CommonName: kubeadmconstants.EtcdCertCommonName, + CommonName: kubeadmconstants.EtcdServerCertCommonName, AltNames: *altNames, Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, } - etcdCert, etcdKey, err := pkiutil.NewCertAndKey(caCert, caKey, config) + etcdServerCert, etcdServerKey, err := pkiutil.NewCertAndKey(caCert, caKey, config) if err != nil { return nil, nil, fmt.Errorf("failure while creating etcd key and certificate: %v", err) } - return etcdCert, etcdKey, nil + return etcdServerCert, etcdServerKey, nil } // NewEtcdPeerCertAndKey generate CA certificate for etcd peering, signed by the given CA. func NewEtcdPeerCertAndKey(cfg *kubeadmapi.MasterConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) { - altNames, err := getAltNames(cfg) + altNames, err := pkiutil.GetEtcdPeerAltNames(cfg) if err != nil { return nil, nil, fmt.Errorf("failure while composing altnames for etcd peering: %v", err) } @@ -636,55 +633,3 @@ func validatePrivatePublicKey(l certKeyLocation) error { } return nil } - -// getAltNames builds an AltNames object for to be used when generating apiserver certificate -func getAltNames(cfg *kubeadmapi.MasterConfiguration) (*certutil.AltNames, error) { - - // advertise address - advertiseAddress := net.ParseIP(cfg.API.AdvertiseAddress) - if advertiseAddress == nil { - return nil, fmt.Errorf("error parsing API AdvertiseAddress %v: is not a valid textual representation of an IP address", cfg.API.AdvertiseAddress) - } - - // internal IP address for the API server - _, svcSubnet, err := net.ParseCIDR(cfg.Networking.ServiceSubnet) - if err != nil { - return nil, fmt.Errorf("error parsing CIDR %q: %v", cfg.Networking.ServiceSubnet, err) - } - - internalAPIServerVirtualIP, err := ipallocator.GetIndexedIP(svcSubnet, 1) - if err != nil { - return nil, fmt.Errorf("unable to get first IP address from the given CIDR (%s): %v", svcSubnet.String(), err) - } - - // create AltNames with defaults DNSNames/IPs - altNames := &certutil.AltNames{ - DNSNames: []string{ - cfg.NodeName, - "kubernetes", - "kubernetes.default", - "kubernetes.default.svc", - fmt.Sprintf("kubernetes.default.svc.%s", cfg.Networking.DNSDomain), - }, - IPs: []net.IP{ - internalAPIServerVirtualIP, - advertiseAddress, - }, - } - - // adds additional SAN - for _, altname := range cfg.APIServerCertSANs { - if ip := net.ParseIP(altname); ip != nil { - altNames.IPs = append(altNames.IPs, ip) - } else if len(validation.IsDNS1123Subdomain(altname)) == 0 { - altNames.DNSNames = append(altNames.DNSNames, altname) - } - } - - // add api server dns advertise address - if len(cfg.API.ControlPlaneEndpoint) > 0 { - altNames.DNSNames = append(altNames.DNSNames, cfg.API.ControlPlaneEndpoint) - } - - return altNames, nil -} diff --git a/cmd/kubeadm/app/phases/certs/certs_test.go b/cmd/kubeadm/app/phases/certs/certs_test.go index 0a93f1e1869..58223adf89b 100644 --- a/cmd/kubeadm/app/phases/certs/certs_test.go +++ b/cmd/kubeadm/app/phases/certs/certs_test.go @@ -258,53 +258,6 @@ func TestWriteKeyFilesIfNotExist(t *testing.T) { } } -func TestGetAltNames(t *testing.T) { - hostname := "valid-hostname" - advertiseIP := "1.2.3.4" - controlPlaneEndpoint := "api.k8s.io" - cfg := &kubeadmapi.MasterConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: advertiseIP, ControlPlaneEndpoint: controlPlaneEndpoint}, - Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - NodeName: hostname, - APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95"}, - } - - altNames, err := getAltNames(cfg) - if err != nil { - t.Fatalf("failed calling getAltNames: %v", err) - } - - expectedDNSNames := []string{hostname, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local", controlPlaneEndpoint} - for _, DNSName := range expectedDNSNames { - found := false - for _, val := range altNames.DNSNames { - if val == DNSName { - found = true - break - } - } - - if !found { - t.Errorf("altNames does not contain DNSName %s", DNSName) - } - } - - expectedIPAddresses := []string{"10.96.0.1", advertiseIP, "10.1.245.94", "10.1.245.95"} - for _, IPAddress := range expectedIPAddresses { - found := false - for _, val := range altNames.IPs { - if val.Equal(net.ParseIP(IPAddress)) { - found = true - break - } - } - - if !found { - t.Errorf("altNames does not contain IPAddress %s", IPAddress) - } - } -} - func TestNewCACertAndKey(t *testing.T) { caCert, _, err := NewCACertAndKey() if err != nil { @@ -357,42 +310,50 @@ func TestNewAPIServerKubeletClientCertAndKey(t *testing.T) { certstestutil.AssertCertificateHasOrganizations(t, apiClientCert, kubeadmconstants.MastersGroup) } -func TestNewEtcdCertAndKey(t *testing.T) { - hostname := "valid-hostname" +func TestNewEtcdServerCertAndKey(t *testing.T) { + proxy := "user-etcd-proxy" + proxyIP := "10.10.10.100" - advertiseAddresses := []string{"1.2.3.4", "1:2:3::4"} - for _, addr := range advertiseAddresses { - cfg := &kubeadmapi.MasterConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: addr}, - Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - NodeName: "valid-hostname", - } - caCert, caKey, err := NewCACertAndKey() - if err != nil { - t.Fatalf("failed creation of ca cert and key: %v", err) - } - - etcdCert, _, err := NewEtcdCertAndKey(cfg, caCert, caKey) - if err != nil { - t.Fatalf("failed creation of cert and key: %v", err) - } - - certstestutil.AssertCertificateIsSignedByCa(t, etcdCert, caCert) - certstestutil.AssertCertificateHasServerAuthUsage(t, etcdCert) - certstestutil.AssertCertificateHasDNSNames(t, etcdCert, hostname, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local") - certstestutil.AssertCertificateHasIPAddresses(t, etcdCert, net.ParseIP("10.96.0.1"), net.ParseIP(addr)) + cfg := &kubeadmapi.MasterConfiguration{ + Etcd: kubeadmapi.Etcd{ + ServerCertSANs: []string{ + proxy, + proxyIP, + }, + }, } + caCert, caKey, err := NewCACertAndKey() + if err != nil { + t.Fatalf("failed creation of ca cert and key: %v", err) + } + + etcdServerCert, _, err := NewEtcdServerCertAndKey(cfg, caCert, caKey) + if err != nil { + t.Fatalf("failed creation of cert and key: %v", err) + } + + certstestutil.AssertCertificateIsSignedByCa(t, etcdServerCert, caCert) + certstestutil.AssertCertificateHasServerAuthUsage(t, etcdServerCert) + certstestutil.AssertCertificateHasDNSNames(t, etcdServerCert, "localhost", proxy) + certstestutil.AssertCertificateHasIPAddresses(t, etcdServerCert, net.ParseIP("127.0.0.1"), net.ParseIP(proxyIP)) } func TestNewEtcdPeerCertAndKey(t *testing.T) { hostname := "valid-hostname" + proxy := "user-etcd-proxy" + proxyIP := "10.10.10.100" advertiseAddresses := []string{"1.2.3.4", "1:2:3::4"} for _, addr := range advertiseAddresses { cfg := &kubeadmapi.MasterConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: addr}, - Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - NodeName: "valid-hostname", + API: kubeadmapi.API{AdvertiseAddress: addr}, + NodeName: hostname, + Etcd: kubeadmapi.Etcd{ + PeerCertSANs: []string{ + proxy, + proxyIP, + }, + }, } caCert, caKey, err := NewCACertAndKey() if err != nil { @@ -407,8 +368,8 @@ func TestNewEtcdPeerCertAndKey(t *testing.T) { certstestutil.AssertCertificateIsSignedByCa(t, etcdPeerCert, caCert) certstestutil.AssertCertificateHasServerAuthUsage(t, etcdPeerCert) certstestutil.AssertCertificateHasClientAuthUsage(t, etcdPeerCert) - certstestutil.AssertCertificateHasDNSNames(t, etcdPeerCert, hostname, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local") - certstestutil.AssertCertificateHasIPAddresses(t, etcdPeerCert, net.ParseIP("10.96.0.1"), net.ParseIP(addr)) + certstestutil.AssertCertificateHasDNSNames(t, etcdPeerCert, hostname, proxy) + certstestutil.AssertCertificateHasIPAddresses(t, etcdPeerCert, net.ParseIP(addr), net.ParseIP(proxyIP)) } } @@ -622,6 +583,9 @@ func TestCreateCertificateFilesMethods(t *testing.T) { kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName, + kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName, + kubeadmconstants.EtcdPeerCertName, kubeadmconstants.EtcdPeerKeyName, + kubeadmconstants.APIServerEtcdClientCertName, kubeadmconstants.APIServerEtcdClientKeyName, kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName, kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName, @@ -643,8 +607,8 @@ func TestCreateCertificateFilesMethods(t *testing.T) { }, { setupFunc: CreateCACertAndKeyfiles, - createFunc: CreateEtcdCertAndKeyFiles, - expectedFiles: []string{kubeadmconstants.EtcdCertName, kubeadmconstants.EtcdKeyName}, + createFunc: CreateEtcdServerCertAndKeyFiles, + expectedFiles: []string{kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName}, }, { setupFunc: CreateCACertAndKeyfiles, diff --git a/cmd/kubeadm/app/phases/certs/doc.go b/cmd/kubeadm/app/phases/certs/doc.go index ef9ea9689d5..da538747af7 100644 --- a/cmd/kubeadm/app/phases/certs/doc.go +++ b/cmd/kubeadm/app/phases/certs/doc.go @@ -24,6 +24,8 @@ package certs From MasterConfiguration .API.AdvertiseAddress is an optional parameter that can be passed for an extra addition to the SAN IPs .APIServerCertSANs is an optional parameter for adding DNS names and IPs to the API Server serving cert SAN + .Etcd.ServerCertSANs is an optional parameter for adding DNS names and IPs to the etcd serving cert SAN + .Etcd.PeerCertSANs is an optional parameter for adding DNS names and IPs to the etcd peer cert SAN .Networking.DNSDomain is needed for knowing which DNS name the internal kubernetes service has .Networking.ServiceSubnet is needed for knowing which IP the internal kubernetes service is going to point to .CertificatesDir is required for knowing where all certificates should be stored @@ -36,12 +38,12 @@ package certs - apiserver.key - apiserver-kubelet-client.crt - apiserver-kubelet-client.key - - etcd-server.crt - - etcd-server.key - - etcd-peer.crt - - etcd-peer.key - apiserver-etcd-client.crt - apiserver-etcd-client.key + - etcd/server.crt + - etcd/server.key + - etcd/peer.crt + - etcd/peer.key - sa.pub - sa.key - front-proxy-ca.crt diff --git a/cmd/kubeadm/app/phases/certs/pkiutil/BUILD b/cmd/kubeadm/app/phases/certs/pkiutil/BUILD index cb91095764b..f4c8a743178 100644 --- a/cmd/kubeadm/app/phases/certs/pkiutil/BUILD +++ b/cmd/kubeadm/app/phases/certs/pkiutil/BUILD @@ -10,14 +10,23 @@ go_test( name = "go_default_test", srcs = ["pki_helpers_test.go"], embed = [":go_default_library"], - deps = ["//vendor/k8s.io/client-go/util/cert:go_default_library"], + deps = [ + "//cmd/kubeadm/app/apis/kubeadm:go_default_library", + "//vendor/k8s.io/client-go/util/cert:go_default_library", + ], ) go_library( name = "go_default_library", srcs = ["pki_helpers.go"], importpath = "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil", - deps = ["//vendor/k8s.io/client-go/util/cert:go_default_library"], + deps = [ + "//cmd/kubeadm/app/apis/kubeadm:go_default_library", + "//cmd/kubeadm/app/constants:go_default_library", + "//pkg/registry/core/service/ipallocator:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library", + "//vendor/k8s.io/client-go/util/cert:go_default_library", + ], ) filegroup( diff --git a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go b/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go index e6bcb27c955..996688ee685 100644 --- a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go +++ b/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go @@ -20,11 +20,16 @@ import ( "crypto/rsa" "crypto/x509" "fmt" + "net" "os" "path/filepath" "time" + "k8s.io/apimachinery/pkg/util/validation" certutil "k8s.io/client-go/util/cert" + kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" + kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" + "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" ) // NewCertificateAuthority creates new certificate and private key for the certificate authority @@ -246,3 +251,106 @@ func pathForKey(pkiPath, name string) string { func pathForPublicKey(pkiPath, name string) string { return filepath.Join(pkiPath, fmt.Sprintf("%s.pub", name)) } + +// GetAPIServerAltNames builds an AltNames object for to be used when generating apiserver certificate +func GetAPIServerAltNames(cfg *kubeadmapi.MasterConfiguration) (*certutil.AltNames, error) { + // advertise address + advertiseAddress := net.ParseIP(cfg.API.AdvertiseAddress) + if advertiseAddress == nil { + return nil, fmt.Errorf("error parsing API AdvertiseAddress %v: is not a valid textual representation of an IP address", cfg.API.AdvertiseAddress) + } + + // internal IP address for the API server + _, svcSubnet, err := net.ParseCIDR(cfg.Networking.ServiceSubnet) + if err != nil { + return nil, fmt.Errorf("error parsing CIDR %q: %v", cfg.Networking.ServiceSubnet, err) + } + + internalAPIServerVirtualIP, err := ipallocator.GetIndexedIP(svcSubnet, 1) + if err != nil { + return nil, fmt.Errorf("unable to get first IP address from the given CIDR (%s): %v", svcSubnet.String(), err) + } + + // create AltNames with defaults DNSNames/IPs + altNames := &certutil.AltNames{ + DNSNames: []string{ + cfg.NodeName, + "kubernetes", + "kubernetes.default", + "kubernetes.default.svc", + fmt.Sprintf("kubernetes.default.svc.%s", cfg.Networking.DNSDomain), + }, + IPs: []net.IP{ + internalAPIServerVirtualIP, + advertiseAddress, + }, + } + + // add api server dns advertise address + if len(cfg.API.ControlPlaneEndpoint) > 0 { + altNames.DNSNames = append(altNames.DNSNames, cfg.API.ControlPlaneEndpoint) + } + + appendSANsToAltNames(altNames, cfg.APIServerCertSANs, kubeadmconstants.APIServerCertName) + + return altNames, nil +} + +// GetEtcdAltNames builds an AltNames object for generating the etcd server certificate. +// `localhost` is included in the SAN since this is the interface the etcd static pod listens on. +// Hostname and `API.AdvertiseAddress` are excluded since etcd does not listen on this interface by default. +// The user can override the listen address with `Etcd.ExtraArgs` and add SANs with `Etcd.ServerCertSANs`. +func GetEtcdAltNames(cfg *kubeadmapi.MasterConfiguration) (*certutil.AltNames, error) { + // create AltNames with defaults DNSNames/IPs + altNames := &certutil.AltNames{ + DNSNames: []string{"localhost"}, + IPs: []net.IP{net.IPv4(127, 0, 0, 1)}, + } + + appendSANsToAltNames(altNames, cfg.Etcd.ServerCertSANs, kubeadmconstants.EtcdServerCertName) + + return altNames, nil +} + +// GetEtcdPeerAltNames builds an AltNames object for generating the etcd peer certificate. +// `localhost` is excluded from the SAN since etcd will not refer to itself as a peer. +// Hostname and `API.AdvertiseAddress` are included if the user chooses to promote the single node etcd cluster into a multi-node one. +// The user can override the listen address with `Etcd.ExtraArgs` and add SANs with `Etcd.PeerCertSANs`. +func GetEtcdPeerAltNames(cfg *kubeadmapi.MasterConfiguration) (*certutil.AltNames, error) { + // advertise address + advertiseAddress := net.ParseIP(cfg.API.AdvertiseAddress) + if advertiseAddress == nil { + return nil, fmt.Errorf("error parsing API AdvertiseAddress %v: is not a valid textual representation of an IP address", cfg.API.AdvertiseAddress) + } + + // create AltNames with defaults DNSNames/IPs + altNames := &certutil.AltNames{ + DNSNames: []string{cfg.NodeName}, + IPs: []net.IP{advertiseAddress}, + } + + appendSANsToAltNames(altNames, cfg.Etcd.PeerCertSANs, kubeadmconstants.EtcdPeerCertName) + + return altNames, nil +} + +// appendSANsToAltNames parses SANs from as list of strings and adds them to altNames for use on a specific cert +// altNames is passed in with a pointer, and the struct is modified +// valid IP address strings are parsed and added to altNames.IPs as net.IP's +// RFC-1123 compliant DNS strings are added to altNames.DNSNames as strings +// certNames is used to print user facing warnings and should be the name of the cert the altNames will be used for +func appendSANsToAltNames(altNames *certutil.AltNames, SANs []string, certName string) { + for _, altname := range SANs { + if ip := net.ParseIP(altname); ip != nil { + altNames.IPs = append(altNames.IPs, ip) + } else if len(validation.IsDNS1123Subdomain(altname)) == 0 { + altNames.DNSNames = append(altNames.DNSNames, altname) + } else { + fmt.Printf( + "[certificates] WARNING: '%s' was not added to the '%s' SAN, because it is not a valid IP or RFC-1123 compliant DNS entry\n", + altname, + certName, + ) + } + } +} diff --git a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go b/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go index 34ac26ee14c..ba4057c6c92 100644 --- a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go +++ b/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go @@ -21,10 +21,12 @@ import ( "crypto/rsa" "crypto/x509" "io/ioutil" + "net" "os" "testing" certutil "k8s.io/client-go/util/cert" + kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" ) func TestNewCertificateAuthority(t *testing.T) { @@ -432,3 +434,154 @@ func TestPathForPublicKey(t *testing.T) { t.Errorf("unexpected certificate path: %s", pubPath) } } + +func TestGetAPIServerAltNames(t *testing.T) { + hostname := "valid-hostname" + advertiseIP := "1.2.3.4" + controlPlaneEndpoint := "api.k8s.io" + cfg := &kubeadmapi.MasterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: advertiseIP, ControlPlaneEndpoint: controlPlaneEndpoint}, + Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + NodeName: hostname, + APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + } + + altNames, err := GetAPIServerAltNames(cfg) + if err != nil { + t.Fatalf("failed calling GetAPIServerAltNames: %v", err) + } + + expectedDNSNames := []string{hostname, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local", controlPlaneEndpoint} + for _, DNSName := range expectedDNSNames { + found := false + for _, val := range altNames.DNSNames { + if val == DNSName { + found = true + break + } + } + + if !found { + t.Errorf("altNames does not contain DNSName %s", DNSName) + } + } + + expectedIPAddresses := []string{"10.96.0.1", advertiseIP, "10.1.245.94", "10.1.245.95"} + for _, IPAddress := range expectedIPAddresses { + found := false + for _, val := range altNames.IPs { + if val.Equal(net.ParseIP(IPAddress)) { + found = true + break + } + } + + if !found { + t.Errorf("altNames does not contain IPAddress %s", IPAddress) + } + } +} + +func TestGetEtcdAltNames(t *testing.T) { + proxy := "user-etcd-proxy" + proxyIP := "10.10.10.100" + cfg := &kubeadmapi.MasterConfiguration{ + Etcd: kubeadmapi.Etcd{ + ServerCertSANs: []string{ + proxy, + proxyIP, + "1.2.3.L", + "invalid,commas,in,DNS", + }, + }, + } + + altNames, err := GetEtcdAltNames(cfg) + if err != nil { + t.Fatalf("failed calling GetEtcdAltNames: %v", err) + } + + expectedDNSNames := []string{"localhost", proxy} + for _, DNSName := range expectedDNSNames { + found := false + for _, val := range altNames.DNSNames { + if val == DNSName { + found = true + break + } + } + + if !found { + t.Errorf("altNames does not contain DNSName %s", DNSName) + } + } + + expectedIPAddresses := []string{"127.0.0.1", proxyIP} + for _, IPAddress := range expectedIPAddresses { + found := false + for _, val := range altNames.IPs { + if val.Equal(net.ParseIP(IPAddress)) { + found = true + break + } + } + + if !found { + t.Errorf("altNames does not contain IPAddress %s", IPAddress) + } + } +} + +func TestGetEtcdPeerAltNames(t *testing.T) { + hostname := "valid-hostname" + proxy := "user-etcd-proxy" + proxyIP := "10.10.10.100" + advertiseIP := "1.2.3.4" + cfg := &kubeadmapi.MasterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: advertiseIP}, + NodeName: hostname, + Etcd: kubeadmapi.Etcd{ + PeerCertSANs: []string{ + proxy, + proxyIP, + "1.2.3.L", + "invalid,commas,in,DNS", + }, + }, + } + + altNames, err := GetEtcdPeerAltNames(cfg) + if err != nil { + t.Fatalf("failed calling GetEtcdPeerAltNames: %v", err) + } + + expectedDNSNames := []string{hostname, proxy} + for _, DNSName := range expectedDNSNames { + found := false + for _, val := range altNames.DNSNames { + if val == DNSName { + found = true + break + } + } + + if !found { + t.Errorf("altNames does not contain DNSName %s", DNSName) + } + } + + expectedIPAddresses := []string{advertiseIP, proxyIP} + for _, IPAddress := range expectedIPAddresses { + found := false + for _, val := range altNames.IPs { + if val.Equal(net.ParseIP(IPAddress)) { + found = true + break + } + } + + if !found { + t.Errorf("altNames does not contain IPAddress %s", IPAddress) + } + } +} diff --git a/cmd/kubeadm/app/phases/controlplane/manifests.go b/cmd/kubeadm/app/phases/controlplane/manifests.go index 169ee18c589..123763c2dce 100644 --- a/cmd/kubeadm/app/phases/controlplane/manifests.go +++ b/cmd/kubeadm/app/phases/controlplane/manifests.go @@ -213,13 +213,13 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, k8sVersion *versio // Warn for unused user supplied variables if cfg.Etcd.CAFile != "" { - fmt.Printf("[controlplane] Configuration for %s CAFile, %s, is unused without providing Endpoints for external %s\n", kubeadmconstants.Etcd, cfg.Etcd.CAFile, kubeadmconstants.Etcd) + fmt.Printf("[controlplane] WARNING: Configuration for %s CAFile, %s, is unused without providing Endpoints for external %s\n", kubeadmconstants.Etcd, cfg.Etcd.CAFile, kubeadmconstants.Etcd) } if cfg.Etcd.CertFile != "" { - fmt.Printf("[controlplane] Configuration for %s CertFile, %s, is unused without providing Endpoints for external %s\n", kubeadmconstants.Etcd, cfg.Etcd.CertFile, kubeadmconstants.Etcd) + fmt.Printf("[controlplane] WARNING: Configuration for %s CertFile, %s, is unused without providing Endpoints for external %s\n", kubeadmconstants.Etcd, cfg.Etcd.CertFile, kubeadmconstants.Etcd) } if cfg.Etcd.KeyFile != "" { - fmt.Printf("[controlplane] Configuration for %s KeyFile, %s, is unused without providing Endpoints for external %s\n", kubeadmconstants.Etcd, cfg.Etcd.KeyFile, kubeadmconstants.Etcd) + fmt.Printf("[controlplane] WARNING: Configuration for %s KeyFile, %s, is unused without providing Endpoints for external %s\n", kubeadmconstants.Etcd, cfg.Etcd.KeyFile, kubeadmconstants.Etcd) } } diff --git a/cmd/kubeadm/app/phases/etcd/local.go b/cmd/kubeadm/app/phases/etcd/local.go index d87005706e2..d25503521f9 100644 --- a/cmd/kubeadm/app/phases/etcd/local.go +++ b/cmd/kubeadm/app/phases/etcd/local.go @@ -75,8 +75,8 @@ func getEtcdCommand(cfg *kubeadmapi.MasterConfiguration) []string { "listen-client-urls": "https://127.0.0.1:2379", "advertise-client-urls": "https://127.0.0.1:2379", "data-dir": cfg.Etcd.DataDir, - "cert-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdCertName), - "key-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdKeyName), + "cert-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdServerCertName), + "key-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdServerKeyName), "trusted-ca-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.CACertName), "client-cert-auth": "true", "peer-cert-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdPeerCertName), diff --git a/cmd/kubeadm/app/phases/etcd/local_test.go b/cmd/kubeadm/app/phases/etcd/local_test.go index 920680e0599..22008bd38be 100644 --- a/cmd/kubeadm/app/phases/etcd/local_test.go +++ b/cmd/kubeadm/app/phases/etcd/local_test.go @@ -82,13 +82,13 @@ func TestGetEtcdCommand(t *testing.T) { "--listen-client-urls=https://127.0.0.1:2379", "--advertise-client-urls=https://127.0.0.1:2379", "--data-dir=/var/lib/etcd", - "--cert-file=etcd-server.crt", - "--key-file=etcd-server.key", - "--trusted-ca-file=ca.crt", + "--cert-file=" + kubeadmconstants.EtcdServerCertName, + "--key-file=" + kubeadmconstants.EtcdServerKeyName, + "--trusted-ca-file=" + kubeadmconstants.CACertName, "--client-cert-auth=true", - "--peer-cert-file=etcd-peer.crt", - "--peer-key-file=etcd-peer.key", - "--peer-trusted-ca-file=ca.crt", + "--peer-cert-file=" + kubeadmconstants.EtcdPeerCertName, + "--peer-key-file=" + kubeadmconstants.EtcdPeerKeyName, + "--peer-trusted-ca-file=" + kubeadmconstants.CACertName, "--peer-client-cert-auth=true", }, }, @@ -107,13 +107,13 @@ func TestGetEtcdCommand(t *testing.T) { "--listen-client-urls=https://10.0.1.10:2379", "--advertise-client-urls=https://10.0.1.10:2379", "--data-dir=/var/lib/etcd", - "--cert-file=etcd-server.crt", - "--key-file=etcd-server.key", - "--trusted-ca-file=ca.crt", + "--cert-file=" + kubeadmconstants.EtcdServerCertName, + "--key-file=" + kubeadmconstants.EtcdServerKeyName, + "--trusted-ca-file=" + kubeadmconstants.CACertName, "--client-cert-auth=true", - "--peer-cert-file=etcd-peer.crt", - "--peer-key-file=etcd-peer.key", - "--peer-trusted-ca-file=ca.crt", + "--peer-cert-file=" + kubeadmconstants.EtcdPeerCertName, + "--peer-key-file=" + kubeadmconstants.EtcdPeerKeyName, + "--peer-trusted-ca-file=" + kubeadmconstants.CACertName, "--peer-client-cert-auth=true", }, }, @@ -126,13 +126,13 @@ func TestGetEtcdCommand(t *testing.T) { "--listen-client-urls=https://127.0.0.1:2379", "--advertise-client-urls=https://127.0.0.1:2379", "--data-dir=/etc/foo", - "--cert-file=etcd-server.crt", - "--key-file=etcd-server.key", - "--trusted-ca-file=ca.crt", + "--cert-file=" + kubeadmconstants.EtcdServerCertName, + "--key-file=" + kubeadmconstants.EtcdServerKeyName, + "--trusted-ca-file=" + kubeadmconstants.CACertName, "--client-cert-auth=true", - "--peer-cert-file=etcd-peer.crt", - "--peer-key-file=etcd-peer.key", - "--peer-trusted-ca-file=ca.crt", + "--peer-cert-file=" + kubeadmconstants.EtcdPeerCertName, + "--peer-key-file=" + kubeadmconstants.EtcdPeerKeyName, + "--peer-trusted-ca-file=" + kubeadmconstants.CACertName, "--peer-client-cert-auth=true", }, }, diff --git a/cmd/kubeadm/app/phases/upgrade/staticpods.go b/cmd/kubeadm/app/phases/upgrade/staticpods.go index 40ab06db67e..ee1016868f9 100644 --- a/cmd/kubeadm/app/phases/upgrade/staticpods.go +++ b/cmd/kubeadm/app/phases/upgrade/staticpods.go @@ -137,7 +137,7 @@ func upgradeComponent(component string, waiter apiclient.Waiter, pathMgr StaticP // ensure etcd certs are generated for etcd and kube-apiserver if component == constants.Etcd { - if err := certsphase.CreateEtcdCertAndKeyFiles(cfg); err != nil { + if err := certsphase.CreateEtcdServerCertAndKeyFiles(cfg); err != nil { return fmt.Errorf("failed to upgrade the %s certificate: %v", constants.Etcd, err) } if err := certsphase.CreateEtcdPeerCertAndKeyFiles(cfg); err != nil { diff --git a/cmd/kubeadm/app/phases/upgrade/staticpods_test.go b/cmd/kubeadm/app/phases/upgrade/staticpods_test.go index e9001ce5b72..6bd50ca9d70 100644 --- a/cmd/kubeadm/app/phases/upgrade/staticpods_test.go +++ b/cmd/kubeadm/app/phases/upgrade/staticpods_test.go @@ -61,6 +61,8 @@ etcd: extraArgs: null image: "" keyFile: "" + serverCertSANs: null + peerCertSANs: null featureFlags: null imageRepository: k8s.gcr.io kubernetesVersion: %s @@ -322,7 +324,7 @@ func TestStaticPodControlPlane(t *testing.T) { certsphase.CreateCACertAndKeyfiles, certsphase.CreateAPIServerCertAndKeyFiles, certsphase.CreateAPIServerKubeletClientCertAndKeyFiles, - // certsphase.CreateEtcdCertAndKeyFiles, + // certsphase.CreateEtcdServerCertAndKeyFiles, // certsphase.CreateEtcdPeerCertAndKeyFiles, // certsphase.CreateAPIServerEtcdClientCertAndKeyFiles, certsphase.CreateServiceAccountKeyAndPublicKeyFiles,