AI EngineeringZero to ProductionHome·About·Contact
Kubernetes Orchestration · Part 1

Why orchestration

You can run one container with docker run. But production means many containers, across many machines, that must survive crashes, reboots, scaling, and rollouts — without you babysitting them. This lesson is the honest bridge from a single docker run to a cluster: the exact problems orchestration solves, the anatomy of a Kubernetes cluster, why a Pod is not the same thing as a container, and — just as important — when not to reach for Kubernetes at all.

⏱️ ~75 min☸️ Cluster concepts🎯 Beginner→Advanced
🌱 Start here — from one container to a fleetYou already know containers (the CD track). Kubernetes — k8s — is what runs them in production when one host and one docker run stop being enough. This lesson is concepts and reading; nothing here needs a cluster yet. From K2 onward the labs apply real YAML to a real cluster, so install minikube or kind locally now, or plan to use EKS in K5. Verify versions and API fields against the current Kubernetes docs — the project moves fast.

Learning objectives

  • Name the concrete production problems docker run leaves unsolved and that orchestration solves.
  • Describe the anatomy of a cluster: control plane (api-server, etcd, scheduler, controller-manager) and nodes (kubelet, container runtime, kube-proxy).
  • Explain the declarative model — you describe desired state, controllers reconcile toward it.
  • Distinguish a Pod from a container and say why the Pod is the smallest unit k8s schedules.
  • Decide honestly when not to use Kubernetes — the cases where it is the wrong tool.

1 · What `docker run` cannot do

A single docker run is perfect for one container on one machine. Production is not that. The moment you have real traffic, you need answers to questions Docker alone does not answer: what restarts a crashed container at 3am? What moves it when its host dies? How do ten replicas share one stable address? How do you roll out v2 without dropping requests, and roll back in seconds when it's bad? Orchestration is the standing machinery that answers all of these automatically.

Production needWith bare `docker run`With an orchestrator
Restart on crash--restart flag, per host onlySelf-healing across the whole cluster
Host diesContainers on it are goneRescheduled onto healthy nodes
Scale to N replicasRun N commands, track them yourselfreplicas: N — one field
Stable address for N replicasWire up your own load balancerA Service gives one virtual IP + DNS
Zero-downtime deployManual, error-proneRolling update built in, with rollback
Config & secretsBake in or pass by handConfigMaps / Secrets, mounted at runtime
Orchestration in one sentenceAn orchestrator keeps a set of containers running in a desired configuration across a pool of machines — restarting, rescheduling, scaling, and updating them so you don't have to. Kubernetes is the de-facto standard, but the ideas (desired state, reconciliation, scheduling) are universal.

2 · The declarative model — desired vs actual state

This is the single most important idea in Kubernetes, and it's what separates it from a shell script. You do not tell the cluster "start this container, then that one." You declare the desired state — "I want 3 replicas of this image exposed on port 80" — and write it down as YAML. A set of controllers continuously compares desired state to actual state and takes whatever action closes the gap. Delete a Pod and the controller notices actual < desired and makes a new one. This loop is called reconciliation.

You write YAML api-server stores desired state Controller reconciles Actual state matches
Why declarative winsBecause the controller runs forever, the system is self-healing by construction: any drift (a crash, a deleted Pod, a dead node) is just a new gap for the loop to close. Imperative scripts run once and then the world drifts away from them. Declarative state is the world the cluster is always pulling itself back toward.

3 · Cluster anatomy — control plane + nodes

A cluster is two kinds of machines. The control plane is the brain that decides what should run where; the worker nodes are the muscle that actually runs your containers. You talk only to the control plane (via kubectl); it drives the nodes.

kubectl / you api-server etcd scheduler + controllers kubelet on node
ComponentLives onWhat it does
kube-apiserverControl planeThe front door. Every read/write goes through it; it validates and persists.
etcdControl planeThe cluster's database — the single source of truth for all state.
kube-schedulerControl planeDecides which node an unscheduled Pod should run on (fit, resources, constraints).
controller-managerControl planeRuns the reconciliation loops (Deployment, ReplicaSet, node controllers…).
kubeletEvery nodeThe node agent — starts/stops Pods and reports health back to the api-server.
container runtimeEvery nodeActually runs containers (containerd/CRI-O).
kube-proxyEvery nodePrograms the node's networking so Service virtual IPs route to Pods.

On a managed service like EKS (K5), AWS runs and secures the entire control plane for you — you only manage nodes. That's the main reason most teams use managed Kubernetes rather than running etcd themselves.

