What Problem Does Kubernetes Solve?

Kubernetes is famously complex, and most explanations start with its parts — pods, deployments, services — which is exactly backwards. Start with the problem: you have containers, you have many machines, and you need something to run the right containers on the right machines and keep them running as things fail. Kubernetes is a control loop for that, and once you see it that way, the complexity becomes comprehensible.

Kubernetes has a reputation for being bewilderingly complex, and it earns it if you learn it as a pile of features. This series learns it from first principles — starting with the problem it solves, then containers, then Kubernetes’s objects as answers to specific needs. This first post is about the why: what problem Kubernetes exists to solve, and its core idea (declarative desired state plus continuous reconciliation) that every later concept is an instance of. Get the why, and the parts stop being arbitrary.

The problem: containers at scale

Assume you already have containers (the next post explains what they really are). A container packages an application with its dependencies into a portable, isolated unit that runs the same everywhere. Containers solved “it works on my machine” — but they created a new problem: running many containers across many machines, reliably. Once you have more than a few containers and more than one server, hard questions pile up:

Doing all this by hand — SSHing to machines, starting containers, restarting them when they die, updating a load balancer as things move — is impossible at any real scale. You need a system that manages containers across a fleet of machines automatically. That system is a container orchestrator, and Kubernetes is the dominant one. The problem Kubernetes solves, in one line: run containers across a cluster of machines, and keep them running correctly as the world changes.

The core idea: declarative desired state + reconciliation

Here is the single most important concept in Kubernetes, and the one that makes everything else fall into place. Kubernetes is built on declarative desired state and continuous reconciliation:

You declare:   "I want 3 replicas of this app"
Kubernetes:    observes actual (2 running) → acts (start 1 more) → observes → acts → ...
               continuously, forever, keeping actual == desired despite failures/changes

This is a control loop (like a thermostat: you set the desired temperature, and it continuously acts to reach and maintain it, regardless of the weather). Kubernetes is a control loop for your containers: you set the desired state, and it works continuously to make reality match, forever, adapting to failures and changes. This is why Kubernetes can self-heal (restart crashed containers), scale, and roll out changes — they’re all just “change the desired state (or the world changes), and reconciliation makes actual match desired.” Every Kubernetes object and behavior you’ll learn is an instance of this one pattern. If you internalize declarative-desired-state-plus-reconciliation, the rest of Kubernetes is details.

This is also the GitOps connection (from the platform-engineering series): GitOps stores the desired state in git, and Kubernetes reconciles to it — GitOps is desired-state-plus-reconciliation extended to git as the source of truth.

The shape of a cluster

To make the reconciliation idea concrete, know the basic anatomy of a Kubernetes cluster:

Control plane (the brain — runs the reconciliation):
  - API server   — the front door; you submit desired state here; everything goes through it
  - etcd         — the datastore holding the cluster's desired + actual state
  - scheduler    — decides which node each pod runs on
  - controllers  — the reconciliation loops (keep actual == desired)

Worker nodes (the muscle — run your containers):
  - kubelet      — the agent on each node that runs and reports on containers
  - container runtime — actually runs the containers
  - kube-proxy   — handles networking to the containers

You interact with the cluster by submitting desired state to the API server (via kubectl or GitOps), and the control plane’s controllers make it real on the nodes. You don’t tell nodes what to do directly; you declare what you want, and the system figures out placement and execution. This architecture is the reconciliation model made physical — a brain (control plane) continuously steering the muscle (nodes) toward your declared state.

Why (and why not) Kubernetes

Kubernetes is powerful but genuinely complex, so it’s worth being honest about fit (the platform-engineering and architecture-decisions themes apply):

The honest framing: Kubernetes solves a real and hard problem (containers at scale) with a powerful, general model (declarative reconciliation), but that generality is complexity you should only take on when the problem warrants it. This series teaches Kubernetes so that when you need it, it’s comprehensible rather than mysterious. The next post goes underneath Kubernetes to what it orchestrates: containers, from first principles.

Key takeaways

Further reading

Sources & References

Official Kubernetes docs
Where Kubernetes fits