Renew site-management cluster certificates
This runbook is for operators maintaining an NVKE fleet. Use it during planned site maintenance to renew the site-management cluster’s kubeadm-managed leaf certificates under its existing certificate authorities (CAs).
The site-management cluster hosts the NVKE controller, Temporal, databases, and other site services. Its API and control-plane restarts can interrupt fleet management operations at that site. Schedule the work with the site’s owners and verify those services before returning the site to normal operation.
Complete one site before moving to the next. Within a site, renew one control-plane node at a time, checking recovery before proceeding. Use your fleet’s existing remote-execution tooling and privileged access; the Bash commands below describe the work to run on the operator machine and selected node. Automation must preserve the same ordering and stop on a failed check.
This procedure assumes kubeadm static pods, stacked etcd, the default
/etc/kubernetes paths, and local kubeadm CA keys. It is for planned renewal
while the cluster and its current certificates are healthy. Externally managed
CAs, expired certificates, external etcd, and different layouts need their own
procedure. It does not rotate CAs, service-account keys, etcd encryption keys,
kubelet certificates, or application TLS.
Kubernetes’ kubeadm guide requires renewal on every control-plane node and a restart of the control-plane static pods afterward. Use the kubeadm installed for the cluster’s Kubernetes version; this procedure does not depend on a particular patch release.
Where to run commands
Use a Bash shell for the command blocks. If your terminal uses another shell,
run bash first. Node commands below run inside a remote session on the
selected control-plane node. Keep a separate operator terminal for API checks.
1. Select a site and prepare maintenance
Select the site from your fleet inventory. Have its current administrative
kubeconfig, control-plane node inventory, approved privileged access, and
backup and recovery instructions available. NVKE bootstrap produces a
<clusterName>.kubeconfig; use the current credential held by your site’s
secret-management process.
Arrange a maintenance window and one owner. Ensure console or SSH access to every control-plane node remains available if the site’s Kubernetes API fails. Prevent concurrent provisioning, upgrades, node replacements, and other certificate work through your site’s maintenance process. Agree on the maximum API outage, node recovery deadline, and who will recover a failed node.
Three control-plane nodes do not by themselves provide a highly available client endpoint: determine whether clients use an init-node IP or a working VIP/load balancer. For replicated stacked etcd, confirm healthy quorum will remain while one member stops. A single-control-plane site needs a planned API and etcd outage.
On the operator machine, use Bash and select the site kubeconfig and context explicitly:
Record the kube-system UID, node names/IPs, API endpoint, and workload
readiness against the selected site’s inventory. Verify the NVKE controller
API, Temporal workers, database, infrastructure provider, and site identity
services using your deployment’s health checks. See
Observe NVKE and its clusters for NVKE service diagnostics.
Operator machine — connect to a control-plane node. Use your fleet’s remote access method. With ordinary SSH, for example:
After connecting, run bash on the node if its login shell is not Bash.
Control-plane node — preflight checks. In that remote Bash session, check
that its /etc/kubernetes/admin.conf reaches the recorded UID. Check that the
installed kubeadm uses the cluster’s Kubernetes minor version and that all
certificates, the required CA keys, and the etcd health-check client
certificate and key are present:
Every etcd health command below needs the health-check client pair, so a missing file would otherwise fail the procedure partway through.
Stop if a required certificate, CA key, or client key is absent, a certificate
is expired or externally managed, or any node, static pod, or management
workload is unhealthy. Use the site’s etcd tools to
check the actual member list and health of every endpoint; a count of Ready
Kubernetes nodes is not an etcd quorum check. For NVKE’s default stacked-etcd
container, use the node’s containerd CRI socket and select the site
kube-system static pod by its Kubernetes labels. A node can also run other etcd
containers for site workloads. Control-plane node — etcd health. Inspect
all listed members. The examples use containerd’s usual socket; substitute your
node’s CRI endpoint if different. If /etc/crictl.yaml already configures the
correct endpoint, you can omit --runtime-endpoint throughout this runbook.
First, set NODE inside the node’s SSH session to its exact name from
kubectl get nodes, then list its control-plane etcd container. Variables set
on the operator machine are not automatically passed into the SSH session.
Expect one Running row. If there are zero rows, check echo "$NODE" and list
etcd containers without the label filters (ps -a --name '^etcd$', using the
same CRI endpoint). An empty filtered list alone does not establish that etcd
is stopped. Resolve zero or multiple matches before continuing.
Copy the matching running row’s CONTAINER ID below.
Run these commands in the same node session:
The member list must match the site’s control-plane inventory, and every
endpoint must report healthy. Otherwise, repair the baseline before renewal.
Repeat this check after restarting etcd, selecting its new container ID.
2. Verify recovery backups
Before any renewal, verify a recent off-node etcd snapshot and that the
recovery owner has the matching encryption configuration/key, CA keys, and
restore instructions. A YAML export or filesystem copy of /var/lib/etcd is
not a substitute. See etcd recovery
and the etcd encryption key file in Bootstrap the management cluster.
Also back up the selected node’s /etc/kubernetes tree off-node before
renewing it. From the operator machine, with approved SSH and noninteractive
sudo, for example:
Operator machine — node file backup:
Continue only if the SSH backup and archive check both succeed. If either fails, the command deletes the archive so no truncated copy of the CA keys stays on disk; fix the cause and repeat. Keep the archive on encrypted, access-restricted storage outside the repository; it contains live credentials and CA keys. Repeat this file backup for each node immediately before its renewal. The file archive protects PKI and manifests; the etcd snapshot protects cluster state.
3. Renew one control-plane node
Monitor the site’s API and applications before the change and through
recovery, using your existing monitoring. If you need a basic authenticated
API check, run this loop in a separate operator terminal with the same
kubeconfig and context. Configure that terminal as in Section 1 and confirm
kubectl --context "$SITE_CONTEXT" get nodes succeeds before starting the
loop. Keep those working settings; the loop does not select a different site.
Operator machine — API monitor:
The request timeout bounds API requests. Each command is followed by a one-second pause. Keep its output in a private log when an outage record is needed. On failure, kubectl’s error remains visible so you can distinguish an API outage from a credential or configuration problem. If failures exceed the agreed outage limit, stop further changes and investigate. Stop this loop with Ctrl-C after completing maintenance.
On one selected node, renew in a stable console or SSH session. Keep the preflight expiration output to compare with the renewed certificates:
Control-plane node — renew certificates:
renew all renews unconditionally. If it fails, stop and investigate. A
successful command updates files on disk; running components can still serve
their old certificates until restarted.
Restart all four components after renew all. Not all components reload
certificates automatically. Run the following Bash block on the selected
control-plane node, in the same Bash session where Section 1 set NODE.
Set the recovery timeout to the agreed limit in seconds (600 is an example).
The API check uses NODE as a hostname; it must resolve to this node and
appear in its API certificate. If it does not, use this node’s InternalIP from
kubectl --context "$SITE_CONTEXT" get nodes -o wide on the operator machine
in the --server URL below. Keep NODE unchanged for pod selection.
The loop restarts etcd, kube-apiserver, kube-controller-manager, and
kube-scheduler in order, checking recovery before each next restart. Keep
the operator API monitor running. If its failures exceed the agreed outage
limit, interrupt this loop with Ctrl-C and investigate before continuing.
crictl stop makes kubelet recreate the container with the renewed files; no
crictl start or manifest move is needed. Its default timeout of 0 kills the
container immediately, so the loop passes -t 30 to let etcd and the API server
shut down gracefully. See
Kubernetes’ static-pod restart example.
Deleting the mirror pod with kubectl does not restart the container.
During startup, expect Waiting for <component> restart..., followed by a
recovery message for each component. If the recovery deadline is reached, the
block stops and prints the last readiness probe result. On any error or
interruption, inspect the current state before retrying; resume with only the
unfinished components in the for list. For example, if etcd has already
restarted after this renewal and its health checks passed, start the list with
kube-apiserver. Proceed to Section 4 only after all four have recovered.
4. Verify before the next node
Repeat the site health checks from Section 1 and review the API monitor.
The post-renewal kubeadm certs check-expiration output must show later expiry
for the renewed leaf certificates; the CAs are not renewed. That command only
reads the files on disk, so also confirm that the API server serves the
renewed certificate. In the node session where NODE is set (use the node’s
InternalIP if NODE does not resolve), compare the served leaf with the file
kubeadm renewed:
Control-plane node — served API server certificate:
A mismatch means the API server still serves its old certificate or is not
reachable. The block then exits nonzero so automation stops; investigate before
moving on. Recheck application
clients and aggregated APIs used by the site. Copies of admin.conf do not
update automatically; distribute renewed admin credentials through the site’s
secret-management process. See
Kubernetes’ admin certificate guidance.
Only after the agreed outage limit and all health checks pass should the owner repeat the backup, renewal, restart, and verification on the next node. On any failure, leave remaining nodes untouched and preserve backups and diagnostics for the recovery owner. Restoring an etcd snapshot or old PKI files is a separate recovery decision, not a routine renewal step.
5. Return the site to service
After the final control-plane node, repeat the site-wide API, etcd, workload, and client checks. Confirm the NVKE controller API, Temporal workers, database, infrastructure provider, and identity services have returned to their healthy baseline. Check for failed or stalled fleet operations during the maintenance window using the site’s monitoring and Temporal workflow history.
Distribute any renewed administrative kubeconfig copies through the site’s secret-management process. Record the site, nodes renewed, new expiry dates, backup references, and any observed interruption in your maintenance record. Restore the work paused for maintenance once the site passes its health checks. Then repeat this procedure for the next site due for renewal.