1
0
mirror of https://github.com/rancher/rke.git synced 2025-04-27 11:21:08 +00:00
rke/pki/services.go

625 lines
25 KiB
Go

package pki
import (
"context"
"crypto/rsa"
"fmt"
"reflect"
"sort"
"strings"
"github.com/rancher/rke/hosts"
"github.com/rancher/rke/log"
"github.com/rancher/rke/pki/cert"
v3 "github.com/rancher/rke/types"
"github.com/sirupsen/logrus"
)
func GenerateKubeAPICertificate(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error {
// generate API 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")
}
kubernetesServiceIP, err := GetKubernetesServiceIP(rkeConfig.Services.KubeAPI.ServiceClusterIPRange)
if err != nil {
return fmt.Errorf("Failed to get Kubernetes Service IP: %v", err)
}
clusterDomain := rkeConfig.Services.Kubelet.ClusterDomain
cpHosts := hosts.NodesToHosts(rkeConfig.Nodes, controlRole)
kubeAPIAltNames := GetAltNames(cpHosts, clusterDomain, kubernetesServiceIP, rkeConfig.Authentication.SANs)
kubeAPICert := certs[KubeAPICertName].Certificate
if kubeAPICert != nil &&
reflect.DeepEqual(kubeAPIAltNames.DNSNames, kubeAPICert.DNSNames) &&
DeepEqualIPsAltNames(kubeAPIAltNames.IPs, kubeAPICert.IPAddresses) && !rotate {
return nil
}
logrus.Info("[certificates] Generating Kubernetes API server certificates")
var serviceKey *rsa.PrivateKey
if !rotate {
serviceKey = certs[KubeAPICertName].Key
}
kubeAPICrt, kubeAPIKey, err := GenerateSignedCertAndKey(caCrt, caKey, true, KubeAPICertName, kubeAPIAltNames, serviceKey, nil)
if err != nil {
return err
}
certs[KubeAPICertName] = ToCertObject(KubeAPICertName, "", "", kubeAPICrt, kubeAPIKey, nil)
// handle service account tokens in old clusters
apiCert := certs[KubeAPICertName]
if certs[ServiceAccountTokenKeyName].Key == nil {
logrus.Info("[certificates] Generating Service account token key")
certs[ServiceAccountTokenKeyName] = ToCertObject(ServiceAccountTokenKeyName, ServiceAccountTokenKeyName, "", apiCert.Certificate, apiCert.Key, nil)
}
return nil
}
func GenerateKubeAPICSR(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig) error {
// generate API csr and key
kubernetesServiceIP, err := GetKubernetesServiceIP(rkeConfig.Services.KubeAPI.ServiceClusterIPRange)
if err != nil {
return fmt.Errorf("Failed to get Kubernetes Service IP: %v", err)
}
clusterDomain := rkeConfig.Services.Kubelet.ClusterDomain
cpHosts := hosts.NodesToHosts(rkeConfig.Nodes, controlRole)
kubeAPIAltNames := GetAltNames(cpHosts, clusterDomain, kubernetesServiceIP, rkeConfig.Authentication.SANs)
kubeAPICert := certs[KubeAPICertName].Certificate
oldKubeAPICSR := certs[KubeAPICertName].CSR
if oldKubeAPICSR != nil &&
reflect.DeepEqual(kubeAPIAltNames.DNSNames, oldKubeAPICSR.DNSNames) &&
DeepEqualIPsAltNames(kubeAPIAltNames.IPs, oldKubeAPICSR.IPAddresses) {
return nil
}
logrus.Info("[certificates] Generating Kubernetes API server csr")
kubeAPICSR, kubeAPIKey, err := GenerateCertSigningRequestAndKey(true, KubeAPICertName, kubeAPIAltNames, certs[KubeAPICertName].Key, nil)
if err != nil {
return err
}
certs[KubeAPICertName] = ToCertObject(KubeAPICertName, "", "", kubeAPICert, kubeAPIKey, kubeAPICSR)
return nil
}
func GenerateKubeControllerCertificate(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error {
// generate Kube controller-manager 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")
}
if certs[KubeControllerCertName].Certificate != nil && !rotate {
return nil
}
logrus.Info("[certificates] Generating Kube Controller certificates")
var serviceKey *rsa.PrivateKey
if !rotate {
serviceKey = certs[KubeControllerCertName].Key
}
kubeControllerCrt, kubeControllerKey, err := GenerateSignedCertAndKey(caCrt, caKey, false, getDefaultCN(KubeControllerCertName), nil, serviceKey, nil)
if err != nil {
return err
}
certs[KubeControllerCertName] = ToCertObject(KubeControllerCertName, "", "", kubeControllerCrt, kubeControllerKey, nil)
return nil
}
func GenerateKubeControllerCSR(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig) error {
// generate Kube controller-manager csr and key
kubeControllerCrt := certs[KubeControllerCertName].Certificate
kubeControllerCSRPEM := certs[KubeControllerCertName].CSRPEM
if kubeControllerCSRPEM != "" {
return nil
}
logrus.Info("[certificates] Generating Kube Controller csr")
kubeControllerCSR, kubeControllerKey, err := GenerateCertSigningRequestAndKey(false, getDefaultCN(KubeControllerCertName), nil, certs[KubeControllerCertName].Key, nil)
if err != nil {
return err
}
certs[KubeControllerCertName] = ToCertObject(KubeControllerCertName, "", "", kubeControllerCrt, kubeControllerKey, kubeControllerCSR)
return nil
}
func GenerateKubeSchedulerCertificate(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error {
// generate Kube scheduler 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")
}
if certs[KubeSchedulerCertName].Certificate != nil && !rotate {
return nil
}
logrus.Info("[certificates] Generating Kube Scheduler certificates")
var serviceKey *rsa.PrivateKey
if !rotate {
serviceKey = certs[KubeSchedulerCertName].Key
}
kubeSchedulerCrt, kubeSchedulerKey, err := GenerateSignedCertAndKey(caCrt, caKey, false, getDefaultCN(KubeSchedulerCertName), nil, serviceKey, nil)
if err != nil {
return err
}
certs[KubeSchedulerCertName] = ToCertObject(KubeSchedulerCertName, "", "", kubeSchedulerCrt, kubeSchedulerKey, nil)
return nil
}
func GenerateKubeSchedulerCSR(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig) error {
// generate Kube scheduler csr and key
kubeSchedulerCrt := certs[KubeSchedulerCertName].Certificate
kubeSchedulerCSRPEM := certs[KubeSchedulerCertName].CSRPEM
if kubeSchedulerCSRPEM != "" {
return nil
}
logrus.Info("[certificates] Generating Kube Scheduler csr")
kubeSchedulerCSR, kubeSchedulerKey, err := GenerateCertSigningRequestAndKey(false, getDefaultCN(KubeSchedulerCertName), nil, certs[KubeSchedulerCertName].Key, nil)
if err != nil {
return err
}
certs[KubeSchedulerCertName] = ToCertObject(KubeSchedulerCertName, "", "", kubeSchedulerCrt, kubeSchedulerKey, kubeSchedulerCSR)
return nil
}
func GenerateKubeProxyCertificate(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error {
// generate Kube Proxy 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")
}
if certs[KubeProxyCertName].Certificate != nil && !rotate {
return nil
}
logrus.Info("[certificates] Generating Kube Proxy certificates")
var serviceKey *rsa.PrivateKey
if !rotate {
serviceKey = certs[KubeProxyCertName].Key
}
kubeProxyCrt, kubeProxyKey, err := GenerateSignedCertAndKey(caCrt, caKey, false, getDefaultCN(KubeProxyCertName), nil, serviceKey, nil)
if err != nil {
return err
}
certs[KubeProxyCertName] = ToCertObject(KubeProxyCertName, "", "", kubeProxyCrt, kubeProxyKey, nil)
return nil
}
func GenerateKubeProxyCSR(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig) error {
// generate Kube Proxy csr and key
kubeProxyCrt := certs[KubeProxyCertName].Certificate
kubeProxyCSRPEM := certs[KubeProxyCertName].CSRPEM
if kubeProxyCSRPEM != "" {
return nil
}
logrus.Info("[certificates] Generating Kube Proxy csr")
kubeProxyCSR, kubeProxyKey, err := GenerateCertSigningRequestAndKey(false, getDefaultCN(KubeProxyCertName), nil, certs[KubeProxyCertName].Key, nil)
if err != nil {
return err
}
certs[KubeProxyCertName] = ToCertObject(KubeProxyCertName, "", "", kubeProxyCrt, kubeProxyKey, kubeProxyCSR)
return nil
}
func GenerateKubeNodeCertificate(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error {
// generate kubelet certificate
caCrt := certs[CACertName].Certificate
caKey := certs[CACertName].Key
if caCrt == nil || caKey == nil {
return fmt.Errorf("CA Certificate or Key is empty")
}
if certs[KubeNodeCertName].Certificate != nil && !rotate {
return nil
}
logrus.Info("[certificates] Generating Node certificate")
var serviceKey *rsa.PrivateKey
if !rotate {
serviceKey = certs[KubeProxyCertName].Key
}
nodeCrt, nodeKey, err := GenerateSignedCertAndKey(caCrt, caKey, false, KubeNodeCommonName, nil, serviceKey, []string{KubeNodeOrganizationName})
if err != nil {
return err
}
certs[KubeNodeCertName] = ToCertObject(KubeNodeCertName, KubeNodeCommonName, KubeNodeOrganizationName, nodeCrt, nodeKey, nil)
return nil
}
func GenerateKubeNodeCSR(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig) error {
// generate kubelet csr and key
nodeCrt := certs[KubeNodeCertName].Certificate
nodeCSRPEM := certs[KubeNodeCertName].CSRPEM
if nodeCSRPEM != "" {
return nil
}
logrus.Info("[certificates] Generating Node csr and key")
nodeCSR, nodeKey, err := GenerateCertSigningRequestAndKey(false, KubeNodeCommonName, nil, certs[KubeNodeCertName].Key, []string{KubeNodeOrganizationName})
if err != nil {
return err
}
certs[KubeNodeCertName] = ToCertObject(KubeNodeCertName, KubeNodeCommonName, KubeNodeOrganizationName, nodeCrt, nodeKey, nodeCSR)
return nil
}
func GenerateKubeAdminCertificate(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error {
// generate Admin certificate and key
logrus.Info("[certificates] Generating admin certificates and kubeconfig")
caCrt := certs[CACertName].Certificate
caKey := certs[CACertName].Key
if caCrt == nil || caKey == nil {
return fmt.Errorf("CA Certificate or Key is empty")
}
cpHosts := hosts.NodesToHosts(rkeConfig.Nodes, controlRole)
if len(configPath) == 0 {
configPath = ClusterConfig
}
localKubeConfigPath := GetLocalKubeConfig(configPath, configDir)
var serviceKey *rsa.PrivateKey
if !rotate {
serviceKey = certs[KubeAdminCertName].Key
}
kubeAdminCrt, kubeAdminKey, err := GenerateSignedCertAndKey(caCrt, caKey, false, KubeAdminCertName, nil, serviceKey, []string{KubeAdminOrganizationName})
if err != nil {
return err
}
kubeAdminCertObj := ToCertObject(KubeAdminCertName, KubeAdminCertName, KubeAdminOrganizationName, kubeAdminCrt, kubeAdminKey, nil)
if len(cpHosts) > 0 {
kubeAdminConfig := GetKubeConfigX509WithData(
"https://"+cpHosts[0].Address+":6443",
rkeConfig.ClusterName,
KubeAdminCertName,
string(cert.EncodeCertPEM(caCrt)),
string(cert.EncodeCertPEM(kubeAdminCrt)),
string(cert.EncodePrivateKeyPEM(kubeAdminKey)))
kubeAdminCertObj.Config = kubeAdminConfig
kubeAdminCertObj.ConfigPath = localKubeConfigPath
} else {
kubeAdminCertObj.Config = ""
}
certs[KubeAdminCertName] = kubeAdminCertObj
return nil
}
func GenerateKubeAdminCSR(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig) error {
// generate Admin certificate and key
kubeAdminCrt := certs[KubeAdminCertName].Certificate
kubeAdminCSRPEM := certs[KubeAdminCertName].CSRPEM
if kubeAdminCSRPEM != "" {
return nil
}
kubeAdminCSR, kubeAdminKey, err := GenerateCertSigningRequestAndKey(false, KubeAdminCertName, nil, certs[KubeAdminCertName].Key, []string{KubeAdminOrganizationName})
if err != nil {
return err
}
logrus.Info("[certificates] Generating admin csr and kubeconfig")
kubeAdminCertObj := ToCertObject(KubeAdminCertName, KubeAdminCertName, KubeAdminOrganizationName, kubeAdminCrt, kubeAdminKey, kubeAdminCSR)
certs[KubeAdminCertName] = kubeAdminCertObj
return nil
}
func GenerateAPIProxyClientCertificate(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error {
//generate API server proxy client key and certs
caCrt := certs[RequestHeaderCACertName].Certificate
caKey := certs[RequestHeaderCACertName].Key
if caCrt == nil || caKey == nil {
return fmt.Errorf("Request Header CA Certificate or Key is empty")
}
if certs[APIProxyClientCertName].Certificate != nil && !rotate {
return nil
}
logrus.Info("[certificates] Generating Kubernetes API server proxy client certificates")
var serviceKey *rsa.PrivateKey
if !rotate {
serviceKey = certs[APIProxyClientCertName].Key
}
apiserverProxyClientCrt, apiserverProxyClientKey, err := GenerateSignedCertAndKey(caCrt, caKey, true, APIProxyClientCertName, nil, serviceKey, nil)
if err != nil {
return err
}
certs[APIProxyClientCertName] = ToCertObject(APIProxyClientCertName, "", "", apiserverProxyClientCrt, apiserverProxyClientKey, nil)
return nil
}
func GenerateAPIProxyClientCSR(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig) error {
//generate API server proxy client key and certs
apiserverProxyClientCrt := certs[APIProxyClientCertName].Certificate
apiserverProxyClientCSRPEM := certs[APIProxyClientCertName].CSRPEM
if apiserverProxyClientCSRPEM != "" {
return nil
}
logrus.Info("[certificates] Generating Kubernetes API server proxy client csr")
apiserverProxyClientCSR, apiserverProxyClientKey, err := GenerateCertSigningRequestAndKey(true, APIProxyClientCertName, nil, certs[APIProxyClientCertName].Key, nil)
if err != nil {
return err
}
certs[APIProxyClientCertName] = ToCertObject(APIProxyClientCertName, "", "", apiserverProxyClientCrt, apiserverProxyClientKey, apiserverProxyClientCSR)
return nil
}
func GenerateExternalEtcdCertificates(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error {
clientCert, err := cert.ParseCertsPEM([]byte(rkeConfig.Services.Etcd.Cert))
if err != nil {
return err
}
clientKey, err := cert.ParsePrivateKeyPEM([]byte(rkeConfig.Services.Etcd.Key))
if err != nil {
return err
}
certs[EtcdClientCertName] = ToCertObject(EtcdClientCertName, "", "", clientCert[0], clientKey.(*rsa.PrivateKey), nil)
caCert, err := cert.ParseCertsPEM([]byte(rkeConfig.Services.Etcd.CACert))
if err != nil {
return err
}
certs[EtcdClientCACertName] = ToCertObject(EtcdClientCACertName, "", "", caCert[0], nil, nil)
return nil
}
func GenerateEtcdCertificates(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error {
caCrt := certs[CACertName].Certificate
caKey := certs[CACertName].Key
if caCrt == nil || caKey == nil {
return fmt.Errorf("CA Certificate or Key is empty")
}
kubernetesServiceIP, err := GetKubernetesServiceIP(rkeConfig.Services.KubeAPI.ServiceClusterIPRange)
if err != nil {
return fmt.Errorf("Failed to get Kubernetes Service IP: %v", err)
}
clusterDomain := rkeConfig.Services.Kubelet.ClusterDomain
etcdHosts := hosts.NodesToHosts(rkeConfig.Nodes, etcdRole)
etcdAltNames := GetAltNames(etcdHosts, clusterDomain, kubernetesServiceIP, []string{})
var (
dnsNames = make([]string, len(etcdAltNames.DNSNames))
ips = []string{}
)
copy(dnsNames, etcdAltNames.DNSNames)
sort.Strings(dnsNames)
for _, ip := range etcdAltNames.IPs {
ips = append(ips, ip.String())
}
sort.Strings(ips)
for _, host := range etcdHosts {
etcdName := GetCrtNameForHost(host, 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) {
var (
certDNSNames = make([]string, len(cert.DNSNames))
certIPs = []string{}
)
copy(certDNSNames, cert.DNSNames)
sort.Strings(certDNSNames)
for _, ip := range cert.IPAddresses {
certIPs = append(certIPs, ip.String())
}
sort.Strings(certIPs)
if reflect.DeepEqual(dnsNames, certDNSNames) && reflect.DeepEqual(ips, certIPs) {
continue
}
}
}
var serviceKey *rsa.PrivateKey
if !rotate {
serviceKey = certs[etcdName].Key
}
logrus.Infof("[certificates] Generating %s certificate and key", etcdName)
etcdCrt, etcdKey, err := GenerateSignedCertAndKey(caCrt, caKey, true, EtcdCertName, etcdAltNames, serviceKey, nil)
if err != nil {
return err
}
certs[etcdName] = ToCertObject(etcdName, "", "", etcdCrt, etcdKey, nil)
}
deleteUnusedCerts(ctx, certs, EtcdCertName, etcdHosts)
return nil
}
func GenerateEtcdCSRs(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig) error {
kubernetesServiceIP, err := GetKubernetesServiceIP(rkeConfig.Services.KubeAPI.ServiceClusterIPRange)
if err != nil {
return fmt.Errorf("Failed to get Kubernetes Service IP: %v", err)
}
clusterDomain := rkeConfig.Services.Kubelet.ClusterDomain
etcdHosts := hosts.NodesToHosts(rkeConfig.Nodes, etcdRole)
etcdAltNames := GetAltNames(etcdHosts, clusterDomain, kubernetesServiceIP, []string{})
for _, host := range etcdHosts {
etcdName := GetCrtNameForHost(host, EtcdCertName)
etcdCrt := certs[etcdName].Certificate
etcdCsr := certs[etcdName].CSR
if etcdCsr != nil {
if reflect.DeepEqual(etcdAltNames.DNSNames, etcdCsr.DNSNames) &&
DeepEqualIPsAltNames(etcdAltNames.IPs, etcdCsr.IPAddresses) {
continue
}
}
logrus.Infof("[certificates] Generating etcd-%s csr and key", host.InternalAddress)
etcdCSR, etcdKey, err := GenerateCertSigningRequestAndKey(true, EtcdCertName, etcdAltNames, certs[etcdName].Key, nil)
if err != nil {
return err
}
certs[etcdName] = ToCertObject(etcdName, "", "", etcdCrt, etcdKey, etcdCSR)
}
return nil
}
func GenerateServiceTokenKey(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig, configPath, configDir string, rotate bool) error {
// generate service account token key
privateAPIKey := certs[ServiceAccountTokenKeyName].Key
caCrt := certs[CACertName].Certificate
caKey := certs[CACertName].Key
if caCrt == nil || caKey == nil {
return fmt.Errorf("CA Certificate or Key is empty")
}
if certs[ServiceAccountTokenKeyName].Certificate != nil {
return nil
}
// handle rotation on old clusters
if certs[ServiceAccountTokenKeyName].Key == nil {
privateAPIKey = certs[KubeAPICertName].Key
}
tokenCrt, tokenKey, err := GenerateSignedCertAndKey(caCrt, caKey, false, ServiceAccountTokenKeyName, nil, privateAPIKey, nil)
if err != nil {
return fmt.Errorf("Failed to generate private key for service account token: %v", err)
}
certs[ServiceAccountTokenKeyName] = ToCertObject(ServiceAccountTokenKeyName, ServiceAccountTokenKeyName, "", tokenCrt, tokenKey, nil)
return nil
}
func GenerateRKECACerts(ctx context.Context, certs map[string]CertificatePKI, configPath, configDir string) error {
if err := GenerateRKEMasterCACert(ctx, certs, configPath, configDir); err != nil {
return err
}
return GenerateRKERequestHeaderCACert(ctx, certs, configPath, configDir)
}
func GenerateRKEMasterCACert(ctx context.Context, certs map[string]CertificatePKI, configPath, configDir string) error {
// generate kubernetes CA certificate and key
logrus.Info("[certificates] Generating CA kubernetes certificates")
caCrt, caKey, err := GenerateCACertAndKey(CACertName, nil)
if err != nil {
return err
}
certs[CACertName] = ToCertObject(CACertName, "", "", caCrt, caKey, nil)
return nil
}
func GenerateRKERequestHeaderCACert(ctx context.Context, certs map[string]CertificatePKI, configPath, configDir string) error {
// generate request header client CA certificate and key
logrus.Info("[certificates] Generating Kubernetes API server aggregation layer requestheader client CA certificates")
requestHeaderCACrt, requestHeaderCAKey, err := GenerateCACertAndKey(RequestHeaderCACertName, nil)
if err != nil {
return err
}
certs[RequestHeaderCACertName] = ToCertObject(RequestHeaderCACertName, "", "", requestHeaderCACrt, requestHeaderCAKey, nil)
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.Debugf(ctx, "[certificates] Generating Kubernetes Kubelet certificates")
allHosts := hosts.NodesToHosts(rkeConfig.Nodes, "")
for _, host := range allHosts {
kubeletName := GetCrtNameForHost(host, KubeletCertName)
kubeletCert := certs[kubeletName].Certificate
if kubeletCert != nil && !rotate {
continue
}
kubeletAltNames := GetIPHostAltnamesForHost(host)
if kubeletCert != nil &&
reflect.DeepEqual(kubeletAltNames.DNSNames, kubeletCert.DNSNames) &&
DeepEqualIPsAltNames(kubeletAltNames.IPs, kubeletCert.IPAddresses) && !rotate {
continue
}
var serviceKey *rsa.PrivateKey
if !rotate {
serviceKey = certs[kubeletName].Key
}
log.Debugf(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)
}
deleteUnusedCerts(ctx, certs, KubeletCertName, allHosts)
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 := GetCrtNameForHost(host, 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) {
continue
}
logrus.Infof("[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,
GenerateServiceTokenKey,
GenerateKubeControllerCertificate,
GenerateKubeSchedulerCertificate,
GenerateKubeProxyCertificate,
GenerateKubeNodeCertificate,
GenerateKubeAdminCertificate,
GenerateAPIProxyClientCertificate,
GenerateEtcdCertificates,
}
if IsKubeletGenerateServingCertificateEnabledinConfig(&rkeConfig) {
RKECerts = append(RKECerts, GenerateKubeletCertificate)
} else {
//Clean up kubelet certs when GenerateServingCertificate is disabled
logrus.Info("[certificates] GenerateServingCertificate is disabled, checking if there are unused kubelet certificates")
for k := range certs {
if strings.HasPrefix(k, KubeletCertName) {
logrus.Infof("[certificates] Deleting unused kubelet certificate: %s", k)
delete(certs, k)
}
}
}
for _, gen := range RKECerts {
if err := gen(ctx, certs, rkeConfig, configPath, configDir, rotate); err != nil {
return err
}
}
if len(rkeConfig.Services.Etcd.ExternalURLs) > 0 {
return GenerateExternalEtcdCertificates(ctx, certs, rkeConfig, configPath, configDir, false)
}
return nil
}
func GenerateRKEServicesCSRs(ctx context.Context, certs map[string]CertificatePKI, rkeConfig v3.RancherKubernetesEngineConfig) error {
RKECerts := []CSRFunc{
GenerateKubeAPICSR,
GenerateKubeControllerCSR,
GenerateKubeSchedulerCSR,
GenerateKubeProxyCSR,
GenerateKubeNodeCSR,
GenerateKubeAdminCSR,
GenerateAPIProxyClientCSR,
GenerateEtcdCSRs,
}
if IsKubeletGenerateServingCertificateEnabledinConfig(&rkeConfig) {
RKECerts = append(RKECerts, GenerateKubeletCSR)
}
for _, csr := range RKECerts {
if err := csr(ctx, certs, rkeConfig); err != nil {
return err
}
}
return nil
}
func deleteUnusedCerts(ctx context.Context, certs map[string]CertificatePKI, certName string, hostList []*hosts.Host) {
hostAddresses := hosts.GetInternalAddressForHosts(hostList)
logrus.Tracef("Checking and deleting unused certificates with prefix [%s] for the following [%d] node(s): %s", certName, len(hostAddresses), strings.Join(hostAddresses, ","))
unusedCerts := make(map[string]bool)
for k := range certs {
if strings.HasPrefix(k, certName) {
unusedCerts[k] = true
}
}
for _, host := range hostList {
Name := GetCrtNameForHost(host, certName)
delete(unusedCerts, Name)
}
for k := range unusedCerts {
logrus.Infof("[certificates] Deleting unused certificate: %s", k)
delete(certs, k)
}
}