Kubernetes Architecture

Concept

Kubernetes is a declarative reconciliation loop. You write desired state (Deployments, Services, …). Controllers watch that state in etcd via the API server and continuously push actual state toward it.

Two planes:

  • Control plane — API server, etcd, scheduler, controller-manager (and cloud-controller-manager when present)
  • Data plane (workers) — kubelet, container runtime (containerd/CRI-O), kube-proxy or equivalent dataplane, CNI plugin

Pods are the smallest deployable unit. Containers in a Pod share network namespace and often volumes; they are scheduled together onto one node.

Why it matters

Almost every Kubernetes incident falls into one layer:

  • Control plane / etcd health
  • Scheduling and placement
  • Node / kubelet / runtime
  • Pod lifecycle and application
  • Service networking / CNI / DNS
  • Storage (PV/PVC/CSI)
  • AuthN/AuthZ and admission

If you do not know which layer owns the symptom, you restart random Pods and lose time. Architecture is the map for triage.

Mental Model

User / CI / GitOps
        │  kubectl / API
        ▼
   kube-apiserver  ◄──── admission, authn/authz
        │
        ▼
      etcd          (desired + observed state)
        │
        ├──────────── controllers (Deployment, ReplicaSet, EndpointSlice, …)
        ├──────────── scheduler (Pod → Node binding)
        ▼
   kubelet on node → CRI (containerd) → Pod sandbox + containers
        │
        └──────────── CNI + kube-proxy/dataplane → Service traffic

Reconciliation is eventually consistent. “I applied the YAML” is not the same as “the cluster matches the YAML”. Watch status and Events.

Key Components

ComponentRoleFailure symptom
kube-apiserverOnly public control-plane APIkubectl hangs/fails; controllers stall
etcdSource of truthAPI latency, leader election issues, lost writes
schedulerBinds free Pods to nodesPods stuck Pending (FailedScheduling)
controller-managerReplica counts, Jobs, endpoints, …Objects not converging
kubeletNode agent; runs Pods via CRINode NotReady; Pods not starting
container runtimePulls images, creates containersImagePullBackOff, CreateContainerError
CNI pluginPod IPs, routes, NetworkPolicyPods Running but unreachable
kube-proxy / dataplaneService VIP → endpointsService IP works on node, fails in Pod (or vice versa)

Key Commands

# Wide health
kubectl get nodes -o wide
kubectl get pods -A -o wide
kubectl get events -A --sort-by='.lastTimestamp' | tail -30
 
# API / control plane
kubectl get --raw='/readyz?verbose'
kubectl get --raw='/healthz?verbose'
kubectl -n kube-system get pods
 
# Node and capacity
kubectl describe node <node>
kubectl top nodes
kubectl get pods -A --field-selector spec.nodeName=<node>
 
# Object status (desired vs actual)
kubectl get deploy,rs,pod -n <ns>
kubectl describe deploy <name> -n <ns>
kubectl get endpointslices -n <ns>

Managed clusters (EKS/GKE/AKS) hide etcd and sometimes the API server process list. You still diagnose via API latency, readyz, and control-plane events.

Common Failure Modes & Symptoms

SymptomTypical layerFirst checks
Pods PendingScheduler / resources / taints / affinitydescribe pod Events; node allocatable
Node NotReadykubelet, runtime, disk pressure, networkdescribe node; kubelet logs; df
CrashLoopBackOffApp, config, probeslogs —previous; probe definitions
ImagePullBackOffImage name, registry auth, networkEvents; crictl pull on node
Service has no endpointsSelector mismatch, Pods not Readyget endpointslices; Pod labels + readiness
API slow or timeoutsapiserver / etcd / webhook latencyreadyz; admission webhook timeouts
NetworkPolicy “broke prod”CNI policy engineRecent Policy objects; default-deny behaviour
Volume stuck Attach/MountCSI, IAM, zone mismatchdescribe pvc/pv; CSI pod logs

Investigation Tips

  • Start with kubectl get nodes and kubectl get pods -A. Then describe the unhealthy object and read Events from the bottom.
  • Pending is almost never fixed by restarting the Pod. Fix scheduling constraints or capacity.
  • Ready vs Running: a Pod can run containers and still fail readiness, so Services omit it. Check probes before blaming CNI.
  • If kubectl itself fails, the problem is control plane or your path to the API — not the workload.
  • kube-system and the CNI namespace are production. Treat their Pods with the same care as customer apps.
  • Prefer kubectl get -o wide and Events over speculative exec into every container.
  • Version skew (kubectl vs server vs node) produces confusing errors. Check kubectl version early when behaviour looks impossible.

Personal Lessons Learned

  • I once spent an hour on application logs for a “network outage” that was Pending Pods after a node drain. get pods -o wide showed no node assigned. Scheduling first, packets second.
  • An admission webhook timed out and blocked all new Pods, including the fix I was trying to roll. Know how to bypass or scale the webhook path in an emergency, and monitor webhook latency like any other dependency.
  • kubectl get componentstatuses lied on modern clusters while readyz told the truth. Prefer livez/readyz and actual kube-system Pod health.
  • ReplicaSet status and Deployment conditions often explain “I applied but nothing moved” before any container log will.