Kubernetes: what it solves, and when you don't need it
The problems that appear once you run many containers, how desired state and control loops fix them, the core objects and parts of a cluster, and the honest alternatives.
By the end of this lesson you'll be able to
0 of 5 completeThe problem after containers
On one server, Docker is all you need. docker run starts the app, and if it crashes you
restart it. Now picture 30 servers running 200 containers for 15 services, and ask:
- Which server has room for the next container?
- A server dies at 3 a.m. Who restarts its containers somewhere else?
- How do you roll out a new version without downtime, and roll it back when it's bad?
- Containers move between servers and their IPs change. How does one service find another?
- Traffic triples on sale day. Who adds copies, and removes them afterwards?
Doing that by hand or with scripts is a full-time job. Kubernetes is a system that does it for you: you give it a cluster of machines and a description of what should run, and it keeps it running. It grew out of Borg, Google's internal cluster manager, was open-sourced in 2014 and is now looked after by the CNCF.
Desired state and the control loop
This is the one idea that makes Kubernetes click. You don't tell it what to do; you tell it what you want, and it works out the steps.
# web.yaml: "I want three copies of nginx running, always." apiVersion: apps/v1 kind: Deployment metadata: name: web spec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: nginx image: nginx:1.27 ports: - containerPort: 80
$ kubectl apply -f web.yaml deployment.apps/web created
kubectl apply -f web.yamlkubectltalk to a Kubernetes clusterapplycreate or update from a file-ffrom this fileweb.yamla value the command works on
From then on, controllers run a loop that never stops: look at what's running, compare it
with what you declared, and fix the difference. A Pod crashes? Start another. A node
disappears? Recreate its Pods elsewhere. You change replicas to 5? Two more appear.
That's why the same file is your documentation, your deploy and your disaster recovery.
The objects you'll use every day
| Object | What it is |
|---|---|
| Cluster | A set of machines Kubernetes manages as one |
| Node | One machine (usually a VM) in the cluster that runs your Pods |
| Pod | The smallest unit: one or more containers sharing an IP address and storage |
| Deployment | Keeps N identical Pods running and rolls out new versions gradually |
| Service | One stable name and IP in front of a changing set of Pods |
| Namespace | A folder for objects, to separate teams or environments in one cluster |
Everything is an object with the same shape: apiVersion, kind, metadata and spec. Learn
to read one and you can read them all.
The parts of a cluster
The control plane is the brain:
- API server: the front door.
kubectl, the other components and your CI all talk to it, and only it. - etcd: a key-value store holding every object and its desired state.
- Scheduler: picks a node for each new Pod, based on free CPU and memory and your rules.
- Controller manager: runs the control loops, like the one that keeps a Deployment at 3 Pods.
Worker nodes do the work:
- kubelet: an agent on each node that starts the Pods it's given and reports their health.
- kube-proxy: sets up the networking rules that make Services reach the right Pods.
- Container runtime: usually containerd, which actually runs the containers.
So kubectl apply means: the API server stores your Deployment in etcd, a controller creates
three Pod objects, the scheduler assigns each to a node, and each node's kubelet starts the
containers.
When you don't need Kubernetes
Kubernetes is powerful, and it's also a lot to run and to learn. Be honest about the job:
| Situation | Often a better fit |
|---|---|
| One or two services, steady traffic | One VM with Docker Compose |
| Containers on AWS without managing a cluster | Amazon ECS with Fargate, or App Runner |
| Containers on Google Cloud or Azure | Cloud Run, or Azure Container Apps |
| A web app and no ops team | A PaaS such as Render, Fly.io or Heroku |
| Mixed workloads, containers and plain binaries | HashiCorp Nomad |
Kubernetes earns its cost with many services, several teams, real scaling needs, or the need to run the same way across clouds. Until then, simpler is faster.
Watch Kubernetes heal an app
Prove the control loop to yourself. On a local kind cluster, run three nginx Pods, record their names, kill one, and record the names again. The file should show that one Pod was replaced and three are still running.
~/self-healing.txtReveal one safe solution
$ kind create cluster --name academy $ kubectl create deployment web --image=nginx:1.27 --replicas=3 $ kubectl rollout status deployment/web deployment "web" successfully rolled out $ kubectl get pods -l app=web -o name > ~/self-healing.txt $ kubectl delete $(head -n 1 ~/self-healing.txt) pod "web-7c5d8bf7b-2xk9q" deleted $ echo "--- after ---" >> ~/self-healing.txt $ kubectl get pods -l app=web -o name >> ~/self-healing.txt $ cat ~/self-healing.txt # your Pod names will differ pod/web-7c5d8bf7b-2xk9q pod/web-7c5d8bf7b-8hjtm pod/web-7c5d8bf7b-qz4wd --- after --- pod/web-7c5d8bf7b-8hjtm pod/web-7c5d8bf7b-qz4wd pod/web-7c5d8bf7b-vn5lp $ kind delete cluster --name academy
kind create cluster --name academykindKubernetes in Docker: local clusterscreatecreateclustera value the command works on--namecluster nameacademya value the command works on
kubectl create deployment web --image=nginx:1.27 --replicas=3kubectltalk to a Kubernetes clustercreatecreate an objectdeploymenta value the command works onweba value the command works on--image=nginx:1.27container image--replicas=3how many copies
kubectl rollout status deployment/webkubectltalk to a Kubernetes clusterrolloutmanage a rolloutstatusa value the command works ondeployment/weba value the command works on
kubectl get pods -l app=web -o name > ~/self-healing.txtkubectltalk to a Kubernetes clustergetlist objectspodsa value the command works on-lonly objects with this labelapp=weba value the command works on-ooutput formatnamea value the command works on>write output to a file, replacing it~/self-healing.txta path
kubectl delete $(head -n 1 ~/self-healing.txt)kubectltalk to a Kubernetes clusterdeletedelete an object$(head -n 1 ~/self-healing.txt)the output of another command
echo "--- after ---" >> ~/self-healing.txtechoprint text"--- after ---"text, kept together by the quotes>>append output to a file~/self-healing.txta path
kubectl get pods -l app=web -o name >> ~/self-healing.txtkubectltalk to a Kubernetes clustergetlist objectspodsa value the command works on-lonly objects with this labelapp=weba value the command works on-ooutput formatnamea value the command works on>>append output to a file~/self-healing.txta path
cat ~/self-healing.txtcatprint a file~/self-healing.txta path
kind delete cluster --name academykindKubernetes in Docker: local clustersdeletedeleteclustera value the command works on--namecluster nameacademya value the command works on
The Deployment's controller saw two Pods instead of three and created vn5lp within seconds.
Nobody ran a restart command. kubectl create deployment labels the Pods app=web, which is
how -l app=web finds them.
Try it yourself
0 of 5 steps doneRun each task in your own account or terminal, then tick it off.
Quick check
You told Kubernetes to run 3 replicas. A node dies and takes one Pod with it. What happens?
Official reading for this lesson
- DocsKubernetes overviewKubernetes Docs
- DocsKubernetes componentsKubernetes Docs
- DocsDeploymentsKubernetes Docs
- ToolInstall tools (kubectl, kind, minikube)Kubernetes Docs
- Guidekind quick startkind
- ArticleLarge-scale cluster management at Google with BorgGoogle Research
- GuideKubernetes the hard wayKelsey Hightower
Or get every quiz answer right and it completes itself.