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]>
109 lines
5.9 KiB
Markdown
109 lines
5.9 KiB
Markdown
# What Kubernetes Solves & the Desired-State Model
|
|
|
|
## Before Kubernetes: the problem
|
|
|
|
Imagine you're running a web application on three servers by hand. One server crashes at 2am —
|
|
someone has to notice, log in, and restart the application. Traffic grows, so you need a fourth
|
|
server — someone has to provision it, install dependencies, and configure it to match the other
|
|
three. You ship a new version — someone has to update all four servers, one at a time, without
|
|
taking the whole application down.
|
|
|
|
None of this is hard in isolation. It becomes unmanageable at scale, and it depends entirely on
|
|
a human noticing and reacting fast enough. Kubernetes exists to make a computer do that
|
|
noticing and reacting instead — continuously, automatically, and the same way every time.
|
|
|
|
## The core idea: desired state
|
|
|
|
You don't tell Kubernetes *how* to run your application step by step. You tell it *what you
|
|
want to be true* — "3 replicas of this container should be running" — and Kubernetes
|
|
continuously works to make that true, correcting drift whenever reality doesn't match.
|
|
|
|
This is the single most important mental shift for someone new to Kubernetes: you're not
|
|
writing a script that runs once. You're declaring a **desired state**, and a background process
|
|
never stops comparing the real world against it.
|
|
|
|
```yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: web
|
|
spec:
|
|
replicas: 3 # <- the desired state: "3 of these, always"
|
|
...
|
|
```
|
|
|
|
If a Pod crashes, Kubernetes doesn't "restart the crashed one" as a special case — it just
|
|
notices reality (2 running) no longer matches desired state (3 wanted) and creates a
|
|
replacement. Same mechanism, no special-casing.
|
|
|
|
## The cluster mental model
|
|
|
|
A Kubernetes cluster has two conceptually different kinds of machines:
|
|
|
|
- **The control plane** — the "brain." It stores the desired state (in `etcd`), watches actual
|
|
state, and makes decisions (the API server, scheduler, and controllers all live here). You
|
|
talk to the control plane through `kubectl`; you never SSH into it to manage workloads.
|
|
- **Worker nodes** — where your containers actually run. Each node runs a `kubelet` (an agent
|
|
that starts/stops containers as the control plane instructs) and a container runtime.
|
|
|
|
You describe desired state to the control plane. The control plane decides which nodes should
|
|
run what. The nodes' kubelets make it actually happen. You never manually place a Pod on a
|
|
specific node in normal operation — that placement decision belongs to the scheduler.
|
|
|
|
## Declarative, not imperative
|
|
|
|
"Imperative" means giving step-by-step instructions ("start a container, then another, then
|
|
configure networking between them"). "Declarative" means describing an end state and letting
|
|
the system figure out the steps. Kubernetes' API objects (Pods, Deployments, Services, and
|
|
everything else you'll learn in ROOT_) are declarative — you write YAML describing what should
|
|
exist, `kubectl apply` submits it, and the control plane does the rest.
|
|
|
|
This is also why Kubernetes YAML looks the way it does: it's not a script, it's a specification.
|
|
|
|
## Pods, Namespaces, and labels — the vocabulary you need first
|
|
|
|
- **Pod** — the smallest deployable unit. Usually one container, sometimes a small group of
|
|
tightly-coupled containers that must run together on the same node and share networking.
|
|
You'll rarely create bare Pods directly in real use (a Deployment manages them for you, see
|
|
ROOT 06) but understanding the Pod itself is foundational to everything built on top of it.
|
|
- **Namespace** — a way to partition one cluster into logically separate areas (e.g. `dev`,
|
|
`staging`, teams, or projects), so names don't collide and access/quotas can be scoped.
|
|
- **Labels** — arbitrary key/value tags attached to objects (`app: web`, `env: prod`). Labels
|
|
are how almost everything in Kubernetes finds related objects — a Deployment finds "its" Pods
|
|
by label selector, not by name pattern matching.
|
|
|
|
## kubectl: your one tool for all of this
|
|
|
|
`kubectl` is the command-line client that talks to the control plane's API server. Nearly
|
|
everything you'll do in ROOT_ Labs goes through it: `kubectl get` (list/inspect),
|
|
`kubectl describe` (detailed status + recent events — your primary troubleshooting tool),
|
|
`kubectl apply -f` (submit a desired-state YAML file), `kubectl logs` (see what a container
|
|
printed). You'll build real fluency with these across this module and the ones that follow.
|
|
|
|
## Instructor Notes
|
|
|
|
**Approximate timing:** 15 minutes read, 10-12 minutes for a live walkthrough with discussion.
|
|
|
|
**Demo plan:** Before the demonstration activity, it's worth drawing the control-plane/worker
|
|
split on a whiteboard (or sharing a simple diagram) and tracing one request: `kubectl apply` ->
|
|
API server -> etcd -> scheduler -> kubelet -> container runtime. Students retain the mental
|
|
model much better when they've seen the path, not just read about it.
|
|
|
|
**Likely misconceptions to watch for:**
|
|
- Students often assume `kubectl` talks directly to nodes/containers. It doesn't — it only ever
|
|
talks to the API server. Worth stating explicitly.
|
|
- "Declarative" is sometimes read as "automatic" in a vague sense. Be concrete: it means "you
|
|
describe the end state; a controller loop makes it true," not "Kubernetes guesses what you
|
|
want."
|
|
|
|
**Discussion question:** "If desired state says 3 replicas and you manually run `kubectl delete
|
|
pod` on one of them, what happens next, and why?" (Answer: a new one is created almost
|
|
immediately — deleting a Pod doesn't change the Deployment's desired replica count, so the
|
|
control loop restores it.)
|
|
|
|
**Optional extension:** Ask students to predict what would happen if they edited a running Pod's
|
|
container image directly with `kubectl edit pod` instead of updating the Deployment that manages
|
|
it (answer: it works until that specific Pod is replaced for any reason, at which point the new
|
|
Pod reverts to whatever the Deployment's template says — a good early illustration of "the
|
|
Deployment is the source of truth, not the running Pod").
|