Skip to content
SRE & DevOpsDeep Dive Published Updated 8 min readViews unavailable

kubeadm Certificate Operations: Expiration, Renewal, and Control-Plane Restarts

Renew kubeadm-managed control-plane certificates safely by checking expiry, separating CA and kubelet lifecycles, restarting consumers, and validating endpoints.

Kubeadm-managed clusters use certificates for several different identities: API-server clients and servers, etcd peers, front-proxy clients, and credentials embedded in kubeconfig files. A successful renewal command is only one step. The consumer must reload the new file, a copied kubeconfig may still contain the old certificate, and a load balancer can continue serving an unexpected endpoint certificate even after a local file looks correct.

Treat renewal as an inventory and rollout procedure, not a calendar command. First establish which certificates kubeadm owns, which are externally managed, and which components consume them. Then back up the local PKI and configuration, renew the intended leaf certificates on every control-plane node, restart the appropriate static Pods, and test both the stored certificates and the certificates clients actually receive.

Inventory certificates before changing files

On a kubeadm control-plane node, begin with:

sudo kubeadm certs check-expiration

The report covers certificates in the configured kubeadm PKI directory (normally /etc/kubernetes/pki) and certificates embedded in kubeadm kubeconfig files such as admin.conf, controller-manager.conf, and scheduler.conf. It also reports the CA certificates’ expiry dates. Save the output from every control-plane node; a multi-node cluster can have node-specific leaf certificates and local files that are not identical.

Do not read the table as a complete inventory of every TLS identity in a cluster. The kubelet client certificate is normally rotated through the kubelet’s own client-certificate-rotation mechanism and is not listed by kubeadm certs check-expiration. Kubelet serving certificates, admission webhooks, ingress controllers, cloud load balancers, and externally managed etcd can have different owners and renewal workflows. Add those systems to the runbook rather than assuming kubeadm certs renew all covers them.

Record the node name, kubeadm and Kubernetes versions, certificate directory, CA ownership, expiry dates, and served endpoint names. Check that system time is synchronized before diagnosing a validity-window problem. For each API-server certificate, compare its Subject Alternative Names with the address clients actually use: a correct issuer and future expiration do not help if the serving name is absent.

Separate leaf renewal from CA rotation

For a cluster whose CA private key is locally managed by kubeadm, kubeadm certs renew reissues leaf certificates using the relevant CA certificate and private key under the PKI directory. A targeted command can renew one certificate, while kubeadm certs renew all renews all certificates that kubeadm knows how to renew:

sudo kubeadm certs renew all
sudo kubeadm certs check-expiration

Renewal is unconditional: the command does not wait for a certificate to approach expiry. That makes a routine “run it just in case” invocation capable of changing certificates that were still valid. Choose specific certificates when only one consumer needs a replacement, and record the reason, old fingerprint, new fingerprint, and restart plan.

Kubeadm uses the existing certificate’s Common Name, Organization, and Subject Alternative Names as the authoritative attributes when renewing. It does not rebuild those attributes from the kubeadm-config ConfigMap. Keep the served certificate and stored cluster configuration synchronized, and review the generated certificate before restarting a component. If the endpoint names need to change, renewal alone is not the right operation: update the declarative kubeadm configuration and generate the intended certificate with the supported kubeadm phase workflow.

CA certificates are a separate lifecycle. Kubeadm does not support rotating or replacing CA certificates through the ordinary kubeadm certs renew workflow. A CA rotation changes trust roots and requires a staged transition across API servers, controllers, kubelets, workloads, and clients. Do not treat an expiring ca, front-proxy-ca, or etcd CA as just another leaf to renew. Follow the dedicated CA-rotation procedure, maintain an overlap period where required, and test both old and new trust paths.

If certificates are signed by an external CA, kubeadm cannot renew them as locally managed certificates. Use your organization’s CA workflow or the documented kubeadm CSR process; keep private CA keys outside the cluster if that is the security design. An EXTERNALLY MANAGED marker is a handoff to that owner, not a warning that can be cleared by repeating the same kubeadm command.

Plan for every control-plane node

