Why Kubernetes exists
In this series (14 parts)
- Why Kubernetes exists
- Kubernetes architecture
- Core Kubernetes objects
- Kubernetes networking
- Storage in Kubernetes
- Kubernetes configuration and secrets
- Resource management and autoscaling
- Kubernetes workload types
- Kubernetes observability
- Kubernetes security
- Helm and package management
- GitOps with ArgoCD
- Kubernetes cluster operations
- Service mesh concepts
You know how to build images and run containers. On a single machine that workflow is manageable. Start a container, expose a port, done. The problems show up when you move past one host.
The manual container problem
Picture a team running a web application across five servers. Each server runs three containers. That is fifteen containers to track. Now consider what happens on any given week:
- A container crashes at 3 AM and nobody restarts it until morning.
- Traffic spikes on Friday and you need more replicas, but the developer who knows which servers have capacity is on vacation.
- You deploy a new version by SSH-ing into each host, pulling the image, and restarting. One host gets the wrong tag.
- A server runs out of disk. Containers on it die silently.
None of these are exotic failures. They happen constantly. The root issue is that humans are acting as the control loop. Every decision about placement, scaling, and recovery depends on someone being available, alert, and consistent.
What an orchestrator does
An orchestrator replaces that human control loop with software. You describe what you want (three replicas of service X, each with 256 MB of memory) and the orchestrator figures out where to run them, starts them, and keeps them running.
The core responsibilities:
| Responsibility | Without orchestrator | With orchestrator |
|---|---|---|
| Scheduling | You pick hosts manually | Scheduler places pods on nodes with available resources |
| Scaling | You start/stop containers by hand | Autoscaler adjusts replica count based on metrics |
| Self-healing | You notice failures and restart | Controller detects crashes and replaces containers |
| Networking | You configure load balancers per host | Service abstraction routes traffic automatically |
| Rollouts | You deploy host by host | Rolling update replaces pods gradually |
Desired state vs actual state
Kubernetes is built around one idea: you declare the desired state, and controllers work to make the actual state match.
graph LR
A["User declares desired state"] --> B["API Server stores state in etcd"]
B --> C["Controller watches for drift"]
C --> D{"Actual == Desired?"}
D -- Yes --> E["No action"]
D -- No --> F["Controller takes corrective action"]
F --> C
The reconciliation loop runs continuously. Controllers watch for differences and act to close the gap.
This loop is the reason Kubernetes feels declarative. You do not say “start two more containers.” You say “there should be five replicas.” If one dies, the controller sees four running, compares that to the desired five, and starts a new one. You never write restart logic. The system handles it.
A simple desired state declaration looks like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: myregistry/web-app:1.4.0
ports:
- containerPort: 8080
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "250m"
memory: "256Mi"
This manifest says: keep three replicas of web-app:1.4.0 running at all times, each with specific resource boundaries. Kubernetes picks the nodes, monitors health, and replaces failures. You commit this file to version control and apply it.
Reconciliation in practice
Every major Kubernetes component uses this pattern. The Deployment controller reconciles replica counts. The kubelet on each node reconciles pod state. The scheduler reconciles unscheduled pods with available nodes.
The sequence for a single correction:
- A node loses power. Three pods disappear.
- The node controller marks the node as
NotReadyafter a timeout. - The Deployment controller sees that actual replicas dropped below desired.
- It creates new Pod objects.
- The scheduler assigns them to healthy nodes.
- The kubelet on each target node pulls images and starts containers.
No human intervened. No runbook was followed. The gap between desired and actual state was detected and closed automatically.
What Kubernetes gives you
Beyond the reconciliation loop, Kubernetes provides a set of primitives that handle common distributed systems problems:
Service discovery. Pods get DNS names. Services provide stable endpoints that load-balance across pods. No need for a separate service registry.
Configuration management. ConfigMaps and Secrets decouple configuration from images. Change a config, restart pods, and the new values are live.
Storage orchestration. Persistent volumes abstract away the underlying storage provider. Your manifests do not care whether storage is a local disk, an EBS volume, or an NFS share.
Batch execution. Jobs and CronJobs run tasks to completion. Failed jobs are retried.
Extensibility. Custom Resource Definitions let you teach Kubernetes about your own object types. Operators encode domain-specific logic into controllers.
When Kubernetes is not the answer
Kubernetes adds complexity. That complexity is worth it for certain workloads, and a burden for others.
You probably do not need Kubernetes if:
- You run fewer than five services and a single server handles the load. A compose file on one host is simpler.
- Your team is small and nobody has operational experience with distributed systems. The learning curve is steep.
- Your workload is purely serverless. Functions-as-a-service platforms handle scaling without cluster management.
- You deploy once a month and availability requirements are modest.
Kubernetes earns its keep when:
- You run dozens of services that need independent scaling.
- You deploy multiple times per day and need zero-downtime rollouts.
- You need self-healing. Containers must restart automatically after failure.
- You want a consistent deployment model across cloud providers.
- Your team is ready to invest in learning the platform.
The decision is not about technology preference. It is about operational needs. If the problems described in the first section are costing your team hours every week, an orchestrator is worth the investment.
A quick comparison of orchestrators
Kubernetes is not the only option. Here is how the major alternatives compare:
| Feature | Kubernetes | Docker Swarm | Nomad | ECS |
|---|---|---|---|---|
| Learning curve | Steep | Gentle | Moderate | Moderate |
| Ecosystem | Massive | Limited | Growing | AWS-only |
| Multi-cloud | Yes | Limited | Yes | No |
| Workload types | Containers, VMs, batch | Containers | Containers, VMs, binaries | Containers |
| Auto-scaling | HPA, VPA, KEDA | Manual | Built-in | Built-in |
Kubernetes dominates because of ecosystem size. Most cloud-native tools assume Kubernetes. That network effect matters when you need monitoring, service meshes, GitOps tooling, and secret management to work together.
What comes next
You understand why orchestrators exist and what problem the reconciliation loop solves. The next article covers Kubernetes architecture: the control plane, node components, and how a pod actually gets scheduled onto a machine.