Introduction to Kubernetes
What Kubernetes is, the problem it actually solves, how it compares to Docker Compose, the core objects you need first, and whether you need it at all.
Kubernetes runs containers across a group of machines and keeps them running. You describe what you want. Five copies of this image, reachable at this address, with this much memory, and it works continuously to make reality match that description.
The word people use is declarative. You do not tell Kubernetes to start a container. You tell it what should be true, and controllers inside the cluster keep checking reality against that and correcting the difference. That single idea explains most of how Kubernetes behaves, including the parts that seem strange at first.
The problem it solves
Running one container is easy. docker run and you are done.
The difficulty arrives with the questions that follow. What happens when the process crashes at 3am? When the machine it is on dies? When traffic triples and you need more copies, and where do they go? How do you deploy a new version without dropping requests? How does one service find another when addresses keep changing?
Every one of those has an answer without Kubernetes. The answers tend to be scripts, a load balancer someone configures by hand, a runbook, and a person who knows how it all fits together. Kubernetes replaces that with a system that does it continuously and identically whether you have three containers or three thousand.
A concrete example
An API runs three replicas. A node fails, taking one with it.
Without an orchestrator: your monitoring alerts, someone wakes up, starts a replacement somewhere, updates the load balancer, and confirms. Fifteen minutes if things go well.
With Kubernetes: a controller notices that observed state (two replicas) does not match desired state (three), schedules a replacement on a healthy node, and the Service starts routing to it once its readiness probe passes. Typically under a minute, with nobody involved.
Nothing here required intervention, and nothing behaves differently at 3am.
Kubernetes vs Docker Compose
The most useful comparison, because most people arrive from Compose.
| Docker Compose | Kubernetes | |
|---|---|---|
| Scope | One machine | A cluster of machines |
| Restarts a failed container | Yes | Yes |
| Reschedules when a node dies | No | Yes |
| Rolling updates | No | Yes, built in |
| Autoscaling | No | Yes |
| Self-healing based on health | Restart policy only | Probes drive traffic and restarts |
| Learning curve | An afternoon | Weeks |
| Config for a small app | ~20 lines | ~100 lines |
Compose is genuinely better for local development and for a single-server deployment. It is simpler, faster to write, and easier to reason about. The moment you need more than one machine, or zero-downtime deploys, or automatic scaling, Compose stops being enough, and that is precisely the boundary where Kubernetes starts being worth its complexity.
Docker and Kubernetes are not alternatives, incidentally. Docker builds the images; Kubernetes runs them across machines. Kubernetes stopped using Docker as its runtime in version 1.24, but images built with Docker work exactly as before, because they follow the OCI standard.
The objects you need on day one
You can be productive knowing five things.
Cluster: the whole system: a control plane that makes decisions and worker nodes that run your containers.
Node: one machine, virtual or physical, that runs workloads.
Pod: the smallest unit Kubernetes schedules. Usually one container, occasionally a couple that must share a network namespace and lifecycle. Pods are disposable; they are created and destroyed constantly.
Deployment: declares how many identical Pods should exist and handles rolling updates and rollbacks. This is what you write for a stateless application.
Service: a stable name and address in front of a changing set of Pods. Pod IPs change constantly; Service addresses do not.
Put together: a Deployment keeps three Pods running across your Nodes, and a Service gives clients one address that reaches whichever Pods currently exist.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
kubectl apply -f web.yaml
kubectl get pods
NAME READY STATUS RESTARTS AGE
web-6d8f7c9b4-2xk9p 1/1 Running 0 12s
web-6d8f7c9b4-7mq4t 1/1 Running 0 12s
web-6d8f7c9b4-k3n8w 1/1 Running 0 12s
Delete one and watch what happens:
kubectl delete pod web-6d8f7c9b4-2xk9p
kubectl get pods
A replacement appears within seconds. Nobody asked for it. The Deployment simply observed that there were two Pods where three were wanted.
How the cluster is arranged
Control Plane
API Server
Entry point for all requests
etcd
Cluster state store
Scheduler
Assigns pods to nodes
Controller Manager
Reconciles desired state
Cloud Controller Manager
Integrates with cloud providers (AWS, GCP, Azure)
Worker Nodes
Node 1
kubelet
Node agent
kube-proxy
Network rules
Container Runtime
containerd / CRI-O
Pod
Pod
Node 2
kubelet
Node agent
kube-proxy
Network rules
Container Runtime
containerd / CRI-O
Pod
Pod
Node 3
kubelet
Node agent
kube-proxy
Network rules
Container Runtime
containerd / CRI-O
Pod
Pod
The control plane decides what should happen. The API server is the only way in, and everything, kubectl, controllers, the nodes themselves, talks to it. etcd stores cluster state. The scheduler picks nodes for new Pods. Controllers watch for differences between desired and actual state and act on them.
Worker nodes do the work. The kubelet on each node starts and monitors containers and reports back. kube-proxy programs the networking rules that make Services reachable.
The split matters because it explains failure behaviour. If the control plane goes down, running Pods keep running and keep serving traffic. You just cannot change anything or replace failed Pods. It is a management outage, not necessarily a service outage.
Do you actually need Kubernetes?
Worth asking honestly, because the answer is often no.
Probably not if you run a single application on one or two servers, your team is small and has no Kubernetes experience, you deploy a few times a month, or a managed platform like ECS, Cloud Run, App Runner or Fly.io covers what you need. Kubernetes is a real operational commitment. Upgrades, networking, storage, RBAC, and a steady stream of things to keep current.
Probably yes if you run many services that need to be deployed independently, you need zero-downtime deploys and autoscaling as a matter of routine, you are running across multiple environments or clouds and want one deployment model, or your team is already large enough for a platform function.
The honest failure mode is a small team adopting Kubernetes for a single application and then spending more time on the cluster than on the product. If you are unsure, start with something managed and move when you feel a specific limitation, not before.
Where to go next
Learn it in this order. Each one builds on the last:
- Kubernetes Architecture. What the components do
- Installing Kubernetes. Get a local cluster
- kubectl Basics. The tool you will live in
- Pods. The scheduling unit
- Deployments. How real workloads run
- Services. Stable networking
Install kind or minikube and run the commands. Kubernetes is not a subject you can absorb by reading.
Quick reference
| Task | Command |
|---|---|
| Apply a manifest | kubectl apply -f file.yaml |
| List Pods | kubectl get pods |
| Detail and events | kubectl describe pod <name> |
| Logs | kubectl logs <name> |
| Shell into a container | kubectl exec -it <name> -- sh |
| Scale | kubectl scale deployment/<n> --replicas=5 |
| Everything in a namespace | kubectl get all |
| Cluster nodes | kubectl get nodes |
Key takeaways
- Kubernetes is declarative. You describe desired state; controllers continuously correct reality toward it.
- Its real value is what happens when things fail: reschedules, rolling updates, autoscaling, all without a person.
- Compose is better on one machine. Kubernetes earns its complexity across several.
- Docker and Kubernetes are complementary: Docker builds images, Kubernetes runs them.
- Five objects get you started: Cluster, Node, Pod, Deployment, Service.
- A control plane outage is not automatically a service outage. Running Pods keep serving.
- Plenty of teams do not need it. Managed platforms are a legitimate answer.
Check your understanding
Why the Pod came back
You run kubectl delete pod on a Pod managed by a Deployment. Seconds later a new Pod with a different name is running. Why?
Control plane outage
The Kubernetes control plane becomes unreachable. Existing Pods are healthy and serving traffic. What is the immediate impact?
Frequently Asked Questions
What is Kubernetes in simple terms?
Kubernetes is a system that runs containers across a group of machines and keeps them running. You give it a description of what should be true. How many copies of an application, how much memory each gets, how they are reached, and it continuously compares that against reality and fixes any difference. If a container crashes it is restarted; if a machine dies its workloads are moved elsewhere; if you change the image it rolls out the new version gradually. You describe the destination rather than the steps.
What is the difference between Docker and Kubernetes?
They do different jobs and are usually used together. Docker builds container images and runs containers on a single machine. Kubernetes takes images, which may well have been built with Docker, and runs them across many machines with scheduling, health checking, load balancing, rolling updates and scaling. Kubernetes removed Docker as its container runtime in version 1.24, but that changed nothing for users. Images follow the OCI standard, so Docker-built images run on Kubernetes exactly as before.
Should I learn Docker before Kubernetes?
Yes. Kubernetes assumes you already understand images, containers, ports, volumes and environment variables, and a great many Kubernetes problems turn out to be container problems wearing a disguise: a wrong entrypoint, a missing environment variable, a process writing to a path that is not persisted. Being comfortable with docker build, docker run and writing a Dockerfile will make the Kubernetes learning curve markedly shorter.
Is Kubernetes overkill for a small project?
Often, yes. If you run one application on one or two servers, deploy occasionally, and have no one with Kubernetes experience, the operational overhead. Upgrades, networking, storage, access control, and keeping up with a fast-moving ecosystem. Will likely cost more than it returns. Docker Compose on a single server, or a managed platform such as ECS, Cloud Run or App Runner, is a perfectly respectable choice. Move to Kubernetes when you hit a specific limitation you can name.
What is the difference between Kubernetes and Docker Compose?
Compose orchestrates containers on one machine; Kubernetes orchestrates them across a cluster. Both restart a crashed container, but only Kubernetes reschedules workloads when an entire machine fails, performs rolling updates without downtime, scales automatically on load, and uses health probes to decide which instances receive traffic. Compose is simpler and better for local development and single-server deployments. The crossover point is the second machine.
How long does it take to learn Kubernetes?
Deploying an application and understanding Pods, Deployments and Services takes a few days of hands-on work. Being genuinely comfortable. Debugging networking, understanding storage and access modes, reasoning about scheduling and resource limits, and operating upgrades. Takes months of real use. The most effective approach is a local cluster with kind or minikube and deliberately breaking things: delete Pods, set a memory limit too low, misconfigure a probe. The failure modes are what you actually need to recognise.