mirror of
https://github.com/rancher/rke.git
synced 2025-09-17 23:49:06 +00:00
Add Rotate certificates command to rke
This commit is contained in:
committed by
Alena Prokharchyk
parent
7582083e7a
commit
3551e6e4b6
@@ -28,6 +28,9 @@ const (
|
||||
IngressAddonJobName = "rke-ingress-controller-deploy-job"
|
||||
IngressAddonDeleteJobName = "rke-ingress-controller-delete-job"
|
||||
MetricsServerAddonResourceName = "rke-metrics-addon"
|
||||
NginxIngressAddonAppName = "ingress-nginx"
|
||||
KubeDNSAddonAppName = "kube-dns"
|
||||
KubeDNSAutoscalerAppName = "kube-dns-autoscaler"
|
||||
)
|
||||
|
||||
type ingressOptions struct {
|
||||
|
@@ -71,7 +71,7 @@ func SetUpAuthentication(ctx context.Context, kubeCluster, currentCluster *Clust
|
||||
if err := rebuildLocalAdminConfig(ctx, kubeCluster); err != nil {
|
||||
return err
|
||||
}
|
||||
kubeCluster.Certificates, err = regenerateAPICertificate(kubeCluster, kubeCluster.Certificates)
|
||||
err = pki.GenerateKubeAPICertificate(ctx, kubeCluster.Certificates, kubeCluster.RancherKubernetesEngineConfig, "", "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to regenerate KubeAPI certificate %v", err)
|
||||
}
|
||||
@@ -129,6 +129,7 @@ func getClusterCerts(ctx context.Context, kubeClient *kubernetes.Clientset, etcd
|
||||
pki.KubeAdminCertName,
|
||||
pki.APIProxyClientCertName,
|
||||
pki.RequestHeaderCACertName,
|
||||
pki.ServiceAccountTokenKeyName,
|
||||
}
|
||||
|
||||
for _, etcdHost := range etcdHosts {
|
||||
@@ -141,14 +142,16 @@ func getClusterCerts(ctx context.Context, kubeClient *kubernetes.Clientset, etcd
|
||||
secret, err := k8s.GetSecret(kubeClient, certName)
|
||||
if err != nil && !strings.HasPrefix(certName, "kube-etcd") &&
|
||||
!strings.Contains(certName, pki.RequestHeaderCACertName) &&
|
||||
!strings.Contains(certName, pki.APIProxyClientCertName) {
|
||||
!strings.Contains(certName, pki.APIProxyClientCertName) &&
|
||||
!strings.Contains(certName, pki.ServiceAccountTokenKeyName) {
|
||||
return nil, err
|
||||
}
|
||||
// If I can't find an etcd, requestheader, or proxy client cert, I will not fail and will create it later.
|
||||
if (secret == nil || secret.Data == nil) &&
|
||||
(strings.HasPrefix(certName, "kube-etcd") ||
|
||||
strings.Contains(certName, pki.RequestHeaderCACertName) ||
|
||||
strings.Contains(certName, pki.APIProxyClientCertName)) {
|
||||
strings.Contains(certName, pki.APIProxyClientCertName) ||
|
||||
strings.Contains(certName, pki.ServiceAccountTokenKeyName)) {
|
||||
certMap[certName] = pki.CertificatePKI{}
|
||||
continue
|
||||
}
|
||||
@@ -346,7 +349,7 @@ func (c *Cluster) getBackupHosts() []*hosts.Host {
|
||||
|
||||
func regenerateAPIAggregationCerts(c *Cluster, certificates map[string]pki.CertificatePKI) (map[string]pki.CertificatePKI, error) {
|
||||
logrus.Debugf("[certificates] Regenerating Kubernetes API server aggregation layer requestheader client CA certificates")
|
||||
requestHeaderCACrt, requestHeaderCAKey, err := pki.GenerateCACertAndKey(pki.RequestHeaderCACertName)
|
||||
requestHeaderCACrt, requestHeaderCAKey, err := pki.GenerateCACertAndKey(pki.RequestHeaderCACertName, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -361,3 +364,54 @@ func regenerateAPIAggregationCerts(c *Cluster, certificates map[string]pki.Certi
|
||||
certificates[pki.APIProxyClientCertName] = pki.ToCertObject(pki.APIProxyClientCertName, "", "", apiserverProxyClientCrt, apiserverProxyClientKey)
|
||||
return certificates, nil
|
||||
}
|
||||
|
||||
func RotateRKECertificates(ctx context.Context, c *Cluster, configPath, configDir string, components []string, rotateCACerts bool) error {
|
||||
var (
|
||||
serviceAccountTokenKey string
|
||||
)
|
||||
componentsCertsFuncMap := map[string]pki.GenFunc{
|
||||
services.KubeAPIContainerName: pki.GenerateKubeAPICertificate,
|
||||
services.KubeControllerContainerName: pki.GenerateKubeControllerCertificate,
|
||||
services.SchedulerContainerName: pki.GenerateKubeSchedulerCertificate,
|
||||
services.KubeproxyContainerName: pki.GenerateKubeProxyCertificate,
|
||||
services.KubeletContainerName: pki.GenerateKubeNodeCertificate,
|
||||
services.EtcdContainerName: pki.GenerateEtcdCertificates,
|
||||
}
|
||||
if rotateCACerts {
|
||||
// rotate CA cert and RequestHeader CA cert
|
||||
if err := pki.GenerateRKECACerts(ctx, c.Certificates, configPath, configDir); err != nil {
|
||||
return err
|
||||
}
|
||||
components = nil
|
||||
}
|
||||
for _, k8sComponent := range components {
|
||||
genFunc := componentsCertsFuncMap[k8sComponent]
|
||||
if genFunc != nil {
|
||||
if err := genFunc(ctx, c.Certificates, c.RancherKubernetesEngineConfig, configPath, configDir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(components) == 0 {
|
||||
// do not rotate service account token
|
||||
if c.Certificates[pki.ServiceAccountTokenKeyName].Key != nil {
|
||||
serviceAccountTokenKey = string(cert.EncodePrivateKeyPEM(c.Certificates[pki.ServiceAccountTokenKeyName].Key))
|
||||
}
|
||||
if err := pki.GenerateRKEServicesCerts(ctx, c.Certificates, c.RancherKubernetesEngineConfig, configPath, configDir); err != nil {
|
||||
return err
|
||||
}
|
||||
if serviceAccountTokenKey != "" {
|
||||
privateKey, err := cert.ParsePrivateKeyPEM([]byte(serviceAccountTokenKey))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Certificates[pki.ServiceAccountTokenKeyName] = pki.ToCertObject(
|
||||
pki.ServiceAccountTokenKeyName,
|
||||
pki.ServiceAccountTokenKeyName,
|
||||
"",
|
||||
c.Certificates[pki.ServiceAccountTokenKeyName].Certificate,
|
||||
privateKey.(*rsa.PrivateKey))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -67,6 +67,10 @@ const (
|
||||
WorkerPlane = "workerPlan"
|
||||
EtcdPlane = "etcd"
|
||||
|
||||
KubeAppLabel = "k8s-app"
|
||||
AppLabel = "app"
|
||||
NameLabel = "name"
|
||||
|
||||
WorkerThreads = util.WorkerThreads
|
||||
)
|
||||
|
||||
@@ -458,3 +462,47 @@ func ConfigureCluster(
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RestartClusterPods(ctx context.Context, kubeCluster *Cluster) error {
|
||||
log.Infof(ctx, "Restarting network, ingress, and metrics pods")
|
||||
// this will remove the pods created by RKE and let the controller creates them again
|
||||
kubeClient, err := k8s.NewClient(kubeCluster.LocalKubeConfigPath, kubeCluster.K8sWrapTransport)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to initialize new kubernetes client: %v", err)
|
||||
}
|
||||
labelsList := []string{
|
||||
fmt.Sprintf("%s=%s", KubeAppLabel, CalicoNetworkPlugin),
|
||||
fmt.Sprintf("%s=%s", KubeAppLabel, FlannelNetworkPlugin),
|
||||
fmt.Sprintf("%s=%s", KubeAppLabel, CanalNetworkPlugin),
|
||||
fmt.Sprintf("%s=%s", NameLabel, WeaveNetworkPlugin),
|
||||
fmt.Sprintf("%s=%s", AppLabel, NginxIngressAddonAppName),
|
||||
fmt.Sprintf("%s=%s", KubeAppLabel, DefaultMonitoringProvider),
|
||||
fmt.Sprintf("%s=%s", KubeAppLabel, KubeDNSAddonAppName),
|
||||
fmt.Sprintf("%s=%s", KubeAppLabel, KubeDNSAutoscalerAppName),
|
||||
}
|
||||
var errgrp errgroup.Group
|
||||
labelQueue := util.GetObjectQueue(labelsList)
|
||||
for w := 0; w < services.WorkerThreads; w++ {
|
||||
errgrp.Go(func() error {
|
||||
var errList []error
|
||||
for label := range labelQueue {
|
||||
runLabel := label.(string)
|
||||
// list pods to be deleted
|
||||
pods, err := k8s.ListPodsByLabel(kubeClient, runLabel)
|
||||
if err != nil {
|
||||
errList = append(errList, err)
|
||||
}
|
||||
// delete pods
|
||||
err = k8s.DeletePods(kubeClient, pods)
|
||||
if err != nil {
|
||||
errList = append(errList, err)
|
||||
}
|
||||
}
|
||||
return util.ErrList(errList)
|
||||
})
|
||||
}
|
||||
if err := errgrp.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -116,7 +116,7 @@ func (c *Cluster) InvertIndexHosts() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cluster) SetUpHosts(ctx context.Context) error {
|
||||
func (c *Cluster) SetUpHosts(ctx context.Context, rotateCerts bool) error {
|
||||
if c.Authentication.Strategy == X509AuthenticationProvider {
|
||||
log.Infof(ctx, "[certificates] Deploying kubernetes certificates to Cluster nodes")
|
||||
hostList := hosts.GetUniqueHostList(c.EtcdHosts, c.ControlPlaneHosts, c.WorkerHosts)
|
||||
@@ -127,7 +127,7 @@ func (c *Cluster) SetUpHosts(ctx context.Context) error {
|
||||
errgrp.Go(func() error {
|
||||
var errList []error
|
||||
for host := range hostsQueue {
|
||||
err := pki.DeployCertificatesOnPlaneHost(ctx, host.(*hosts.Host), c.RancherKubernetesEngineConfig, c.Certificates, c.SystemImages.CertDownloader, c.PrivateRegistriesMap)
|
||||
err := pki.DeployCertificatesOnPlaneHost(ctx, host.(*hosts.Host), c.RancherKubernetesEngineConfig, c.Certificates, c.SystemImages.CertDownloader, c.PrivateRegistriesMap, rotateCerts)
|
||||
if err != nil {
|
||||
errList = append(errList, err)
|
||||
}
|
||||
|
@@ -134,7 +134,7 @@ func (c *Cluster) BuildKubeAPIProcess(prefixPath string) v3.Process {
|
||||
"tls-private-key-file": pki.GetKeyPath(pki.KubeAPICertName),
|
||||
"kubelet-client-certificate": pki.GetCertPath(pki.KubeAPICertName),
|
||||
"kubelet-client-key": pki.GetKeyPath(pki.KubeAPICertName),
|
||||
"service-account-key-file": pki.GetKeyPath(pki.KubeAPICertName),
|
||||
"service-account-key-file": pki.GetKeyPath(pki.ServiceAccountTokenKeyName),
|
||||
"etcd-cafile": etcdCAClientCert,
|
||||
"etcd-certfile": etcdClientCert,
|
||||
"etcd-keyfile": etcdClientKey,
|
||||
@@ -249,7 +249,7 @@ func (c *Cluster) BuildKubeControllerProcess(prefixPath string) v3.Process {
|
||||
"allocate-node-cidrs": "true",
|
||||
"cluster-cidr": c.ClusterCIDR,
|
||||
"service-cluster-ip-range": c.Services.KubeController.ServiceClusterIPRange,
|
||||
"service-account-private-key-file": pki.GetKeyPath(pki.KubeAPICertName),
|
||||
"service-account-private-key-file": pki.GetKeyPath(pki.ServiceAccountTokenKeyName),
|
||||
"root-ca-file": pki.GetCertPath(pki.CACertName),
|
||||
}
|
||||
if len(c.CloudProvider.Name) > 0 && c.CloudProvider.Name != aws.AWSCloudProviderName {
|
||||
|
@@ -47,6 +47,12 @@ func ReconcileCluster(ctx context.Context, kubeCluster, currentCluster *Cluster,
|
||||
if err := reconcileControl(ctx, currentCluster, kubeCluster, kubeClient); err != nil {
|
||||
return err
|
||||
}
|
||||
// Handle service account token key issue
|
||||
kubeAPICert := currentCluster.Certificates[pki.KubeAPICertName]
|
||||
if currentCluster.Certificates[pki.ServiceAccountTokenKeyName].Key == nil {
|
||||
log.Infof(ctx, "[certificates] Creating service account token key")
|
||||
currentCluster.Certificates[pki.ServiceAccountTokenKeyName] = pki.ToCertObject(pki.ServiceAccountTokenKeyName, pki.ServiceAccountTokenKeyName, "", kubeAPICert.Certificate, kubeAPICert.Key)
|
||||
}
|
||||
log.Infof(ctx, "[reconcile] Reconciled cluster state successfully")
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user