What Kubernetes is

The problem it solves, in plain terms.

Beginner8 min · lesson 1 of 24
In plain terms
You declare a replica count. Kubernetes starts those pods, replaces failures, and keeps the count.

You wrote an app and packaged it into a container: the program plus what it needs to run, so it behaves the same on any machine. One copy on a laptop is a single command. The hard part is many copies across many machines: restart the ones that crash, move work off a dead server, and roll out new versions without going dark. Doing that by hand is a full-time job. Kubernetes does it for you.

The one idea that makes it click

You do not give Kubernetes a list of steps. You declare the end state you want, for example "keep three copies of my app running," and it keeps comparing live objects to that declaration. If a copy dies, it starts a replacement without being asked. The cluster is maintaining the state you set, not waiting for the next command.

Imperative automation is a fixed list of steps. If one step cannot run, the rest of the plan stalls. Kubernetes is declarative: you name the destination state, and controllers keep working out how to get there, including around a failed node or a crashed pod.

People call this a container orchestrator, which is a fancy way of saying it runs, connects, heals, and updates lots of containers for you. You'll also see the name written K8s: the letter K, then eight letters, then s. It grew out of Google's experience running containers at huge scale, and it behaves the same everywhere. The same app description runs on your laptop, in a company data center, or on Amazon, Google, or Microsoft's cloud, so you aren't locked to one vendor. Learn it once and the skills carry over wherever you work.

What Kubernetes does for you
You provide
a desired state
"keep 3 copies running"
your app in a container
the thing to run
Kubernetes handles
running + restarting
keeps copies alive
scaling + updating
more or fewer, new versions
spreading + healing
survives machine failures
You describe what you want. Kubernetes keeps making it true: running, healing, scaling, and updating your app across many machines.

Where your app actually runs

Kubernetes does not live on a single computer. It ties a group of machines together so they act like one system. That group is a cluster. Each machine is a node. Most nodes are workers: they run your app. The control plane decides and remembers what you asked for. You rarely log into a worker. You talk to the control plane, and it assigns work to the workers.

Talking to the cluster with kubectl

You talk to the control plane with kubectl. That is a command-line tool: you type commands instead of clicking. People say "kube-control" or "kube-cuttle," and no one really agrees. Every kubectl command is a request from your machine to the cluster. A good first one lists the machines in the cluster.

terminal
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 9m v1.31.0
kind-worker Ready <none> 8m v1.31.0
kind-worker2 Ready <none> 8m v1.31.0

Kubernetes is not a fancy way to run one container on your laptop. It is a control loop that keeps a whole fleet of containers matching the state you declared. You say "three copies of this app, behind this address, with this config." The cluster compares live reality to that wish and nudges things until they match. That is why operators talk about desired state instead of a checklist of start scripts.

On-call, this mental model matters more than memorizing every YAML field. When something is wrong, ask what the desired state says and what the live objects actually look like. The gap between those two views is almost always where the incident lives. Imagine an attacker already has a foothold in one pod on your production cluster: the same desired-state machinery that heals crashes will also recreate anything you delete unless you change the declaration that keeps recreating it.

Prefer reading the API with kubectl get and kubectl describe over guessing from a dashboard screenshot. The API is the source of truth the controllers read. A dashboard is a delayed sketch of that truth.

Try this

Talk to a real (or kind/minikube) cluster and prove you can see nodes and create a throwaway pod. You want Ready nodes and a Running pod so the "desired state" idea stops being abstract.

terminal
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 12d v1.30.0
kind-worker Ready <none> 12d v1.30.0
$ kubectl run demo --image=nginx:1.27 --restart=Never
pod/demo created
$ kubectl get pods demo -o wide
NAME READY STATUS RESTARTS AGE IP NODE
demo 1/1 Running 0 8s 10.244.1.7 kind-worker
$ kubectl delete pod demo
pod "demo" deleted

Takeaway

Kubernetes is a desired-state engine: you declare what should be true, controllers close the gap. Verify with kubectl against the API, not against a hunch — and remember that healing will recreate whatever your declaration still asks for.

kubectl needs a cluster to talk to first
If kubectl get nodes prints something like "The connection to the server localhost:8080 was refused," don't panic. Nothing is broken. It just means kubectl can't find a cluster yet, because you haven't started one. On your own machine, a free tool like kind or minikube brings up a small practice cluster in a couple of minutes. The rest of this course assumes you have one running.

Run something right now

