KubernetesLXXIII · Control Plane High AvailabilityControl plane HA
DNS and kubeconfig — distributing the API server endpoint
What you'll learn
- Configure DNS for the API server VIP
- Distribute kubeconfig securely to operators
- Manage kubelet kubeconfig during join
- Plan kubeconfig rotation and credential renewal
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
The kubeconfig is the file that tells kubectl (and kubelet, and every controller) where the API server is and how to authenticate. In an HA cluster, the kubeconfig must point at the LB VIP (or DNS name) so that failover is transparent. This lesson walks the DNS configuration, the kubeconfig distribution, and the rotation discipline.
The kubeconfig anatomy
apiVersion: v1
kind: Config
clusters:
- name: kubernetes
cluster:
server: https://api.example.com:6443
certificate-authority-data: <base64 of ca.crt>
contexts:
- name: default
context:
cluster: kubernetes
user: kubernetes-admin
current-context: default
users:
- name: kubernetes-admin
user:
client-certificate-data: <base64 of admin.crt>
client-key-data: <base64 of admin.key>
Three sections: clusters (where), users (who),
contexts (which user against which cluster). The
current-context selects which context is active.
The DNS configuration
The API server’s DNS record:
api.example.com. IN A 10.0.1.254
Where 10.0.1.254 is the LB VIP (kept HA by keepalived).
Production clusters use DNS for:
- Clean failover: when VIP moves, DNS may need an update; a low TTL enables that.
- Name-based kubeconfig:
https://api.example.com:6443survives IP changes. - TLS SAN match: the cert SAN includes the DNS name; the cert does not need renewal when the IP changes.
The kubeadm-managed kubeconfig
When kubeadm init runs, it creates:
/etc/kubernetes/admin.conf
This is the admin kubeconfig. The user can copy it to their workstation:
mkdir -p ~/.kube
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
Or, on macOS/Linux, use a snap-in helper.
flowchart LR
K[kubeadm] -->|generates| A["/etc/kubernetes/admin.conf"]
A -->|scp| U["~/.kube/config"]
U -->|kubectl uses| C["kubectl commands"]
The kubelet kubeconfig
The kubelet on every worker uses its own kubeconfig:
/etc/kubernetes/kubelet.conf
The kubelet’s ServiceAccount in this kubeconfig is
system:node:<node-name>; its RBAC allows API access
for node / Pod operations.
# /etc/kubernetes/kubelet.conf
apiVersion: v1
kind: Config
clusters:
- name: kubernetes
cluster:
server: https://api.example.com:6443
certificate-authority-data: <base64 of ca.crt>
contexts:
- name: default
context:
cluster: kubernetes
user: system:node:cp-1
users:
- name: system:node:cp-1
user:
client-certificate-data: <base64 of kubelet.crt>
client-key-data: <base64 of kubelet.key>
The kubelet’s kubeconfig is automatically populated by
kubeadm join; the worker uses it on startup.
The bootstrap kubeconfig
During kubeadm join, a temporary kubeconfig is created:
# /etc/kubernetes/bootstrap-kubelet.conf
# A short-lived bootstrap credential used to fetch
# the kubelet's actual credential via CSR
The bootstrap kubeconfig is used to submit a CertificateSigningRequest (CSR); the kube-controller-manager signs it; the kubelet’s actual cert is installed.
Distributing the admin kubeconfig
To give operators access to the cluster, the admin kubeconfig is shared:
# Generation
kubeadm init creates /etc/kubernetes/admin.conf
# Distribution
scp admin.conf user@workstation:~/.kube/config
# Or: kubectl create serviceaccount + token + RBAC
# (for non-admin operators)
In production, the admin kubeconfig is shared:
- Encrypted at rest (GPG, age).
- Through a secure channel (SSH, vault).
- With audit logging enabled (the audit log records who used the kubeconfig).
flowchart LR
A[kubeadm] -->|admin.conf| V[Vault]
V -->|fetch| O1[Operator 1]
V -->|fetch| O2[Operator 2]
V -->|audit| AU[Audit]
Non-admin kubeconfig
A non-admin operator gets a constrained kubeconfig:
# Create a ServiceAccount for an operator
kubectl create serviceaccount ops-readonly -n prod
# Bind a read-only role
kubectl create rolebinding ops-readonly \
--clusterrole=view \
--serviceaccount=prod:ops-readonly \
--namespace=prod
# Get the token
kubectl create token ops-readonly -n prod
The kubeconfig’s client-certificate is replaced with
token:
users:
- name: ops-readonly
user:
token: <SA token>
The token has limited RBAC (view-only in the prod namespace).
The cert validity
The kubeconfig’s client cert has a finite validity (default 1 year):
sudo openssl x509 -in /etc/kubernetes/pki/admin.crt \
-noout -dates
notBefore=Aug 1 10:00:00 2026 GMT
notAfter=Aug 1 10:00:00 2027 GMT
Renewal is required before expiry. kubeadm certs renew covers the cluster’s certificates:
sudo kubeadm certs renew all
For the operator’s kubeconfig, the renewal is manual: generate a new kubeconfig with a fresh cert.
The kubeconfig rotation procedure
Step-by-step:
# 1. Check current cert
sudo openssl x509 -in /etc/kubernetes/pki/admin.crt -noout -dates
# 2. Renew the cert on cp-1
sudo kubeadm certs renew admin.conf
# 3. Verify
sudo openssl x509 -in /etc/kubernetes/pki/admin.conf -noout -dates
# notAfter = 1 year from now
# 4. Distribute the new admin.conf to operators
scp /etc/kubernetes/pki/admin.conf user@workstation:~/.kube/config
# 5. Validate the new kubeconfig
kubectl get no
Cluster operation is unaffected (the renew is on a single control-plane node; the kubeconfig cert is what’s being renewed, not the API server cert).
The kubelet credential rotation
Worker kubelets’ certs are also 1 year:
# Renew kubelet client cert on a worker
sudo kubeadm certs renew kubelet-client
# Or, regenerate via CSR
sudo kubeadm certs renew helper
The kubelet’s new cert is installed; the existing connections from that kubelet to the API server are unaffected.
The DNS for production
Production DNS records:
api.example.com. IN A 10.0.1.254
*.apps.example.com. IN A <worker-IP-range> ; if using wildcard for Services
The *.apps.example.com is for Ingress; the api is
for the control plane.
# Verify the DNS resolves
dig api.example.com +short
# 10.0.1.254
The disaster-recovery kubeconfig
A disaster-recovery kubeconfig is generated for emergency operations:
# Generate a kubeconfig pinned to a specific API server IP
# (skipping the LB)
export KUBECONFIG=/tmp/dr-kubeconfig.yaml
kubectl config set-cluster kubernetes \
--server=https://cp-1.example.com:6443 \
--certificate-authority=/etc/kubernetes/pki/ca.crt
kubectl config set-credentials dr-admin \
--client-certificate=/etc/kubernetes/pki/admin.crt \
--client-key=/etc/kubernetes/pki/admin.key
kubectl config set-context dr \
--cluster=kubernetes \
--user=dr-admin
kubectl config use-context dr
A DR kubeconfig bypasses the LB and connects to one specific API server IP. This is for emergencies (LB failure).
The production discipline
- Store kubeconfig in a vault. Not in Git, not in email, not on shared drives.
- Use DNS for the API endpoint. Survives VIP moves.
- Cert SAN includes both DNS and IP. The cert works for both URL forms.
- Renew kubeconfig certs annually. Calendar reminders.
- Test DR kubeconfig periodically. The DR context must work.
- Audit kubeconfig use. The audit log records who used what.
Quiz
Knowledge check · 4 questions
Q1. What should the kubeconfig's `server` URL point at?
Q2. kubeconfig users can be authenticated via token-based ServiceAccount credentials instead of client certificates.
Q3. An operator's kubeconfig cert is expiring in 7 days. Walk the renewal.
Operator X has a kubeconfig dated 11 months ago; the cert expires in 7 days. They are a primary responder on the cluster.
Q4. Why is it important to rotate the kubeconfig certificates annually, and what happens if rotation is missed?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- DNS for the API endpoint. VIP movement is transparent to the kubeconfig.
- Cert SAN includes DNS name. TLS validation works for both forms.
- Renew kubeconfig certs annually. Calendar reminders.
- Test the DR kubeconfig. A DR context that hasn’t been used is brittle.
- Store kubeconfig securely. Vault, encrypted at rest, audited.
DNS and kubeconfig are the cluster’s connection infrastructure. Operating them well is keeping operators able to connect.