Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kubeadm 710 Switch to a dedicated CA for kubeadm etcd identities #60385

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 23 additions & 11 deletions cmd/kubeadm/app/cmd/phases/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ var (

allCertsExample = normalizer.Examples(`
# Creates all PKI assets necessary to establish the control plane,
# functionally equivalent to what generated by kubeadm init.
# functionally equivalent to what generated by kubeadm init.
kubeadm alpha phase certs all

# Creates all PKI assets using options read from a configuration file.
kubeadm alpha phase certs all --config masterconfiguration.yaml
`)

caCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
Generates the self-signed certificate authority and related key, and saves them into %s and %s files.
Generates the self-signed kubernetes certificate authority and related key, and saves them into %s and %s files.

If both files already exist, kubeadm skips the generation step and existing files will be used.
`+cmdutil.AlphaDisclaimer), kubeadmconstants.CACertName, kubeadmconstants.CAKeyName)
Expand All @@ -74,6 +74,12 @@ var (
If both files already exist, kubeadm skips the generation step and existing files will be used.
`+cmdutil.AlphaDisclaimer), kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName)

etcdCaCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
Generates the self-signed etcd certificate authority and related key and saves them into %s and %s files.

If both files already exist, kubeadm skips the generation step and existing files will be used.
`+cmdutil.AlphaDisclaimer), kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdCAKeyName)

etcdServerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
Generates the etcd serving certificate and key and saves them into %s and %s files.

Expand Down Expand Up @@ -166,37 +172,43 @@ func getCertsSubCommands(defaultKubernetesVersion string) []*cobra.Command {
},
{
use: "ca",
short: "Generates self-signed CA to provision identities for each component in the cluster",
short: "Generates a self-signed kubernetes CA to provision identities for components of the cluster",
long: caCertLongDesc,
cmdFunc: certsphase.CreateCACertAndKeyfiles,
cmdFunc: certsphase.CreateCACertAndKeyFiles,
},
{
use: "apiserver",
short: "Generates API server serving certificate and key",
short: "Generates an API server serving certificate and key",
long: apiServerCertLongDesc,
cmdFunc: certsphase.CreateAPIServerCertAndKeyFiles,
},
{
use: "apiserver-kubelet-client",
short: "Generates client certificate for the API server to connect to the kubelets securely",
short: "Generates a client certificate for the API server to connect to the kubelets securely",
long: apiServerKubeletCertLongDesc,
cmdFunc: certsphase.CreateAPIServerKubeletClientCertAndKeyFiles,
},
{
use: "etcd-ca",
short: "Generates a self-signed CA to provision identities for etcd",
long: etcdCaCertLongDesc,
cmdFunc: certsphase.CreateEtcdCACertAndKeyFiles,
},
{
use: "etcd-server",
short: "Generates etcd serving certificate and key",
short: "Generates an etcd serving certificate and key",
long: etcdServerCertLongDesc,
cmdFunc: certsphase.CreateEtcdServerCertAndKeyFiles,
},
{
use: "etcd-peer",
short: "Generates etcd peer certificate and key",
short: "Generates an etcd peer certificate and key",
long: etcdPeerCertLongDesc,
cmdFunc: certsphase.CreateEtcdPeerCertAndKeyFiles,
},
{
use: "apiserver-etcd-client",
short: "Generates client certificate for the API server to connect to etcd securely",
short: "Generates a client certificate for the API server to connect to etcd securely",
long: apiServerEtcdServerCertLongDesc,
cmdFunc: certsphase.CreateAPIServerEtcdClientCertAndKeyFiles,
},
Expand All @@ -208,13 +220,13 @@ func getCertsSubCommands(defaultKubernetesVersion string) []*cobra.Command {
},
{
use: "front-proxy-ca",
short: "Generates front proxy CA certificate and key for a Kubernetes cluster",
short: "Generates a front proxy CA certificate and key for a Kubernetes cluster",
long: frontProxyCaCertLongDesc,
cmdFunc: certsphase.CreateFrontProxyCACertAndKeyFiles,
},
{
use: "front-proxy-client",
short: "Generates front proxy CA client certificate and key for a Kubernetes cluster",
short: "Generates a front proxy CA client certificate and key for a Kubernetes cluster",
long: frontProxyClientCertLongDesc,
cmdFunc: certsphase.CreateFrontProxyClientCertAndKeyFiles,
},
Expand Down
7 changes: 7 additions & 0 deletions cmd/kubeadm/app/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ const (
// APIServerKubeletClientCertCommonName defines kubelet client certificate common name (CN)
APIServerKubeletClientCertCommonName = "kube-apiserver-kubelet-client"

// EtcdCACertAndKeyBaseName defines etcd's CA certificate and key base name
EtcdCACertAndKeyBaseName = "etcd/ca"
// EtcdCACertName defines etcd's CA certificate name
EtcdCACertName = "etcd/ca.crt"
// EtcdCAKeyName defines etcd's CA key name
EtcdCAKeyName = "etcd/ca.key"

// EtcdServerCertAndKeyBaseName defines etcd's server certificate and key base name
EtcdServerCertAndKeyBaseName = "etcd/server"
// EtcdServerCertName defines etcd's server certificate name
Expand Down
81 changes: 56 additions & 25 deletions cmd/kubeadm/app/phases/certs/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ import (
func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration) error {

certActions := []func(cfg *kubeadmapi.MasterConfiguration) error{
CreateCACertAndKeyfiles,
CreateCACertAndKeyFiles,
CreateAPIServerCertAndKeyFiles,
CreateAPIServerKubeletClientCertAndKeyFiles,
CreateEtcdCACertAndKeyFiles,
CreateEtcdServerCertAndKeyFiles,
CreateEtcdPeerCertAndKeyFiles,
CreateAPIServerEtcdClientCertAndKeyFiles,
Expand All @@ -57,9 +58,9 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration) error {
return nil
}

// CreateCACertAndKeyfiles create a new self signed CA certificate and key files.
// CreateCACertAndKeyFiles create a new self signed cluster CA certificate and key files.
// If the CA certificate and key files already exists in the target folder, they are used only if evaluated equal; otherwise an error is returned.
func CreateCACertAndKeyfiles(cfg *kubeadmapi.MasterConfiguration) error {
func CreateCACertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error {

caCert, caKey, err := NewCACertAndKey()
if err != nil {
Expand All @@ -76,7 +77,7 @@ func CreateCACertAndKeyfiles(cfg *kubeadmapi.MasterConfiguration) error {

// CreateAPIServerCertAndKeyFiles create a new certificate and key files for the apiserver.
// If the apiserver certificate and key files already exists in the target folder, they are used only if evaluated equal; otherwise an error is returned.
// It assumes the cluster CA certificate and key files should exists into the CertificatesDir
// It assumes the cluster CA certificate and key files exist in the CertificatesDir.
func CreateAPIServerCertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error {

caCert, caKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
Expand All @@ -98,9 +99,9 @@ func CreateAPIServerCertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error {
)
}

// CreateAPIServerKubeletClientCertAndKeyFiles create a new CA certificate for kubelets calling apiserver
// CreateAPIServerKubeletClientCertAndKeyFiles create a new certificate for kubelets calling apiserver.
// If the apiserver-kubelet-client certificate and key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
// It assumes the cluster CA certificate and key files should exists into the CertificatesDir
// It assumes the cluster CA certificate and key files exist in the CertificatesDir.
func CreateAPIServerKubeletClientCertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error {

caCert, caKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
Expand All @@ -122,73 +123,92 @@ func CreateAPIServerKubeletClientCertAndKeyFiles(cfg *kubeadmapi.MasterConfigura
)
}

// CreateEtcdCACertAndKeyFiles create a self signed etcd CA certificate and key files.
// The etcd CA and client certs are used to secure communication between etcd peers and connections to etcd from the API server.
// This is a separate CA, so that kubernetes client identities cannot connect to etcd directly or peer with the etcd cluster.
// If the etcd CA certificate and key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
func CreateEtcdCACertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error {

etcdCACert, etcdCAKey, err := NewEtcdCACertAndKey()
if err != nil {
return err
}

return writeCertificateAuthorithyFilesIfNotExist(
cfg.CertificatesDir,
kubeadmconstants.EtcdCACertAndKeyBaseName,
etcdCACert,
etcdCAKey,
)
}

// 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
// It assumes the etcd CA certificate and key file exist in the CertificatesDir
func CreateEtcdServerCertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error {

caCert, caKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
etcdCACert, etcdCAKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.EtcdCACertAndKeyBaseName)
if err != nil {
return err
}

etcdServerCert, etcdServerKey, err := NewEtcdServerCertAndKey(cfg, caCert, caKey)
etcdServerCert, etcdServerKey, err := NewEtcdServerCertAndKey(cfg, etcdCACert, etcdCAKey)
if err != nil {
return err
}

return writeCertificateFilesIfNotExist(
cfg.CertificatesDir,
kubeadmconstants.EtcdServerCertAndKeyBaseName,
caCert,
etcdCACert,
etcdServerCert,
etcdServerKey,
)
}

// CreateEtcdPeerCertAndKeyFiles create a new certificate and key file for etcd peering.
// If the etcd peer 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
// It assumes the etcd CA certificate and key file exist in the CertificatesDir
func CreateEtcdPeerCertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error {

caCert, caKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
etcdCACert, etcdCAKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.EtcdCACertAndKeyBaseName)
if err != nil {
return err
}

etcdPeerCert, etcdPeerKey, err := NewEtcdPeerCertAndKey(cfg, caCert, caKey)
etcdPeerCert, etcdPeerKey, err := NewEtcdPeerCertAndKey(cfg, etcdCACert, etcdCAKey)
if err != nil {
return err
}

return writeCertificateFilesIfNotExist(
cfg.CertificatesDir,
kubeadmconstants.EtcdPeerCertAndKeyBaseName,
caCert,
etcdCACert,
etcdPeerCert,
etcdPeerKey,
)
}

// CreateAPIServerEtcdClientCertAndKeyFiles create a new client certificate for the apiserver calling etcd
// If the apiserver-etcd-client 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
// It assumes the etcd CA certificate and key file exist in the CertificatesDir
func CreateAPIServerEtcdClientCertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error {

caCert, caKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
etcdCACert, etcdCAKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.EtcdCACertAndKeyBaseName)
if err != nil {
return err
}

apiEtcdClientCert, apiEtcdClientKey, err := NewAPIServerEtcdClientCertAndKey(caCert, caKey)
apiEtcdClientCert, apiEtcdClientKey, err := NewAPIServerEtcdClientCertAndKey(etcdCACert, etcdCAKey)
if err != nil {
return err
}

return writeCertificateFilesIfNotExist(
cfg.CertificatesDir,
kubeadmconstants.APIServerEtcdClientCertAndKeyBaseName,
caCert,
etcdCACert,
apiEtcdClientCert,
apiEtcdClientKey,
)
Expand Down Expand Up @@ -232,7 +252,7 @@ func CreateFrontProxyCACertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) erro

// CreateFrontProxyClientCertAndKeyFiles create a new certificate for proxy server client.
// If the front-proxy-client certificate and key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
// It assumes the front proxy CAA certificate and key files should exists into the CertificatesDir
// It assumes the front proxy CA certificate and key files exist in the CertificatesDir.
func CreateFrontProxyClientCertAndKeyFiles(cfg *kubeadmapi.MasterConfiguration) error {

frontProxyCACert, frontProxyCAKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.FrontProxyCACertAndKeyBaseName)
Expand Down Expand Up @@ -265,7 +285,7 @@ func NewCACertAndKey() (*x509.Certificate, *rsa.PrivateKey, error) {
return caCert, caKey, nil
}

// NewAPIServerCertAndKey generate CA certificate for apiserver, signed by the given CA.
// NewAPIServerCertAndKey generate 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 := pkiutil.GetAPIServerAltNames(cfg)
Expand All @@ -286,7 +306,7 @@ func NewAPIServerCertAndKey(cfg *kubeadmapi.MasterConfiguration, caCert *x509.Ce
return apiCert, apiKey, nil
}

// NewAPIServerKubeletClientCertAndKey generate CA certificate for the apiservers to connect to the kubelets securely, signed by the given CA.
// NewAPIServerKubeletClientCertAndKey generate certificate for the apiservers to connect to the kubelets securely, signed by the given CA.
func NewAPIServerKubeletClientCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {

config := certutil.Config{
Expand All @@ -302,7 +322,18 @@ func NewAPIServerKubeletClientCertAndKey(caCert *x509.Certificate, caKey *rsa.Pr
return apiClientCert, apiClientKey, nil
}

// NewEtcdServerCertAndKey generate CA certificate for etcd, signed by the given CA.
// NewEtcdCACertAndKey generate a self signed etcd CA.
func NewEtcdCACertAndKey() (*x509.Certificate, *rsa.PrivateKey, error) {

etcdCACert, etcdCAKey, err := pkiutil.NewCertificateAuthority()
if err != nil {
return nil, nil, fmt.Errorf("failure while generating etcd CA certificate and key: %v", err)
}

return etcdCACert, etcdCAKey, nil
}

// NewEtcdServerCertAndKey generate 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 := pkiutil.GetEtcdAltNames(cfg)
Expand All @@ -323,7 +354,7 @@ func NewEtcdServerCertAndKey(cfg *kubeadmapi.MasterConfiguration, caCert *x509.C
return etcdServerCert, etcdServerKey, nil
}

// NewEtcdPeerCertAndKey generate CA certificate for etcd peering, signed by the given CA.
// NewEtcdPeerCertAndKey generate 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 := pkiutil.GetEtcdPeerAltNames(cfg)
Expand All @@ -344,7 +375,7 @@ func NewEtcdPeerCertAndKey(cfg *kubeadmapi.MasterConfiguration, caCert *x509.Cer
return etcdPeerCert, etcdPeerKey, nil
}

// NewAPIServerEtcdClientCertAndKey generate CA certificate for the apiservers to connect to etcd securely, signed by the given CA.
// NewAPIServerEtcdClientCertAndKey generate certificate for the apiservers to connect to etcd securely, signed by the given CA.
func NewAPIServerEtcdClientCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {

config := certutil.Config{
Expand Down Expand Up @@ -383,7 +414,7 @@ func NewFrontProxyCACertAndKey() (*x509.Certificate, *rsa.PrivateKey, error) {
return frontProxyCACert, frontProxyCAKey, nil
}

// NewFrontProxyClientCertAndKey generate CA certificate for proxy server client, signed by the given front proxy CA.
// NewFrontProxyClientCertAndKey generate certificate for proxy server client, signed by the given front proxy CA.
func NewFrontProxyClientCertAndKey(frontProxyCACert *x509.Certificate, frontProxyCAKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {

config := certutil.Config{
Expand Down
Loading