In a replicated control plane, kubeadm’s documentation requires manual renewal to be performed on all control-plane nodes. Renewing only the first node can leave a cluster where requests routed to one API server succeed and requests routed to another fail. Execute the procedure locally and sequentially on each node, using the same approved kubeadm version and configuration policy. Keep enough healthy API servers available for the cluster’s availability objective; a two-node etcd cluster has different quorum risk from a three-member quorum, so account for local etcd as well as the API endpoint.

Before the first change, take a protected backup of /etc/kubernetes/ and relevant kubeadm configuration. Include the certificate/key pairs, kubeconfig files, and static-Pod manifests needed for recovery. Store the backup under the same key-handling controls as the originals; copying private keys to a general-purpose share increases the blast radius. Confirm the backup is readable and that an operator knows which versioned files to restore.

The cluster upgrade path is another renewal trigger: kubeadm renews certificates during a control-plane upgrade by default. If that behavior is intentionally disabled with --certificate-renewal=false, document who owns renewal and how expiry monitoring will page the right operator. A successful upgrade that quietly renews certificates still requires an inventory and consumer-restart plan; it is not proof that every external copy or TLS endpoint has been updated.

Restart consumers, not mirror-Pod objects

Control-plane components created by kubeadm are commonly static Pods. The node’s kubelet watches local manifests, starts the component, and publishes a mirror Pod into the API for visibility. Updating a certificate file does not guarantee that every component reloads it dynamically. Kubernetes documents that control-plane Pods should be restarted after renewal because dynamic reload is not supported for every component and certificate.

kubectl delete pod is not the restart mechanism for a static Pod: the kubelet, not the API server, owns the desired state. Use the node’s supported configuration-management workflow to update or recreate the affected manifest, or follow the kubeadm procedure to temporarily remove that manifest from the watched directory and restore it after the kubelet has stopped the Pod. Check the effective fileCheckFrequency instead of assuming the default delay. Never move all manifests at once, and do not restart API servers or etcd on multiple members simultaneously when the availability plan requires them one at a time.

After each node’s restart, verify that the static Pod is running and that the component is healthy before proceeding to the next node. If local etcd is part of the control plane, check member health and quorum before restarting another etcd member. Keep out-of-band access available; when the API server is down, Kubernetes status commands cannot be the only recovery path.

Renewing admin.conf does not rewrite copies made earlier, including a typical $HOME/.kube/config. Install the renewed kubeconfig only into the intended administrator’s protected profile and preserve ownership and file permissions. Do not print a kubeconfig or private key into a CI log to compare it. The controller-manager and scheduler kubeconfigs also need to be considered by their consumers, even though those components may use the files directly from the local PKI directory.

Verify the artifact and the live endpoint

For a stored certificate, inspect the subject, issuer, validity interval, and SANs without printing private key material. This example uses the openssl x509 -ext option documented by OpenSSL 1.1.1; verify the option against the locally installed OpenSSL build when supporting older or vendor-modified versions:

sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt \
  -noout -subject -issuer -dates -ext subjectAltName

Compare the result with the approved endpoint list and the backup record. kubeadm certs check-expiration verifies the files it knows about, but it does not prove that a running process has reloaded the file. From a trusted administrative host, inspect the certificate served by each control-plane address with the correct TLS server name, including the load-balanced endpoint. If the load balancer terminates TLS, validate that certificate separately; it may not be the kube-apiserver certificate at all.

Then test the control plane’s readiness and a representative authenticated client operation. Check logs for certificate-load or trust errors, confirm that the API endpoint remains reachable through its normal route, and confirm etcd health if local etcd was affected. On an HA cluster, repeat those checks after each node before moving on. Keep before/after dates and fingerprints in the change record so a failed rollout can be distinguished from an endpoint that was already serving a different certificate.

The useful completion condition is not “kubeadm certs renew all returned zero.” It is that each intended certificate has the expected identity and validity, every local consumer restarted or reloaded it, all copied credentials are accounted for, and the actual client-facing endpoints pass the checks your operators depend on.

Related:

Sources:

Comments