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]>
77 lines
3.2 KiB
Markdown
77 lines
3.2 KiB
Markdown
# 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).
|