Files
rootnode-academy/content/root/root-05-kubernetes-foundations/m00-mental-model/02-demonstration-desired-state.md
T
ced4568andClaude Sonnet 5 25409d3bd7 feat(root): author Kubernetes foundations curriculum
root-05-m00-kubernetes-mental-model — a new, full gold-standard-pattern
front-door module for ROOT 05: what Kubernetes solves, the desired-state
model, the control-plane/worker split, and Pods/Namespaces/labels
through kubectl. Lesson, demonstration (watching a Pod get replaced
after manual deletion), knowledge check, guided exercise (planning a
Namespace layout), a real Lab (namespaces-basics), and a reflection —
sequenced ahead of the existing bare kubectl-fluency lab bank.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-26 09:05:40 -05:00

3.2 KiB

Demonstration: Desired State Reconciliation

Watch what actually happens when reality drifts from desired state — this is the mechanism the whole lesson describes, made concrete.

Setup

A Namespace called demo exists with a Deployment web declaring replicas: 2. Right now, reality matches desired state:

$ kubectl get pods -n demo
NAME                   READY   STATUS    RESTARTS   AGE
web-7d8f9c6b5d-abcde   1/1     Running   0          3m
web-7d8f9c6b5d-fghij   1/1     Running   0          3m

Someone (or something) deletes one Pod

$ kubectl delete pod web-7d8f9c6b5d-abcde -n demo
pod "web-7d8f9c6b5d-abcde" deleted

What happens in the next second or two, without anyone doing anything else

$ kubectl get pods -n demo
NAME                   READY   STATUS              RESTARTS   AGE
web-7d8f9c6b5d-fghij   1/1     Running             0          3m
web-7d8f9c6b5d-klmno   0/1     ContainerCreating   0          1s

A brand new Pod (...-klmno, a new random suffix — this is NOT the deleted Pod coming back) appeared on its own. Nobody ran kubectl create again. The Deployment's controller noticed actual state (1 running Pod matching its label selector) no longer matched desired state (replicas: 2), and created exactly one replacement to close the gap — not two, not zero.

A few seconds later:

$ kubectl get pods -n demo
NAME                   READY   STATUS    RESTARTS   AGE
web-7d8f9c6b5d-fghij   1/1     Running   0          3m
web-7d8f9c6b5d-klmno   1/1     Running   0          8s

Back to 2/2 — desired state restored, entirely without human intervention.

Why this matters beyond the demo

This exact mechanism is what makes a node crash, a Pod eviction, or a container being OOM-killed something Kubernetes recovers from automatically instead of something that pages a human at 2am. The controller loop doesn't know or care WHY a Pod disappeared — crash, manual delete, node failure — it only ever asks "does reality match desired state right now?" and acts if not. Understanding this one loop explains a huge amount of Kubernetes' behavior that would otherwise look like unrelated special cases.

Instructor Notes

Demo script: Run this live rather than only showing the captured output above — have students watch kubectl get pods -n demo --watch in one terminal while you delete a Pod from another. Watching the new Pod name/age appear in real time lands the "this is a NEW Pod, not a restart" point far better than static text.

Approximate timing: 8-10 minutes live; 5 minutes as a self-paced read.

Common misconception to correct: students frequently describe this as "Kubernetes restarted the Pod." Correct this explicitly — a deleted Pod is gone permanently; a new Pod object was created to satisfy the replica count. This distinction matters later when debugging (the new Pod has zero history from the old one — no old logs, no old restart count).

Optional extension: ask what would happen if you deleted the Deployment itself instead of one Pod (answer: all of its Pods are deleted and NOT replaced, because the thing declaring desired state is now gone — a good way to reinforce that the Deployment, not any individual Pod, is the actual source of truth).