Kubernetes (K8s) is a container orchestration platform. In simple language, when we have dozens or hundreds of containers to run, we can’t manually SSH into machines and start them. Kubernetes handles that for us — it decides where containers run, restarts them when they crash, scales them up or down, and manages networking between them.
Why We Need It
Running one container with docker run is easy. Running 50 containers across 10 machines? That’s where things get messy. We’d need to handle:
- Which machine has enough CPU/memory?
- What happens when a container crashes at 3 AM?
- How do containers on different machines talk to each other?
- How do we roll out updates without downtime?
Kubernetes solves all of this. We tell it what we want (desired state), and it figures out how to make it happen.
The Big Picture
A Kubernetes cluster has two parts: the control plane (the brain) and worker nodes (the muscles).
Control Plane Components
API Server (kube-apiserver) — the front door to the cluster. Every command we run with kubectl, every internal component talking to the cluster — it all goes through the API server. It validates requests and writes state to etcd.
etcd — a distributed key-value store that holds the entire cluster state. Think of it like the cluster’s database. If etcd dies and we have no backup, we lose the cluster. That’s why production setups run etcd with replication.
Scheduler (kube-scheduler) — when we create a Pod, it doesn’t have a node yet. The scheduler looks at resource requirements, constraints, and available capacity, then picks the best node.
Controller Manager (kube-controller-manager) — runs a bunch of control loops that watch the cluster state and make corrections. If we say “I want 3 replicas” and one dies, the controller notices and creates a new one.
Worker Node Components
kubelet — an agent running on every worker node. It talks to the API server, receives Pod assignments, and tells the container runtime to start/stop containers. It also reports node health back to the control plane.
kube-proxy — handles networking rules on each node. When a Service gets created, kube-proxy sets up the rules so traffic can reach the right Pods. It uses iptables or IPVS under the hood.
Container Runtime — the software that actually runs containers. Kubernetes doesn’t run containers itself. It delegates to a runtime like containerd or CRI-O via the Container Runtime Interface (CRI). Docker was removed as a direct runtime in K8s 1.24.
How They All Talk
The flow goes like this: we run kubectl apply → API server validates and stores in etcd → scheduler assigns a node → kubelet on that node picks it up → container runtime starts the container. Every component watches the API server for changes rather than components calling each other directly. This “watch and react” pattern is what makes Kubernetes so resilient.
In simple language, the control plane is the brain that makes decisions, and worker nodes are the hands that do the actual work. We tell the brain what we want, and it coordinates the hands to make it happen.