Why Orchestration
The overview promised that orchestration earns its keep the moment you have many containers. This page makes that concrete. We are going to imagine running a real service with nothing but Docker and a few machines, hit every wall, and watch the hand-written script grow until it is — quietly, by accident — a bad reimplementation of Kubernetes. The point is not that scripting is wrong; it’s that the same five problems come up every time, and an orchestrator solves them once, correctly, so you don’t.
The recurring thread frames the whole page: what manual, error-prone step does orchestration remove — and how does it make production safer?
The five walls you hit at scale
Section titled “The five walls you hit at scale”Say you have a web app, three machines, and you want it to be reliable. Here is what goes wrong.
1. Scheduling — which machine runs this?
Section titled “1. Scheduling — which machine runs this?”You have to place containers on machines. Which box has spare CPU and memory right now? You could
hard-code it — “web on box 1, worker on box 2” — but the moment a box fills up or dies, your map is
wrong, and you’re SSHing around eyeballing free -m and docker ps to decide where things fit. This
is a bin-packing problem, and it changes every minute.
2. Healing — the container died at 3am
Section titled “2. Healing — the container died at 3am”Containers crash. Processes leak memory and get OOM-killed (see
cgroups). Whole machines reboot. Something must notice and
restart the work — ideally somewhere healthy. docker run --restart=always handles a process crash
on a surviving box, but it does nothing when the box itself dies. So you write a health-checker. Now
you maintain a health-checker.
3. Scaling — traffic just tripled
Section titled “3. Scaling — traffic just tripled”Black Friday hits and three replicas aren’t enough; you need twelve, then back to three by midnight. By hand that means starting containers, finding room for them, and — crucially — telling the load balancer they exist (and that the old ones are gone). Every step is a chance to fat-finger production.
4. Rollouts — ship v2 without downtime
Section titled “4. Rollouts — ship v2 without downtime”You can’t just stop v1 and start v2; users would see errors in the gap. You want to bring up v2 gradually, watch it stay healthy, shift traffic over, and keep v1 ready to snap back if v2 misbehaves. That is a careful, stateful dance — exactly the kind of thing humans do inconsistently under pressure.
5. Networking — the addresses keep changing
Section titled “5. Networking — the addresses keep changing”Every time a container restarts or moves, it gets a new IP. But other services were talking to the old IP. So you need a stable name that always points at the current healthy set — service discovery, the problem from Part 2, now churning constantly because containers are ephemeral by design.
The hand-rolled script that grows into a bad Kubernetes ┌──────────────────────────────────────────────────────────┐ │ place_container() ← scheduling (which box has room?) │ │ watch_and_restart() ← healing (crashed? node dead?) │ │ scale_to(n) ← scaling (start/stop + tell LB) │ │ rolling_update() ← rollouts (v2 up, drain v1, undo) │ │ update_dns() ← networking (new IPs every restart) │ └──────────────────────────────────────────────────────────┘ Each function is fragile, untested, and yours to keep alive.What Kubernetes automates instead
Section titled “What Kubernetes automates instead”Kubernetes turns all five into one move: you declare desired state, and built-in controllers make reality match it and keep it matching. You don’t write the loop; you state the goal.
| The wall | What you’d script by hand | What you declare to Kubernetes |
|---|---|---|
| Scheduling | Pick a machine, hope it fits | ”Run this Pod”; the scheduler places it |
| Healing | A health-checker daemon | ”Keep 4 replicas”; the controller restarts/reschedules |
| Scaling | Start/stop + update the LB | replicas: 12 (or a target metric) |
| Rollouts | A careful update/rollback script | A Deployment strategy; one command to roll back |
| Networking | Rewrite DNS on every restart | A Service: one stable name, members updated for you |
Here is the entire “keep four replicas healthy forever” problem, declared:
apiVersion: apps/v1kind: Deploymentmetadata: name: webspec: replicas: 4 # desired state: I want four selector: matchLabels: { app: web } template: metadata: labels: { app: web } spec: containers: - name: web image: myapp:1.4.0kubectl apply -f web.yaml# Kill a pod, kill a node — the count returns to 4 on its own.kubectl scale deployment/web --replicas=12 # scaling is one linekubectl rollout undo deployment/web # rollback is one lineNotice what’s gone: no placement decisions, no restart daemon, no LB edits, no DNS rewrites. The manual, error-prone steps from the table above are absorbed by the platform. That is the safety win — not that Kubernetes never fails, but that the routine, repetitive, 3am work is now done the same correct way every time, by software that doesn’t get tired or distracted.
How does it actually do this? Through a control plane and a relentless loop — the subjects of the next two pages, Kubernetes Architecture and The Reconciliation Loop.
The architect’s lens
Section titled “The architect’s lens”Step back from the five walls and ask the questions that decide whether a team adopts an orchestrator at all:
- Why does it exist? Because running many containers on many machines forces five problems — scheduling, healing, scaling, rollouts, networking — and solving each by hand grows into an untested, one-person reimplementation of Kubernetes that breaks at 3am.
- What problem does it solve? It replaces five fragile hand-written scripts with one idea — you
declare desired state (
replicas: 4, this image, this Service) and built-in controllers make reality match and keep it matching. - What are the trade-offs? You trade bespoke scripts you fully understand for a large platform you must learn and operate; the routine 3am toil is absorbed, but you take on cluster complexity, etcd to protect, and a control plane to keep healthy.
- When should I avoid it? When you have few containers on few machines — a single box with
docker run --restart=alwaysalready handles a process crash, and the five walls never get tall enough to justify an orchestrator. - What breaks if I remove it? The five problems return as manual work: SSHing around to place containers, a hand-rolled health-checker, fat-fingered scale-and-tell-the-LB steps, an inconsistent rollout dance, and DNS rewritten on every restart — every cluster reinventing the same load-bearing code, badly.
Check your understanding
Section titled “Check your understanding”- Name the five problems that appear once you run many containers across many machines.
docker run --restart=alwayshandles one kind of failure but not another. Which does it fix, and which does it miss?- Why does the “rewrite DNS on every restart” problem get worse with containers than it was with long-lived VMs?
- Kubernetes replaces five hand-written scripts with one idea. What is that idea, in your own words?
- Using the book’s thread: pick one of the five walls and explain how moving it from a script to a declaration makes production safer, not just easier.
Show answers
- Scheduling (which machine runs this?), healing (notice and restart failed work), scaling (add/remove replicas with load), rollouts (ship a new version without downtime), and networking (a stable name despite churning IPs).
- It fixes a process crash on a surviving box — Docker restarts the container in place. It misses a whole-machine failure: if the box itself dies, there’s nothing left to do the restart, so the work just vanishes.
- Because containers are ephemeral by design — they restart and move constantly, getting a new IP each time — whereas long-lived VMs kept the same address for months. The churn that used to be rare is now continuous, so hand-rewriting DNS becomes a never-ending, error-prone job.
- Declare desired state: instead of writing the loop yourself, you state the goal (
replicas: 4, this image, this Service) and built-in controllers make reality match it and keep it matching. - For example, healing: a hand-written health-checker is untested, undocumented code only its author understands, and it breaks at 3am on a holiday. Declaring
replicas: 4hands that responsibility to a battle-tested controller that does the same correct thing every time — so recovery no longer depends on one person’s fragile script running at the worst possible moment.