4 · Pods vs containers

Newcomers assume Kubernetes runs containers. It doesn't — directly. The smallest unit it schedules is a Pod: one or more containers that share a network namespace (same IP, same localhost) and can share storage. Usually a Pod is one app container; a second sidecar container (a log shipper, a proxy) is added only when it must live and die with the main one.

Example code for learning — review, test, and adapt it before running against real or production systems. Commands can create, change, or delete resources. See the Terms & Disclaimer.
YAML · a minimal Pod (needs a cluster — minikube/kind or EKS)
pod.yamlapiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    app: web
spec:
  containers:
    - name: app
      image: ghcr.io/example/web:1.0.0   # pin a version, never :latest
      ports:
        - containerPort: 8000
shell · apply and inspect it (needs a cluster)
run.shkubectl apply -f pod.yaml        # create/update from the manifest
kubectl get pods                 # is it Running?
kubectl describe pod web         # events, image, node, why it's Pending/CrashLooping
kubectl logs web                 # the container's stdout/stderr
NAME   READY   STATUS    RESTARTS   AGE
web    1/1     Running   0          12s
You almost never create bare PodsA raw Pod has no self-healing — delete it or lose its node and it's gone for good. In practice you create a Deployment (K2), which manages Pods for you via a ReplicaSet. The bare Pod above is only to make the unit concrete. Output shown is illustrative — verify field names against the current Kubernetes API docs, which do drift between versions.

5 · When NOT to use Kubernetes

Kubernetes is powerful and expensive in complexity. It is the wrong first choice more often than the internet admits. Reach for something simpler when:

SituationWhy k8s is overkillReach for instead
A single container, low trafficYou'd run a control plane to babysit one appA PaaS: Fly.io, Render, App Runner, ECS
A small team, no platform engineerk8s needs someone to own it full-timeManaged containers / serverless
Bursty, event-driven, scale-to-zeroIdle nodes cost moneyLambda / Cloud Run / Fargate tasks
A static site or simple APIEnormous machinery for little benefitA CDN / a managed app host
You just want to ship this weekThe learning curve is realWhatever gets it live; migrate later
The most common Kubernetes mistakeAdopting it before you have the scale or the team to justify it. k8s pays off when you run many services across many machines and need portability, self-healing, and a common platform. For one app and a two-person team, it is usually a tax, not a tool. Use it when the problems in section 1 are your problems.

✓ Checkpoint — you can move on when you can…

  • Name three production problems docker run alone doesn't solve.
  • Explain the reconciliation loop in one sentence (desired vs actual state).
  • Label the control-plane components and say what etcd and the scheduler each do.
  • Explain why a Pod — not a container — is the unit Kubernetes schedules.
  • Give two concrete situations where you'd deliberately not use Kubernetes.
✓ Knowledge check

You delete a Pod that was created directly with kubectl apply -f pod.yaml (a bare Pod, not owned by a Deployment). What happens, and why is this different from deleting a Pod managed by a Deployment?

Show answer
The bare Pod stays deleted — nothing recreates it, because no controller owns it and is watching for the gap between desired and actual state. A Deployment, by contrast, declares "I want N replicas"; its ReplicaSet controller sees actual (N-1) < desired (N) and immediately schedules a replacement. This is exactly why you deploy workloads via Deployments rather than bare Pods: self-healing comes from a controller running the reconciliation loop, not from the Pod itself.
✓ Knowledge check

A startup with one Flask API and two engineers asks whether to launch on Kubernetes. What's the honest answer?

Show answer
Almost certainly no — not yet. One service and a two-person team hit none of the problems k8s solves (many services, many machines, self-healing across a fleet), but pay its full complexity cost: someone must own the cluster, upgrades, networking, and security. A managed container host (App Runner, Cloud Run, Render, Fly.io, or ECS/Fargate) ships the same container with far less operational burden. Revisit Kubernetes when they have multiple services, a platform owner, and concrete needs for portability or fleet-wide operations.

🪜 Practice ladder beginner → industry

Six graded exercises, easy to real-world. Try each before opening its solution.

Exercise 1 · Justify orchestration to a skepticBeginner

Context: Before you learn the YAML, you should be able to defend why the cluster exists at all — the reflex a lead expects from you in a design review.

Your task: Write a short, concrete answer to "we already have docker run on a VM — why add Kubernetes?" grounded in real failure modes, not buzzwords.

