Skip to main content
Course/Troubleshooting/Troubleshooting the Control Plane
4/490 min
Troubleshooting

Troubleshooting the Control Plane

Diagnose kube-apiserver, kube-scheduler, kube-controller-manager, and etcd failures. Fix broken static pod manifests and verify control plane health.

advanced90 minRead β†’ Lab β†’ Quiz β†’ Practice
🧠 Brain Warm-Up
🧠 Brain Warm-Up: The kube-apiserver static pod manifest in /etc/kubernetes/manifests/kube-apiserver.yaml has a typo in the --etcd-servers flag. Walk through exactly what happens next β€” which component notices the error, what the error looks like, and what the observable symptoms are before you even run a single kubectl command.

Control Plane Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Control Plane Node ─────────────────────────────┐
β”‚                                                                             β”‚
β”‚  /etc/kubernetes/manifests/            Static Pod Manifests                 β”‚
β”‚  β”œβ”€β”€ kube-apiserver.yaml    ─────────► API Server (port 6443)               β”‚
β”‚  β”œβ”€β”€ kube-scheduler.yaml    ─────────► Scheduler                            β”‚
β”‚  β”œβ”€β”€ kube-controller-manager.yaml ──► Controller Manager                   β”‚
β”‚  └── etcd.yaml              ─────────► etcd (port 2379)                     β”‚
β”‚                                                                             β”‚
β”‚  kubelet watches /etc/kubernetes/manifests/ and ensures these pods run.     β”‚
β”‚  They appear in: kubectl get pods -n kube-system                            β”‚
β”‚                                                                             β”‚
β”‚  Certificates:    /etc/kubernetes/pki/                                      β”‚
β”‚  kubeconfig:      /etc/kubernetes/admin.conf β†’ ~/.kube/config               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Diagnostic Sequence When kubectl Fails

kubectl get nodes returns: "The connection to the server 127.0.0.1:6443 was refused"
       β”‚
       β”œβ”€β”€ Step 1: Is kube-apiserver running?
       β”‚   kubectl get pods -n kube-system | grep apiserver
       β”‚   crictl ps | grep apiserver            (on the control plane node)
       β”‚
       β”œβ”€β”€ Step 2: Check the static pod manifest
       β”‚   cat /etc/kubernetes/manifests/kube-apiserver.yaml
       β”‚   Look for: typos in flags, wrong file paths, wrong etcd endpoint
       β”‚
       β”œβ”€β”€ Step 3: Check kubelet logs for manifest errors
       β”‚   journalctl -u kubelet -n 100 | grep -i "error|fail|apiserver"
       β”‚
       β”œβ”€β”€ Step 4: Check kubeconfig
       β”‚   cat ~/.kube/config | grep server
       β”‚   Should be: https://127.0.0.1:6443 (or the control plane IP)
       β”‚
       └── Step 5: Check etcd health
           ETCDCTL_API=3 etcdctl endpoint health \
             --endpoints=https://127.0.0.1:2379 \
             --cacert=/etc/kubernetes/pki/etcd/ca.crt \
             --cert=/etc/kubernetes/pki/etcd/server.crt \
             --key=/etc/kubernetes/pki/etcd/server.key

Static Pod Manifests β€” How They Work

The kubelet has a --pod-manifest-path (or staticPodPath in config.yaml) pointing to /etc/kubernetes/manifests/. The kubelet watches this directory:

  • Add a file β†’ kubelet creates the pod within seconds
  • Edit a file β†’ kubelet detects the change and recreates the pod
  • Delete a file β†’ kubelet terminates the pod

This is why control plane components survive API server restarts β€” they are managed directly by kubelet, not by the API server.

Important: Changes take effect when kubelet detects the file change. You do NOT need to restart kubelet for manifest changes.

Common Control Plane Failures

# kube-apiserver won't start after manifest edit
journalctl -u kubelet | grep kube-apiserver
# Error: open /etc/kubernetes/pki/apiserver.crt: no such file or directory
# β†’ Wrong certificate path in manifest

# kube-apiserver: flag error
# flag provided but not defined: --etcd-serverss (typo)
# β†’ Edit manifest, fix the typo, kubelet recreates the pod

# kube-scheduler: can't connect to API server
# Failed to get delegated authentication kubeconfig
# β†’ kube-apiserver may be down, fix API server first

# etcd: member list fails
# context deadline exceeded
# β†’ etcd data dir corrupted or network issue

Checking Control Plane Health

# Quick overview of control plane pods
kubectl get pods -n kube-system

# Component status (may show unhealthy for deprecated endpoints)
kubectl get componentstatuses

# Check individual component pod logs
kubectl logs -n kube-system kube-scheduler-<node-name>
kubectl logs -n kube-system kube-controller-manager-<node-name>

# etcd health check (from control plane node)
ETCDCTL_API=3 etcdctl endpoint health \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

# etcd member list
ETCDCTL_API=3 etcdctl member list \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key