Kubernetes runs many containers across many machines, and keeps them running the way you told it to.
It is for anyone who has containers running in more than one place at once. That includes a team moving from a single container on a laptop to many containers across many servers in production.
It watches over hundreds or thousands of containers at once and continuously fixes anything that drifts from how you said it should run.
The problem Kubernetes exists to solve
Running one container is easy. Running hundreds or thousands of containers across many machines is a different problem. Some will crash and need restarting, and traffic needs to keep finding the right containers as they come and go.
A container running your app crashes at 3am. Nobody is awake to restart it, but a customer's request still needs to reach a working copy of that app within seconds.
The technical details
Kubernetes' own docs put the core question directly. "In a production environment, you need to manage the containers that run the applications and ensure that there is no downtime. For example, if a container goes down, another container needs to start. Wouldn't it be easier if this behavior was handled by a system?"
Kubernetes describes itself as "an open source system for automating deployment, scaling, and management of containerized applications." It groups the containers that make up an application into logical units for easier management and discovery.
The Pod
A Pod is the smallest unit Kubernetes manages. It is one or more containers that are always scheduled and run together on the same machine, sharing storage and a network address. Most Pods run a single container, but a Pod can group several containers that need to work closely together.
A Pod might run a web server container alongside a small helper container that keeps its files up to date from a remote source. Both start together, run on the same machine, and can talk to each other over localhost.
The technical details
Kubernetes' own docs define Pods as "the smallest deployable units of computing that you can create and manage in Kubernetes." A Pod's contents "are always co-located and co-scheduled, and run in a shared context."
Every container in a Pod shares the same network namespace, including one IP address and port space. This lets containers inside a Pod find each other using localhost. They can also share storage volumes.
Pods are "relatively ephemeral, disposable entities." You rarely create one directly. Instead, higher-level resources such as a Deployment create and manage Pods for you.
The Deployment and reconciliation
You do not tell Kubernetes what to do step by step. Instead, you describe the state you want, such as "3 copies of this container running," in a Deployment. Kubernetes then continuously checks reality against that description and changes reality to match.
You set a Deployment's desired replica count to 3. Kubernetes' etcd store records that. If a controller checks and finds only 2 Pods running, it schedules a third to close the gap.
The technical details
Kubernetes' own docs define it directly. "You describe a desired state in a Deployment, and the Deployment Controller changes the actual state to the desired state at a controlled rate." A Deployment "provides declarative updates for Pods and ReplicaSets."
Wikipedia's independent account calls this same mechanism a controller's "reconciliation loop," and gives the same worked example: "a human operator may specify that three instances of a particular pod need to be running, and etcd stores this fact. If the Deployment controller finds that only two instances are running... it schedules the creation of an additional instance of that pod."
The Service
Pods are disposable and get a new IP address every time they are recreated, so nothing else in the cluster can reliably remember one Pod's address for long. A Service fixes this by giving a shifting set of Pods a single, stable name and address. That address stays the same even as the Pods behind it change.
A frontend needs to reach a backend that runs as 3 replica Pods. The Pods' individual IP addresses change constantly as they are replaced, but the frontend only ever needs to know the Service's one stable address.
The technical details
Kubernetes' own docs frame the problem directly. "If some set of Pods... provides functionality to other Pods... inside your cluster, how do the frontends find out and keep track of which IP address to connect to?" Its answer: "Enter Services."
"A key aim of Services in Kubernetes is that you don't need to modify your existing application to use an unfamiliar service discovery mechanism." The set of Pods a Service targets is usually determined by a selector. "The controller for that Service continuously scans for Pods that match its selector" and updates the set it routes to.
Going deeper
What stores and drives a cluster's state?
Every fact Kubernetes knows about a cluster, both what you asked for and what is running, lives in one place. One component is the only thing allowed to talk to it directly.
etcd holds the state, kube-apiserver is the front door
Kubernetes' own docs describe etcd plainly as a "Consistent and highly-available key value store for all API server data," and describe it elsewhere as the backing store "for all cluster data." It is the single source of truth for both desired and observed state.
Nothing else in the cluster reads or writes etcd directly. Instead, everything goes through kube-apiserver, described as "the front end for the Kubernetes control plane" and "the core component server that exposes the Kubernetes HTTP API." It can be scaled horizontally, running several instances with traffic balanced between them.
Reconciliation is what turns stored state into running reality
Storing a desired state would do nothing on its own. Wikipedia's independent account describes the mechanism that acts on it. "A controller is a reconciliation loop that drives the actual cluster state toward the desired state, communicating with the API server to create, update, and delete the resources it manages."
Kubernetes' own overview page makes an almost identical, independently stated point about why this design matters. It argues Kubernetes "eliminates the need for orchestration" precisely because it is "a set of independent, composable control processes that continuously drive the current state towards the provided desired state," rather than a fixed workflow that executes "first do A, then B, then C." Centralized, step-by-step control is not required. The docs describe this as making the system "easier to use and more powerful, robust, resilient, and extensible."
How does a Pod end up running on a specific machine?
Deciding where a Pod runs and making sure it keeps running there are two separate jobs, handled by two separate components.
kube-scheduler picks the node
Kubernetes' own docs describe kube-scheduler as the component that "watches for newly created Pods with no assigned node, and selects a node for them to run on." That decision weighs "individual and collective resource requirements, hardware/software/policy constraints, affinity and anti-affinity specifications, data locality, inter-workload interference, and deadlines."
kubelet keeps it running once it's placed
Once a Pod is assigned to a node, a separate per-node agent called kubelet takes over. Kubernetes' own docs describe it as ensuring "that Pods are running, including their containers," based on the PodSpecs it is given. "The kubelet doesn't manage containers which were not created by Kubernetes," so it only watches over what the cluster itself placed there.
This split, one component deciding placement and a different one enforcing it locally, is what lets Kubernetes keep working even if a node fails. The scheduler picks a new, healthy node for the replacement Pod.
Where did Pods, Services, and Labels come from?
Google's own 2015 announcement blog post traces Kubernetes' core ideas directly back to Borg, its decade-old internal cluster manager.
Borg's "alloc" became the Pod
Google's post states plainly: "Kubernetes traces its lineage directly from Borg. Many of the developers at Google working on Kubernetes were formerly developers on the Borg project." Borg had a similar abstraction called an alloc, short for resource allocation. It was used for cases like running a web server alongside a lightweight log-shipping process on the same machine. Pods generalized that pattern.
Naming and load balancing became the Service
Borg's own naming and load-balancing services, used by applications running on it, became Kubernetes' Service abstraction: "a service has a name and maps to a dynamic set of pods defined by a label selector."
Borg's Job abstraction became Labels
Borg grouped identical replicas into a rigid unit called a Job. Kubernetes replaced that rigidity with Labels, arbitrary key/value pairs attached to any object. It did this specifically because Borg users "often want to manage their entire service... as a single entity" or reason about subsets of a Job differently, something a fixed Job structure couldn't easily do.
A deliberate fix: one IP address per Pod
In Borg, every task on a machine shared that machine's single IP address, forcing every application to manage its own port assignments. Kubernetes fixed this by giving every Pod and Service its own IP address, made possible by software-defined overlay networks. The post calls this change one that "removes the infrastructure complexity of managing ports."
Is Kubernetes an alternative to Docker, or does it run on top of it?
Kubernetes and Docker solve different problems, and the relationship between them has changed over time. Kubernetes never ran containers itself. It always delegated that work to a separate piece of software called a container runtime.
Kubernetes talks to a pluggable runtime, not to Docker specifically
Kubernetes reaches a container runtime through a standard interface called the Container Runtime Interface (CRI). Its own docs name containerd and CRI-O as the container runtimes it supports today, alongside "any other implementation" of the CRI.
Docker support existed, then was removed
Kubernetes did originally support Docker directly, through a compatibility layer called a "dockershim" that sat between Docker and the CRI. Per Wikipedia, that shim was deprecated between November 2020 and April 2022. It was then "removed entirely" in Kubernetes v1.24, released May 2022, "dropping official support for Docker as a container runtime."
This is why the "Kubernetes vs. Docker" framing is a bit of a false choice. Docker was historically one way Kubernetes ran containers, and today that role belongs to containerd or CRI-O.
What does Kubernetes cost to run?
Kubernetes itself is free, open-source software with no pricing page anywhere on its own site. The cost shows up one layer up, in the managed services cloud providers sell to run it for you.
Google Kubernetes Engine charges a flat per-cluster fee
Google Cloud's own GKE pricing page states "a flat cluster management fee of $0.10 per cluster per hour" applies to all GKE clusters, with one zonal cluster free per billing account per month.
Other cloud providers charge for managed Kubernetes too
Amazon Web Services confirms the same shape of cost on its own pricing page for its Elastic Kubernetes Service (EKS): "All Amazon EKS clusters have a per cluster per hour fee based on the cluster's Kubernetes version." AWS also charges separately for optional add-ons such as a Provisioned Control Plane, Auto Mode, and managed capabilities like Argo CD.
Other major cloud providers offer their own managed Kubernetes services with their own separate pricing. The pattern across them is the same. Kubernetes the software is free, but running it reliably at scale, with someone else managing the control plane, is a paid service.
Sources
- Kubernetes homepage
- Overview (Kubernetes Docs)
- Kubernetes Components (Kubernetes Docs)
- Cluster Architecture (Kubernetes Docs)
- Pods (Kubernetes Docs)
- Deployments (Kubernetes Docs)
- Service (Kubernetes Docs)
- Borg: The Predecessor to Kubernetes (Kubernetes Blog)
- Kubernetes, Wikipedia
- GKE Pricing (Google Cloud)
- Amazon EKS Pricing (AWS)
- Kubernetes (CNCF)
Last checked August 2026