Requirements:

  • Name at least three production problems bare docker run leaves unsolved
  • For each, state what an orchestrator does instead
  • End with one honest caveat: a case where k8s would be the wrong call

💡 Hint: Anchor each point to a 3am failure: a crash, a dead host, a bad deploy.

Show solution

The pitch. Bare docker run is fine until production stress arrives, and then it leaves gaps an orchestrator fills automatically:

  • Crash at 3am → a bare container needs --restart and only recovers on that one host; Kubernetes self-heals by rescheduling failed Pods anywhere in the cluster.
  • Host dies → everything on it is lost; the scheduler reschedules those Pods onto healthy nodes.
  • Bad deploy → manual stop/start drops requests; a Deployment does a rolling update with an instant rollback.
  • Ten replicas need one address → you'd hand-roll a load balancer; a Service gives a stable virtual IP and DNS name.

The honest caveat: for a single low-traffic app and a two-person team, this is all cost and little benefit — a PaaS or serverless host is the right call. Kubernetes earns its complexity only when you run many services across many machines.

Exercise 2 · Trace a `kubectl apply` end to endIntermediate

Context: Understanding the request path demystifies every later debugging session.

Your task: Describe, step by step, what happens inside the cluster from the moment you run kubectl apply -f pod.yaml until the container is actually running.

Requirements:

  • Follow the request through the api-server and etcd
  • Say where the scheduling decision is made
  • Say which component actually starts the container on the node

💡 Hint: Every write goes through the api-server; nothing talks to etcd directly except it.

Show solution

The path, component by component:

  1. kubectl sends the manifest to the kube-apiserver (the only front door), which authenticates, validates, and writes the desired state to etcd.
  2. The Pod now exists in etcd but is unscheduled (no node assigned). The kube-scheduler watches for such Pods, picks a node that fits (resources, constraints), and writes that assignment back through the api-server.
  3. The kubelet on the chosen node sees a Pod bound to it, tells the container runtime (containerd) to pull the image and start the container, then reports status back.
  4. kube-proxy programs node networking so any Service in front of the Pod can route to it.

The mental model: you write desired state → api-server persists it → controllers and the scheduler reconcile → kubelet makes it real. Every debugging step later (describe, logs, events) is just reading one stage of this pipeline.

Exercise 3 · Explain reconciliation with a concrete driftAdvanced

Context: The reconciliation loop is the heart of k8s; you should be able to demonstrate it, not just define it.

Your task: Explain what happens when a node running one of a Deployment's 3 replicas is abruptly powered off, tracing the loop back to 3 healthy replicas.

Requirements:

  • Identify which controller notices the gap and how
  • Explain the role of node health / heartbeats
  • State what the end state looks like and roughly how fast

💡 Hint: Two loops interact here: node health detection and the ReplicaSet's replica count.

Show solution

Setup: a Deployment declares replicas: 3; its ReplicaSet has 3 Pods, one per node. A node is powered off hard.

  1. The dead node's kubelet stops sending heartbeats. The node controller waits a grace period, then marks the node NotReady and eventually evicts its Pods (deleting them from desired-state's point of view).
  2. The ReplicaSet controller now sees actual (2 running) < desired (3). It creates a new Pod to close the gap.
  3. That new Pod is unscheduled, so the scheduler places it on a surviving healthy node; its kubelet starts the container.
  4. End state: 3 running replicas again, no human involved. Timing depends on the node eviction timeouts (tens of seconds to a few minutes) — verify the current default grace/eviction settings against the Kubernetes docs.

The lesson: self-healing is not magic — it's two reconciliation loops (node health and replica count) each independently pulling actual state back toward desired state.

Exercise 4 · Decide: k8s or not, for four systemsExpert

Context: The expert skill is knowing when NOT to use the tool you're learning.

Your task: Given four representative systems, decide for each whether Kubernetes is justified, and name the alternative when it isn't.

Requirements:

  • System A: a marketing static site
  • System B: a monthly batch job that runs 20 minutes then exits
  • System C: a platform of 15 microservices for 40 engineers
  • System D: a bursty webhook handler, idle most of the day

💡 Hint: Score each on: many services? many machines? need self-healing/portability? bursty?

Show solution

System A — static site → no. A CDN or managed static host is cheaper, faster, and needs no cluster. k8s adds nothing.

System B — monthly batch → no (mostly). A scheduled serverless job (Lambda, Cloud Run job, or a Fargate task) matches the run-then-exit shape without paying for idle nodes. Only put it on k8s if a cluster already exists and a CronJob is convenient.

