diff --git a/cmd/cloud-controller-manager/app/options/options.go b/cmd/cloud-controller-manager/app/options/options.go index 5b184105bde..e15a659f012 100644 --- a/cmd/cloud-controller-manager/app/options/options.go +++ b/cmd/cloud-controller-manager/app/options/options.go @@ -44,6 +44,7 @@ import ( "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/master/ports" + // add the kubernetes feature gates _ "k8s.io/kubernetes/pkg/features" ) @@ -102,7 +103,8 @@ func NewCloudControllerManagerOptions() (*CloudControllerManagerOptions, error) s.Authorization.RemoteKubeConfigFileOptional = true s.Authorization.AlwaysAllowPaths = []string{"/healthz"} - s.SecureServing.ServerCert.CertDirectory = "/var/run/kubernetes" + // Set the PairName but leave certificate directory blank to generate in-memory by default + s.SecureServing.ServerCert.CertDirectory = "" s.SecureServing.ServerCert.PairName = "cloud-controller-manager" s.SecureServing.BindPort = ports.CloudControllerManagerPort diff --git a/cmd/cloud-controller-manager/app/options/options_test.go b/cmd/cloud-controller-manager/app/options/options_test.go index 72bcb068a9c..b9825bb2354 100644 --- a/cmd/cloud-controller-manager/app/options/options_test.go +++ b/cmd/cloud-controller-manager/app/options/options_test.go @@ -78,7 +78,7 @@ func TestDefaultFlags(t *testing.T) { BindPort: 10258, BindAddress: net.ParseIP("0.0.0.0"), ServerCert: apiserveroptions.GeneratableKeyCert{ - CertDirectory: "/var/run/kubernetes", + CertDirectory: "", PairName: "cloud-controller-manager", }, HTTP2MaxStreamsPerConnection: 0, diff --git a/cmd/kube-controller-manager/app/options/options.go b/cmd/kube-controller-manager/app/options/options.go index 22cf24a12e3..c2c8d3be183 100644 --- a/cmd/kube-controller-manager/app/options/options.go +++ b/cmd/kube-controller-manager/app/options/options.go @@ -190,7 +190,8 @@ func NewKubeControllerManagerOptions() (*KubeControllerManagerOptions, error) { s.Authorization.RemoteKubeConfigFileOptional = true s.Authorization.AlwaysAllowPaths = []string{"/healthz"} - s.SecureServing.ServerCert.CertDirectory = "/var/run/kubernetes" + // Set the PairName but leave certificate directory blank to generate in-memory by default + s.SecureServing.ServerCert.CertDirectory = "" s.SecureServing.ServerCert.PairName = "kube-controller-manager" s.SecureServing.BindPort = ports.KubeControllerManagerPort diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/serving.go b/staging/src/k8s.io/apiserver/pkg/server/options/serving.go index 3ecc7e02094..998c7ce358a 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/serving.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/serving.go @@ -75,19 +75,25 @@ type CertKey struct { } type GeneratableKeyCert struct { + // CertKey allows setting an explicit cert/key file to use. CertKey CertKey - // CertDirectory is a directory that will contain the certificates. If the cert and key aren't specifically set - // this will be used to derive a match with the "pair-name" + // CertDirectory specifies a directory to write generated certificates to if CertFile/KeyFile aren't explicitly set. + // PairName is used to determine the filenames within CertDirectory. + // If CertDirectory and PairName are not set, an in-memory certificate will be generated. CertDirectory string + // PairName is the name which will be used with CertDirectory to make a cert and key filenames. + // It becomes CertDirectory/PairName.crt and CertDirectory/PairName.key + PairName string + + // GeneratedCert holds an in-memory generated certificate if CertFile/KeyFile aren't explicitly set, and CertDirectory/PairName are not set. + GeneratedCert *tls.Certificate + // FixtureDirectory is a directory that contains test fixture used to avoid regeneration of certs during tests. // The format is: // _-_-.crt // _-_-.key FixtureDirectory string - // PairName is the name which will be used with CertDirectory to make a cert and key names - // It becomes CertDirector/PairName.crt and CertDirector/PairName.key - PairName string } func NewSecureServingOptions() *SecureServingOptions { @@ -121,6 +127,10 @@ func (s *SecureServingOptions) Validate() []error { errors = append(errors, fmt.Errorf("--secure-port %v must be between 0 and 65535, inclusive. 0 for turning off secure port", s.BindPort)) } + if (len(s.ServerCert.CertKey.CertFile) != 0 || len(s.ServerCert.CertKey.KeyFile) != 0) && s.ServerCert.GeneratedCert != nil { + errors = append(errors, fmt.Errorf("cert/key file and in-memory certificate cannot both be set")) + } + return errors } @@ -219,6 +229,8 @@ func (s *SecureServingOptions) ApplyTo(config **server.SecureServingInfo) error return fmt.Errorf("unable to load server certificate: %v", err) } c.Cert = &tlsCert + } else if s.ServerCert.GeneratedCert != nil { + c.Cert = s.ServerCert.GeneratedCert } if len(s.CipherSuites) != 0 { @@ -264,13 +276,20 @@ func (s *SecureServingOptions) MaybeDefaultWithSelfSignedCerts(publicAddress str return nil } - keyCert.CertFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".crt") - keyCert.KeyFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".key") - - canReadCertAndKey, err := certutil.CanReadCertAndKey(keyCert.CertFile, keyCert.KeyFile) - if err != nil { - return err + canReadCertAndKey := false + if len(s.ServerCert.CertDirectory) > 0 { + if len(s.ServerCert.PairName) == 0 { + return fmt.Errorf("PairName is required if CertDirectory is set") + } + keyCert.CertFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".crt") + keyCert.KeyFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".key") + if canRead, err := certutil.CanReadCertAndKey(keyCert.CertFile, keyCert.KeyFile); err != nil { + return err + } else { + canReadCertAndKey = canRead + } } + if !canReadCertAndKey { // add either the bind address or localhost to the valid alternates bindIP := s.BindAddress.String() @@ -282,15 +301,21 @@ func (s *SecureServingOptions) MaybeDefaultWithSelfSignedCerts(publicAddress str if cert, key, err := certutil.GenerateSelfSignedCertKeyWithFixtures(publicAddress, alternateIPs, alternateDNS, s.ServerCert.FixtureDirectory); err != nil { return fmt.Errorf("unable to generate self signed cert: %v", err) - } else { + } else if len(keyCert.CertFile) > 0 && len(keyCert.KeyFile) > 0 { if err := certutil.WriteCert(keyCert.CertFile, cert); err != nil { return err } - if err := certutil.WriteKey(keyCert.KeyFile, key); err != nil { return err } glog.Infof("Generated self-signed cert (%s, %s)", keyCert.CertFile, keyCert.KeyFile) + } else { + tlsCert, err := tls.X509KeyPair(cert, key) + if err != nil { + return fmt.Errorf("unable to generate self signed cert: %v", err) + } + s.ServerCert.GeneratedCert = &tlsCert + glog.Infof("Generated self-signed cert in-memory") } }