KubernetesLXXVI · Cluster CertificatesCluster certificates
Cluster certificates — the PKI that holds the cluster together
What you'll learn
- List every certificate managed by kubeadm
- Explain what each certificate identifies
- Locate the PKI directory and inspect cert contents
- Identify the failure mode when a specific cert expires
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
Every kubeadm-managed cluster has a Public Key Infrastructure (PKI) that governs both authentication and encryption. The PKI is small enough to enumerate completely — about twenty certificate and key files in a single directory — and each one has a defined purpose and expiry. This lesson walks the layout, the certs, and what each one does.
The PKI directory
kubeadm init creates the cluster’s PKI in
/etc/kubernetes/pki/:
ls /etc/kubernetes/pki/
ca.crt
ca.key
apiserver.crt
apiserver.key
apiserver-kubelet-client.crt
apiserver-kubelet-client.key
front-proxy-ca.crt
front-proxy-ca.key
front-proxy-client.crt
front-proxy-client.key
sa.key
sa.pub
etcd/
ca.crt
ca.key
server.crt
server.key
peer.crt
peer.key
healthcheck-client.crt
healthcheck-client.key
Sibling files in /etc/kubernetes/ include the kubeconfigs
that bind identities to client certs:
admin.conf
controller-manager.conf
scheduler.conf
kubelet.conf
flowchart LR
A["/etc/kubernetes/pki/"] --> B["Cluster CA (ca.crt, ca.key)"]
A --> C["API server (apiserver.crt, apiserver.key)"]
A --> D["API server kubelet client"]
A --> E["Front-proxy CA + client"]
A --> F["ServiceAccount signing key"]
A --> G["etcd/ (CA, server, peer, healthcheck)"]
H["/etc/kubernetes/*.conf"] --> I["admin, controller-manager, scheduler, kubelet"]
The cluster CA
The cluster CA (ca.crt, ca.key) is the trust anchor for
the entire cluster. It signs:
- The API server’s serving certificate.
- The API server’s kubelet client certificate.
- The kubelet’s client certificate (signed on demand via the kube-controller-manager’s CSR signers).
- The
admin.conf,controller-manager.conf,scheduler.conf, andkubelet.confkubeconfigs.
sudo openssl x509 -in /etc/kubernetes/pki/ca.crt \
-noout -subject -issuer -dates
subject=CN = kubernetes
issuer=CN = kubernetes
notBefore=Aug 16 10:00:00 2026 GMT
notAfter=Aug 16 10:00:00 2027 GMT
Self-signed (issuer == subject). 1-year validity.
The API server certificate
The API server’s serving certificate (apiserver.crt) is
what clients present against when they connect to the API
server:
sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt \
-noout -subject -ext subjectAltName
subject=CN = kube-apiserver
X509v3 Subject Alternative Name:
DNS:cp-1, DNS:cp-2, DNS:cp-3, DNS:lb,
DNS:localhost, DNS:kubernetes,
IP Address:10.0.1.10, IP Address:10.0.1.11,
IP Address:10.0.1.12, IP Address:10.0.1.254,
IP Address:127.0.0.1
The SAN list is critical: every hostname or IP that a client might use to reach the API server must be in the SAN, or the TLS handshake fails. Adding a new control-plane host requires re-signing this cert with the new SAN.
The API server kubelet client cert
The API server authenticates to the kubelet using the
apiserver-kubelet-client cert. This is a client cert
(presented to the kubelet, not the other way around), and
its CN is what the kubelet’s webhook authorization checks.
The front-proxy CA and client
The front-proxy CA authenticates the API server’s
aggregated-API path. The aggregator uses the
front-proxy-client cert to authenticate to upstream
extension API servers (metrics-server, custom metrics API,
ingress controllers with admission). Without this cert, the
aggregator cannot forward requests to extension API servers.
The ServiceAccount signing key
The sa.key and sa.pub pair are used by the API server
to sign and verify ServiceAccount tokens:
ls -la /etc/kubernetes/pki/sa.key /etc/kubernetes/pki/sa.pub
These keys do not have a certificate expiry — they are cryptographic keys, not X.509 certs. Rotating them invalidates every existing SA token across the cluster, which is correct but disruptive. Plan SA-key rotation for major cluster operations.
The etcd certificates
The etcd/ directory contains a separate PKI for the
etcd cluster:
ca.crt/ca.key— etcd’s own CA.server.crt/server.key— the etcd member’s serving cert (used for peer traffic and client traffic).peer.crt/peer.key— the cert etcd uses to authenticate to peer members.healthcheck-client.crt/healthcheck-client.key— the cert used byetcdctl endpoint healthand liveness probes.
etcd’s CA is independent of the cluster CA. Replacing the cluster CA does not affect etcd.
The kubeconfigs
The kubeconfigs in /etc/kubernetes/ are not certificates
themselves; they bundle a client certificate with
configuration:
| File | Purpose |
|---|---|
admin.conf | Cluster-admin client (used by operators) |
controller-manager.conf | Identifies kube-controller-manager to the API server |
scheduler.conf | Identifies kube-scheduler to the API server |
kubelet.conf | Identifies the local kubelet to the API server |
The cert lifecycle
Every cert (except the SA keys) has a 1-year default validity. The lifecycle is:
- Generated at
kubeadm init(orkubeadm join). - In use for the duration of the validity.
- Renewed by
kubeadm certs renew(or by external tooling). - Replaced by the kubelet; the static pods are restarted; control plane resumes.
The cert is the cluster’s hygiene discipline. Operating it well is knowing what each cert does, when it expires, and how to rotate it without downtime.
Cross-course references
- The Linux course covers X.509 certificate anatomy
(
man 5 x509v3_config) — the underlying ASN.1 structure Kubernetes certs reuses. - The Observability course covers certificate expiry
alerting via Prometheus
probe_ssl_earliest_cert_expiry. - The OPNsense course covers the CA chain when integrating external services with the cluster.
Quiz
Knowledge check · 4 questions
Q1. Where does kubeadm store the cluster's PKI by default?
Q2. The ServiceAccount signing key (sa.key) has a 1-year default expiry.
Q3. An operator adds a fourth control-plane host (cp-4) to a 3-control-plane cluster. After kubeadm join, kubectl from cp-4 fails with x509: certificate is valid for cp-1, cp-2, cp-3, lb, not for cp-4. What is the issue and how do you fix it?
The cluster has 3 control-plane hosts (cp-1, cp-2, cp-3) and a load balancer. A new cp-4 is added with kubeadm join. The new host can authenticate to etcd but cannot authenticate to the API server: kubectl on cp-4 fails with x509 SAN mismatch. kubectl from existing hosts works fine.
Q4. What does the front-proxy-client certificate authenticate, and what is the failure mode if it expires?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Inventory every cert. Run
kubeadm certs check-expirationmonthly (Lesson 3) and store the output in version control. - Document the SAN list. When adding a control-plane host, the SAN list grows; document the change in the runbook.
- Treat the cluster CA as sacred. Rotating it is a planned operation, not a default.
- Test renewal on staging.
kubeadm certs renewis non-disruptive but not free; rehearse it. - Alert on cert expiry. 30/15/7-day warnings via Prometheus
probe_ssl_earliest_cert_expiry. - Avoid SA key rotation without planning. It breaks every workload’s token cache.
The PKI is small, enumerable, and finite. Operating it well is keeping every cert in that enumeration current and accounted for.