System C — 15 services, 40 engineers → yes. This is exactly k8s's sweet spot: many services across many machines, a shared platform, self-healing, and a team large enough to own the cluster. The complexity now buys real leverage.

System D — bursty webhook, idle → probably no. Scale-to-zero serverless (Lambda / Cloud Run) avoids paying for idle capacity; on k8s you'd carry baseline nodes or add KEDA/knative to fake scale-to-zero. Use k8s only if it's already your platform.

The rule: Kubernetes earns its keep on many services × many machines × a team to run it. Miss those and a simpler host wins.

Exercise 5 · Draw the cluster and label the failure domainsProfessional

Context: A platform engineer must be able to sketch the cluster and reason about what breaks when a given piece fails.

Your task: Produce a labeled diagram of a cluster (control plane + 3 nodes) and, for each component, state the blast radius if it fails.

Requirements:

  • Include api-server, etcd, scheduler, controller-manager, and per-node kubelet/runtime/proxy
  • For each, describe what still works and what breaks if it's down
  • Note which components a managed service (EKS) takes off your plate

💡 Hint: Ask for each: if this dies, can running Pods still serve traffic? Can new ones be created?

Show solution

Failure-domain analysis:

  • api-server down → no new changes (no apply, no scheduling of new work), but existing Pods keep running and serving traffic since kubelets act on already-persisted state. The cluster is frozen, not dead.
  • etcd down/lost → the most serious: it's the source of truth. Without a backup, cluster state is unrecoverable. Running Pods may limp on, but the cluster can't be managed. Back up etcd.
  • scheduler down → running Pods fine; new Pods stay Pending (unassigned) until it returns.
  • controller-manager down → reconciliation stops: crashed Pods aren't replaced, rollouts stall. Existing steady-state keeps serving.
  • one node's kubelet down → that node's Pods are eventually rescheduled elsewhere; the rest of the cluster is unaffected.

Managed value: on EKS, AWS runs and replicates the api-server and etcd across AZs and handles their backups/upgrades — you inherit a resilient control plane and only own the nodes. That offload is the main reason to pay for managed Kubernetes.

Exercise 6 · Write the one-page 'do we adopt Kubernetes?' decision memoIndustry scenario

Context: Representative scenario: a Series-B company with 6 services and growing traffic asks platform engineering for a recommendation on adopting Kubernetes. Leadership wants a one-pager, not a religious war.

Your task: Write a decision memo that recommends for or against adopting Kubernetes now, with explicit criteria, costs, and a migration path.

Requirements:

  • State the decision up front, then the criteria behind it
  • Quantify the ongoing cost: who owns the cluster, what breaks if no one does
  • Include a 'revisit if' trigger list so the decision isn't permanent
  • Name the interim option and how you'd migrate to k8s later without a rewrite

💡 Hint: Frame it as reversible: containerize now (portable), choose the runtime as a separate, revisitable decision.

Show solution

Recommendation: not yet — containerize now, defer the cluster. Ship the 6 services as containers on a managed host (ECS/Fargate or Cloud Run) today; adopt Kubernetes when the triggers below fire. Rationale, in one page:

Criteria we scored. (1) Number of services: 6 — meaningful but not yet fleet-scale. (2) Team: no dedicated platform owner — the decisive factor. (3) Portability need: low today. (4) Self-healing/scaling: a managed host already provides both. On these, k8s's benefits are largely already met, while its costs are not yet justified.

The real cost of adopting now. Kubernetes needs an owner: upgrades, CVE patching, networking, RBAC, cost control, and on-call for the cluster itself. Without a named owner it rots into an unpatched, misconfigured liability — the worst of both worlds. That headcount is the true price, not the compute.

Revisit if any of these become true: we cross ~10–15 services; we hire/allocate a platform engineer; we need multi-cloud or on-prem portability; a managed host's limits (custom networking, GPUs, operators) start blocking us; or spend on managed containers exceeds what a cluster would cost with an owner.

Migration path (why this is reversible). Because every service is already a container with a Dockerfile and externalized config/secrets, moving to Kubernetes later is writing manifests — not a rewrite. We lose nothing by waiting, and we avoid paying the cluster tax before it buys us anything.

© 2026 studybydoing.in · AI Engineering: Zero to Production · All rights reserved. · About · Privacy Policy · Terms · Contact
Educational content, provided as-is and without warranty. Code samples are examples — review, test, and adapt them before using in production. See the Terms of Use & Disclaimer. Use at your own risk.
© studybydoing.in