Skip to main content
RunBook Academy

KubernetesLXXIII · Control Plane High AvailabilityControl plane HA

DNS and kubeconfig — distributing the API server endpoint

Advanced⏱ ~17 minkubectlkubeadm

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

Not yet marked complete on this device.

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:6443 survives 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

  1. Q1. What should the kubeconfig's `server` URL point at?

  2. Q2. kubeconfig users can be authenticated via token-based ServiceAccount credentials instead of client certificates.

  3. 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.

  4. 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.