Section 1 · Why Kubernetes exists

One container is easy. Forty containers on ten servers is why Kubernetes exists.

You already know how to build and run a container (that's the Docker course). This chapter shows you the problem that appears the moment your app becomes real — and the beautifully simple idea Kubernetes uses to solve it. By the end you'll know what a cluster is, what lives inside it, and exactly what happens between typing kubectl apply and your app serving traffic.

1The 2 a.m. problem

Picture QuickBites, a small food-delivery startup (you'll follow them through this whole course). Their app is containerized and business is good: an API, a frontend, a database, a payment worker — about 40 containers spread across 10 servers. No Kubernetes yet. Just Docker, SSH, and a very tired engineer on call.

Life before Kubernetes: every box is a worry that wakes somebody up.
😴 On-call engineer ssh server-4 docker restart api… server-2 api ✅ frontend ✅ worker 💥 server-5 api ✅ frontend 🐢 disk 91% full… server-8 ⚡ whole machine down its 6 containers are just… gone The questions that page you at 2 a.m.: • Who restarts the crashed worker on server-2? • Who moves server-8's containers somewhere alive? • Release day: who updates 40 containers one by one — without downtime? • Traffic doubled: who starts more api containers, and how does the frontend find them?

Every one of those questions has a manual answer: an SSH session, a script, a checklist, a human. Manual answers don't scale, don't run at 2 a.m., and don't survive the day your best engineer goes on holiday. Kubernetes is the machine that answers all of them automatically.

So what is Kubernetes? Kubernetes (often written K8s — K, eight letters, s) is an open-source container orchestrator: software that takes a group of servers, pools them into one big computer called a cluster, and keeps your containers running on it in whatever shape you asked for — restarting, replacing, moving and scaling them without you. It was open-sourced by Google in 2014 and is now the industry standard everywhere from startups to banks.

2The big idea: declare, don't command

Here is the mental shift that makes Kubernetes click. Everything you've done so far — docker run, docker restart, SSH — is imperative: you issue commands, one by one, and you are responsible for what happens next. Kubernetes flips it: you declare the end state you want, in a YAML file, and the cluster works forever to make reality match it.

🗣 Imperative — you give orders

"Start a container on server-2. Now one on server-5. server-2's crashed — restart it. server-8 died — start its containers on server-3…"

If you stop giving orders, everything stops being managed.

📜 Declarative — you state the goal

"There should always be 3 copies of my API, built from image api:v2, each getting 256 MB of memory."

The cluster enforces this 24/7 — even while you sleep.

That declaration is just a small YAML file. This is a real one — three copies of an API, forever:

deployment.yaml
apiVersion: apps/v1
kind: Deployment          # "keep N copies of this container running"
metadata:
  name: api
spec:
  replicas: 3            # ← the desired state: ALWAYS three
  selector:
    matchLabels: { app: api }
  template:
    metadata:
      labels: { app: api }
    spec:
      containers:
        - name: api
          image: quickbites/api:v2   # the container image to run
The thermostat analogy A thermostat doesn't wait for you to shout "turn on the heater!" — you set 22°C once, and it forever compares desired temperature with actual temperature and acts on the difference. Kubernetes is a thermostat for your software: replicas: 3 is the temperature dial, and its controllers run that compare-and-fix loop (the reconciliation loop) every few seconds, forever.

3Feel it: kill a pod, watch the cluster fight back

In Kubernetes your container runs inside a Pod — the smallest deployable unit, basically a thin wrapper that gives your container an IP address and a home on some server. The demo below is a tiny cluster running replicas: 3. Click any pod to kill it (or use the chaos button) and watch the reconciliation loop do the 2 a.m. work for you.

desired: 3 · actual: 3 · pods replaced so far: 0

🖥 node-1

🖥 node-2

✔ api-7f9c… Running · ✔ api-b21d… Running · ✔ api-e04a… Running — desired state satisfied.
What you just watched (and nobody had to wake up for) The moment a pod died, the cluster noticed actual (2) ≠ desired (3) and created a replacement — sometimes on a different node. That's the answer to half the 2 a.m. questions: a crashed container, or even a dead server, is just a temporary difference between desired and actual state. Fixing that difference is the cluster's full-time job.

4The architecture: a brain and its workers

So what machinery makes that loop happen? Every Kubernetes cluster splits into two roles: a control plane (the brain — it decides) and worker nodes (the muscle — they run your actual containers).

Every Kubernetes cluster in the world — from a laptop to a bank — has this exact shape.
👩‍💻 You kubectl apply 🧠 Control plane — decides, never runs your app kube-apiserver the front door — EVERYTHING talks through it etcd the cluster's memory — stores desired + actual state of everything scheduler picks WHICH node each new pod should run on controller-manager the thermostat — runs the reconciliation loops, 24/7 💪 worker node-1 kubelet (node agent) containerd (runs containers) kube-proxy (networking) 📦 pod: api 📦 pod: frontend 📦 pod: worker 💪 worker node-2 kubelet containerd kube-proxy 📦 pod: api 🗄 pod: database "node-1, run pod X" — kubelets obey the API server

🧠 Control plane

kube-apiserver is the only door — kubectl, nodes and controllers all talk through it. etcd remembers everything. The scheduler places pods; the controller-manager runs the thermostat loops. In managed clouds (EKS, GKE, AKS) this whole layer is run for you.

💪 Worker nodes

Any Linux machine can join as a worker. Its kubelet takes orders ("run this pod"), tells containerd to pull images and start containers, and reports health back. kube-proxy wires the network so pods can reach each other across nodes.

📦 Pods

The unit everything is measured in. A pod wraps one (usually) container, gets its own IP, lives on one node, and is deliberately disposable — pods are cattle, not pets. Higher-level objects like Deployments (next chapter) exist precisely because pods are allowed to die.

5A deploy's journey: apply → running

Let's connect everything with the one flow you'll repeat hundreds of times. You edit your YAML to image: quickbites/api:v3 and run kubectl apply -f deployment.yaml. Six things happen, in order:

1 · kubectl → API server

kubectl sends your YAML to the kube-apiserver over HTTPS. It validates the spec and checks you're allowed to do this.

2 · Desired state saved in etcd

"api should be 3 × quickbites/api:v3" is now recorded. Nothing has run yet — Kubernetes has simply accepted the goal.

3 · A controller spots the difference

The Deployment controller compares: desired v3, actual v2 — and starts a rolling update, creating new v3 pods before killing old v2 ones, so there's zero downtime.

4 · The scheduler picks nodes

Each new pod is assigned to the healthiest node with room — CPU, memory and other rules considered in milliseconds.

5 · kubelet + containerd do the work

The chosen node's kubelet sees its assignment, containerd pulls quickbites/api:v3 from the registry and starts the container.

6 · Running — and now guarded

The pod reports Ready and starts receiving traffic. From this second on, the reconciliation loop guards it: crash it, or even lose the whole node, and the cluster rebuilds toward your declared state. That is the entire magic of Kubernetes.

the whole journey, from your terminal
$ kubectl apply -f deployment.yaml
deployment.apps/api configured

$ kubectl get pods
NAME                   READY   STATUS              RESTARTS   AGE
api-6d5f8-x2p4q        0/1     ContainerCreating   0          2s   ← new v3 coming up
api-59b7c-8kfns        1/1     Running             0          3d    ← old v2 still serving
api-59b7c-mw9zt        1/1     Running             0          3d

$ kubectl get pods        # a few seconds later…
api-6d5f8-x2p4q        1/1     Running             0          9s
api-6d5f8-tr7vb        1/1     Running             0          6s
api-6d5f8-qq21d        1/1     Running             0          4s   ← rollout complete, zero downtime

6What you get for free

What Kubernetes is NOT It doesn't build your images (that's Docker + CI), doesn't store your code (that's Git), and it won't fix a broken app — it will faithfully run your bug on three replicas with perfect uptime. Garbage in, highly-available garbage out.
🧠

Checkpoint — did the big idea stick?

1. You set replicas: 3 and one pod crashes at 2 a.m. What happens?
This is the reconciliation loop: desired state lives in etcd, the controller-manager compares it with reality every few seconds, and any difference gets fixed — no human involved. It's the single most important idea in Kubernetes.
2. Which component does everything — kubectl, kubelets, controllers — talk through?
Nothing talks to etcd or the scheduler directly. Every read and write goes through the API server, which is why it's called the front door — and why kubectl is really just a friendly HTTPS client for it.
3. What is a Pod?
Pods are cattle, not pets: they're meant to be killed and replaced. That's why you almost never create bare pods — you declare a Deployment and let it manage pods for you (next chapter).
4. "Declarative" means…
Like a thermostat: set the goal once, and the system holds it — versus imperative Docker commands, where you are the reconciliation loop.
🔓 You're reading a free chapter of Kubernetes — the first two are open.
Unlock the rest of this course with a one-time payment.
Unlock this course →
🔓 See course prices