KubernetesI · Container and Distributed Systems FoundationsContainer and distributed systems foundations
Why distributed systems need an orchestrator
What you'll learn
- Articulate the operational failure modes that appear when containers are run by hand on many hosts
- Distinguish the responsibilities a container orchestrator takes from the responsibilities it leaves to operators
- Reason about distributed systems failures (partial failure, network unreliability, clock drift) that shape every orchestrator design
- Identify where Kubernetes shifts work and where it creates new categories of failure
Prerequisites
- linux-distributions-and-lifecycle
- docker-architecture-at-a-glance
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
A single host running a single container is a solved problem. A production estate running hundreds of containers across tens of hosts is not a solved problem — it is a recurring series of incidents until the operator introduces an orchestrator. This lesson sets up the failure modes that drive every Kubernetes design decision that follows.
What breaks when you scale containers by hand
Running containers manually with docker run, docker compose up
or systemd units on a fleet of hosts works up to about a dozen
services. Past that, the operator starts paying a tax in
incident time that grows faster than linearly:
flowchart LR
A[1-5 services / 1 host] --> B[5-20 services / 2-3 hosts]
B --> C[20-100 services / 5-20 hosts]
C --> D[100+ services / 20+ hosts]
A --> A1["Trivial: one host, one script"]
B --> B1["Drift starts: SSH + ad-hoc automation"]
C --> C1["Operator becomes the orchestrator"]
D --> D1["Pager fatigue: humans cannot keep up"]
At each step, the symptoms are different but the causes are the same: a human is being asked to do what a control loop should.
Symptom 1: failed containers are not restarted where they should be
A container crashes on host web-04 at 03:00. Without an
orchestrator, nothing restarts it. With an orchestrator, a new copy
is placed on a different host because the original is unhealthy.
This is not “high availability” by accident — it is the orchestrator’s
explicit job to track desired replica count against observed running
replicas and to act on the difference.
Symptom 2: rolling deploys become manual surgery
Updating 50 containers across 10 hosts means ssh, docker pull,
docker stop, docker run. Each step is a place where the
deployment can become partial — five containers on the new
version, forty-five on the old, and the load balancer is sending
50% of traffic to each. Production systems need atomic-or-rolling
semantics; humans do not provide them reliably.
Symptom 3: configuration and secrets drift
Two months in, web-04 has the old TLS certificate because nobody
restarted the container after cping the new cert into place. Three
hosts have the new DATABASE_URL; seven do not. The orchestrator’s
job is to make the configuration declarative — the operator
writes “the database URL is X” once, and the system converges every
host to X.
Symptom 4: scaling is a project, not a knob
A marketing campaign is sending 10x the normal traffic. The operator must ssh to every host, decide which containers to start, decide where, decide which load balancer to update. With an orchestrator, the operator writes “if CPU > 70%, scale out” — the system handles the rest, including scaling back when traffic returns to normal.
Symptom 5: observability is host-shaped, not service-shaped
Without an orchestrator, “is my service healthy” is a join across every host’s logs, every host’s metrics, every load balancer’s view. With an orchestrator, the service is the unit of identity — the operator asks the system, not the hosts.
What an orchestrator does (and does not) solve
A container orchestrator takes a declarative description of the
desired state (“there should be 5 replicas of web:v2.1 behind this
service, with these environment variables, on nodes labelled
role=app”) and a set of workers (the hosts), and runs a control
loop that closes the gap between the two:
sequenceDiagram
autonumber
participant Op as Operator
participant API as API server
participant Store as State store (etcd)
participant Ctrl as Controller
participant Worker as Worker node
Op->>API: Declare desired state
API->>Store: Persist
Ctrl->>Store: Observe (watch)
Ctrl->>Worker: Reconcile (create/schedule)
Worker-->>Ctrl: Report status
Ctrl->>Store: Update observed state
Note over Ctrl,Store: Loop continues — drift closes automatically
The orchestrator’s responsibilities are:
- Scheduling: which container runs on which host, given constraints (resources, affinity, taints, topology)
- Lifecycle: starting, replacing, restarting unhealthy containers
- Scaling: adjusting replica counts, vertically or horizontally, in response to signals or operator intent
- Configuration and secrets distribution: declarative injection of env vars, files, credentials
- Service discovery and routing: stable network identity (ClusterIP, Service) decoupled from container identity (Pod IP)
- Self-healing: replacing containers that fail their probes, rescheduling when hosts disappear
- Rolling updates and rollbacks: progressive replacement with rollback on failure
What the orchestrator does not solve:
- Application correctness. The orchestrator can guarantee “5 replicas of web:v2.1 are running and reachable”; it cannot guarantee that v2.1 actually works. That remains the operator’s job (tests, canary, observability).
- Stateful data safety. The orchestrator schedules Pods; it does not back up the database they connect to. Storage and backup are separate problems.
- Network reliability inside the cluster. The cluster network is software-defined and can fail in new ways.
- Cost. Schedulers optimise for constraints, not money.
- Disaster recovery of the orchestrator itself. Kubernetes needs its own backup (etcd), HA, and recovery strategy — which the orchestrator cannot provide for itself.
The distributed-systems tax
Every orchestrator is a distributed system. Kubernetes inherits three consequences that shape its design and operation:
- Partial failure is normal. A 100-node cluster loses a node every few days on average; a 1000-node cluster loses nodes every few hours. The orchestrator must treat node loss as a routine event, not an exceptional one.
- Network is unreliable. Packets are dropped, partitions happen, latencies spike. The orchestrator cannot rely on synchronous RPCs as if the network were a bus.
- Clocks drift. Every host’s clock is wrong by some amount; certificate validation, log timestamps, lease expiry, and TLS all depend on clocks being within tolerance. NTP / chrony is a prerequisite for Kubernetes, not an optional nice-to-have.
flowchart LR
A[Single host] --> B[Multi-host]
B --> C[Distributed system]
C --> D[Failures are routine]
C --> E[Network is unreliable]
C --> F[Clocks drift]
D --> G[Orchestrator design]
E --> G
F --> G
G --> H[Kubernetes: API + reconcilers + watch + etcd]
These three properties explain nearly every Kubernetes design choice: the API server is the single funnel for state (so it can serialize decisions), etcd uses Raft consensus (so the cluster state survives partial failure), the scheduler is a separate component (so it can retry without blocking the API), and the kubelet runs every few seconds (so a missed heartbeat does not mean a lost node).
What Kubernetes actually is
Kubernetes is:
- A declarative API for describing desired cluster state (Pods, Services, Deployments, ConfigMaps, etc.).
- A set of controllers that observe the cluster and reconcile the observed state toward the desired state.
- A scheduler that places Pods on nodes based on constraints and resources.
- A worker agent (
kubelet) on every node that runs the containers and reports back. - A storage backend (
etcd) that durably persists all API objects. - A set of conventions (label selectors, owner references, finalizers) that let controllers coordinate without a central brain.
Kubernetes is not:
- A container runtime (it delegates to containerd / CRI-O via CRI).
- A network (it delegates to a CNI plugin).
- A storage system (it delegates to a CSI driver).
- A load balancer (it delegates to a cloud controller or MetalLB).
- A configuration management system (it stores config; it does not render it).
What Kubernetes changes for the operator
Adopting Kubernetes shifts the operator’s day-to-day work:
| Before Kubernetes | With Kubernetes |
|---|---|
| ssh to host X, fix container | Edit YAML, apply, observe reconciliation |
| Write runbook for “container won’t start” | Read the Pod event — usually tells you why |
| Hand-write health checks | Declare liveness/readiness/startup probes |
| Hand-roll rolling deploys | Declare strategy: RollingUpdate, set maxSurge/maxUnavailable |
| Manually update load balancer config | Declare a Service or Ingress |
| Manually distribute secrets | Declare a Secret and a mount |
| Manually scale up at peak | Declare an HPA and let metrics drive it |
| ssh to find which host a container is on | kubectl get pod -o wide |
Each row is a category of work that shrinks. None of them disappears entirely: probes still need to be designed, RollingUpdate parameters still need tuning, secrets still need rotation, HPA targets still need thought, host placement still matters for performance and HA.
Cross-course references
- The Linux course part
LXXVIII-Linux-Containerscovers the kernel primitives (namespaces, cgroups, OverlayFS) that the orchestrator inherits from the OS. - The Docker course parts
XXV-Docker-FoundationsandXXVII-Docker-Installcover the image and runtime model that Kubernetes workloads run on top of. - The Linux course part
XXIV-Linux-Timecovers chrony and NTP — a prerequisite for any distributed system that does certificate validation, log correlation, or lease expiry. - The Observability course part
I-Observability-Foundationscovers the metrics/logs/traces signals a Kubernetes estate feeds into and the operational difference between monitoring and observability.
Quiz
Knowledge check · 4 questions
Q1. Which of the following problems does a container orchestrator such as Kubernetes actually solve?
Q2. Adopting Kubernetes removes the operational burden of running containers in production.
Q3. A team runs 80 services across 12 hosts with systemd unit files and a hand-rolled deploy script. They are considering Kubernetes. What specific symptoms will adoption address, and what new failure modes does it introduce?
Output of `kubectl-equivalent` audit: host web-04 service web@v1.32 container crashed 0 restarts since 03:12 host web-04 service web@v1.32 crash loop: 4 restarts in last 6 minutes host db-02 service db@v2.7 running healthy host db-03 service db@v2.7 running healthy host app-07 service app@v3.1 running healthy but with stale config (DB_URL points to db-02 which was migrated to db-04 two weeks ago) host app-09 service app@v3.1 not running — host unreachable host app-09 no service scheduled — no automation to relocate Inventory: 12 hosts, 80 services, 0 orchestration, 1 hand-rolled bash deploy.
Q4. Name three properties of distributed systems that shape every Kubernetes design decision, and give one concrete example of how each property appears in the architecture.
Passing score: 75%. Answers are checked in this browser.
Production discipline
A container orchestrator is the answer to a specific operational question: how do I run many containers across many hosts without becoming the bottleneck myself? Kubernetes answers that question well, but it is not the answer to every operational question.
Production discipline for Part I:
- Treat the orchestrator as a distributed system with its own failure modes, not as a magic layer that removes them.
- Recognise that Kubernetes is a planner, not an executor for application correctness — your tests, canaries, and observability remain load-bearing.
- Plan for the control plane’s own HA, backup, and recovery before the first workload lands; an etcd that is not backed up is a single point of failure.
- Document the operational differences: what was a runbook before is now a manifest; what was a script is now a controller’s job.
- Accept that adopting Kubernetes is a multi-quarter migration, not a swap.