Enough describing it. Let's make Kubernetes run something for real. The command below starts nginx, a small and popular free web server (a program that answers requests coming from web browsers), as a quick throwaway pod named hello. A pod is the smallest unit Kubernetes runs, and it usually holds a single container: your app. When you press enter, the cluster finds a node with room, pulls down the nginx software, and starts it. A few seconds later it's serving.

terminal
$ kubectl run hello --image=nginx
pod/hello created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello 1/1 Running 0 12s

That one-liner is great for a quick poke around. For real work, you write the state you want into a file and apply that file. Then it lives in version control, a system that tracks every change to your files over time, so a teammate can review it and you can run it again exactly the same way later. These files are written in YAML, a plain-text format that describes settings as simple labels, values, and lists. Here's the same web server written out in full, as a pod named web.

pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
terminal
$ kubectl apply -f pod.yaml
pod/web created
$ kubectl apply -f pod.yaml
pod/web unchanged

Run apply a second time and Kubernetes reports unchanged. It compared your file to what is already running, found no difference, and did nothing. You describe what you want; it only acts on the gap between that and reality.

When a pod won't start

Pods don't always come up clean, and learning to read a failure is half the job. The most common first stumble is a typo in the image tag: ask for one that doesn't exist and the pod gets stuck. kubectl get pods flags the trouble in the STATUS column, and kubectl describe pod explains why at the bottom, under a heading called Events.

terminal
$ kubectl run oops --image=nginx:1.99
pod/oops created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
oops 0/1 ImagePullBackOff 0 45s
$ kubectl describe pod oops
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 45s default-scheduler Successfully assigned default/oops to kind-worker
Normal Pulling 18s (x3 over 45s) kubelet Pulling image "nginx:1.99"
Warning Failed 17s (x3 over 44s) kubelet Failed to pull image "nginx:1.99": manifest not found
Warning Failed 17s (x3 over 44s) kubelet Error: ErrImagePull
Normal BackOff 4s (x4 over 44s) kubelet Back-off pulling image "nginx:1.99"

Read the Events from top to bottom like a short story. The scheduler picked a node, the kubelet on that node tried to pull nginx:1.99, and there is no such tag, so it keeps backing off and retrying. That status, ImagePullBackOff, almost always means a wrong image name or tag. Fix it to a real one like nginx:1.27 and the same pod comes up Running.

When you don't need Kubernetes
Kubernetes earns its keep when you run many copies across many machines and can't watch them by hand. It isn't free: it's a large system to learn, set up, and keep patched. For one small app on one server, where a quick restart after a crash is good enough, plain Docker or a single virtual machine is simpler and cheaper. Reach for Kubernetes when the scale or the uptime is worth that overhead, not because it's in fashion.
Quick check
01You told Kubernetes to keep 4 copies of your app running. One copy crashes at 3 a.m. What happens?
Correct — You declared a desired state of 4 copies. Kubernetes constantly compares that target to reality and closes the gap by itself.
Incorrect — That's the manual work Kubernetes exists to remove. You set the target once, and it keeps restoring it without you.
Incorrect — No. The other 3 copies keep serving requests, and a 4th is started automatically within seconds.
02You run kubectl apply -f pod.yaml, then run the exact same command again and Kubernetes prints "pod/web unchanged". What does that tell you about how Kubernetes works?
Correct — apply is declarative, so Kubernetes only acts on the gap between your desired state and reality, like a thermostat that stays quiet when the room is already at target.
Incorrect — apply is not a one-shot create; you can re-run it any time and it updates whatever has drifted from the file.
Incorrect — "unchanged" means nothing was touched at all, so no delete or recreate happened.
Incorrect — an error would be reported as an error; "unchanged" is a success message meaning no work was needed.
03You maintain one small internal tool that runs on a single server. If it crashes, a simple automatic restart is good enough, and it never needs more than one copy. A colleague suggests moving it onto Kubernetes. Based on this lesson, what is the sound call?
Incorrect — the lesson warns against adopting Kubernetes because it is fashionable; it is a large system to learn, set up, and keep patched.
Incorrect — a plain restart on one machine already handles a crash; you do not need an orchestrator just for that.
Correct — Kubernetes earns its keep when you run many copies across many machines or need high uptime; for a single small app the simpler setup is cheaper and easier.
Incorrect — Kubernetes does not shrink an app's footprint; it orchestrates many copies across machines, adding overhead rather than removing it.

Related