Key Takeaways
- Kubernetes manages containerized applications by continuously working toward the desired state you declare, such as running two copies of a web application.
- Containers share a host kernel; VMs run their own guest operating systems. Kubernetes nodes can themselves be VMs.
- Docker remains useful for building images. Kubernetes runs containers through a CRI-compatible runtime, commonly containerd or CRI-O.
- Scaling, external traffic routing, durable storage, and recovery require appropriate configuration. Open-source software doesn't mean a free production environment.
Kubernetes is an open-source platform for deploying and managing containerized applications across a group of machines called a cluster. You describe what should be running, and Kubernetes uses controllers to keep moving the actual system toward that desired state. This is the foundation of Kubernetes container orchestration.
To understand what Kubernetes does, start with the difference between virtual machines, containers, and the machinery that manages them.
What's a VM?
A virtual machine, or VM, is a computer implemented through virtualized hardware. Imagine taking one powerful computer and virtually slicing it into smaller, independent units. Each VM runs its own guest operating system and filesystem, with virtual CPUs and configured memory.
A hypervisor is the software layer that manages these virtual machines. Their underlying physical resources can still be shared or oversubscribed; virtual hardware doesn't necessarily mean dedicated physical CPU cores or automatically fair resource allocation. Microsoft's Hyper-V terminology guide illustrates how a hypervisor manages resources such as memory.
Why use a VM?
- Isolation: Separate guest operating systems create boundaries between applications and their environments.
- Stability: An application crash inside one VM doesn't normally crash applications in another, although a shared host failure can affect both.
- Resource controls: You can configure allocations, limits, or reservations rather than letting every application compete without boundaries.
These are useful controls, not automatic guarantees of security or performance. You still have to configure and maintain the host and its guests.
What's a container?
A container runs an application as isolated processes using an image that packages its code and runtime dependencies. Unlike a VM, an ordinary Linux container shares the kernel of its host environment instead of booting a separate guest operating system. That host environment may itself be a VM.
This avoids a full guest OS for each application, but containers aren't simply replacement VMs with identical isolation. Containers and VMs solve different problems and are frequently used together, including in cloud Kubernetes clusters.
| Concern | Virtual machine | Container |
|---|---|---|
| What it packages | A guest OS and its applications | An application and its runtime dependencies |
| Kernel | Its own guest kernel | Shares the host environment's kernel |
| Resource management | Configured through the hypervisor | Configured through OS and runtime controls; Kubernetes adds requests and limits |
Neither approach automatically guarantees fair resource usage. Kubernetes resource requests and limits are explicit configuration, not a benefit you receive just by putting an application in a container.
Why containers help with portability
You can use the same application image on your laptop and in a cloud environment, reducing differences in installed libraries and application files. Portability still depends on compatible operating systems and CPU architectures, plus the configuration, networking, storage, and external services your application needs. Docker's multi-platform build documentation explains the architecture constraint.
If images and containers are new to you, start with our explanation of what Docker does.
Kubernetes vs Docker: tools and container runtimes
Docker helps you build images and work with containers during development. Kubernetes manages workloads across a cluster. They're complementary tools, not interchangeable products; our Kubernetes vs Docker comparison explores that distinction.
On a Kubernetes node, the kubelet communicates with a container runtime through the Container Runtime Interface, or CRI. containerd and CRI-O are common CRI-compatible choices. CRI is the interface; containerd and CRI-O are implementations.
Kubernetes removed its built-in Docker Engine adapter, dockershim, in version 1.24. Docker-built images still work with compatible runtimes, but Docker Engine requires an external adapter such as cri-dockerd to act as a Kubernetes node runtime. The official dockershim FAQ explains what changed.
So where does Kubernetes come in?
Starting a container is only part of running an application. You also need to decide where it runs, maintain the required number of copies, replace failed instances, and give clients a stable way to reach them. Kubernetes provides resources and controllers for these jobs.
The Kubernetes cluster: control plane and worker nodes
A cluster contains a control plane and worker nodes. The control plane manages cluster state; worker nodes run application Pods. A node can be a physical machine or a VM.
- API server: Accepts requests to create, inspect, and change Kubernetes resources.
- Scheduler: Selects a suitable node for a Pod that hasn't been assigned one.
- Controllers: Watch resources and act to reconcile desired and observed state.
- Kubelet: The node agent that works with the runtime to keep assigned containers running as specified.
These components coordinate management decisions; application requests don't normally pass through the control plane.
Pods, Deployments, and desired state
A Pod is Kubernetes' smallest deployable unit. It contains one or more closely related containers that share networking and can share storage volumes. For a simple web application, one application container per Pod is a useful starting point.
A Deployment manages replicated application Pods through ReplicaSets. Instead of manually starting two containers, you declare a Deployment with two replicas and a Pod template describing the image and configuration.
These declarations are Kubernetes API objects, commonly written in YAML files called manifests. Controllers compare the requested state with the observed state and take corrective action. That continuing process is called reconciliation—not a one-time deployment script.
Kubernetes cluster
+----------------------------------------------------+
| Control plane: API server, scheduler, controllers |
| | assigns and manages Pods |
| v |
| Worker node A Worker node B |
| +------------------+ +------------------+ |
| | Pod: web replica | | Pod: web replica | |
| | kubelet + runtime| | kubelet + runtime| |
| +---------^--------+ +--------^---------+ |
| | | |
| +------ Service --------+ |
| ^ |
| application clients |
+----------------------------------------------------+This is one possible placement, not a guarantee that replicas land on different nodes. For a deeper walkthrough, read how Kubernetes works.
Services, service discovery, and external access
Pods are replaceable, so their addresses aren't a good permanent connection target. A typical Service selects Pods using labels and provides a stable cluster address; cluster DNS lets applications discover it by name. The cluster's networking implementation distributes connections to eligible endpoints.
A ClusterIP Service provides internal access, not an automatic public endpoint. A LoadBalancer Service needs a load-balancer implementation or cloud integration. Ingress and Gateway API resources describe application traffic routing and require a corresponding controller or implementation. These are separate layers, not features every Deployment receives automatically.
A minimal Kubernetes tutorial: Deployment and Service
Use a disposable learning cluster with Linux worker nodes, installed kubectl, and permission to create a namespace and workloads. Save this as web.yaml. It uses the official NGINX image to demonstrate a Deployment and an internal Service.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:stable-alpine
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 500m
memory: 128Mi
readinessProbe:
httpGet:
path: /
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: ClusterIP
selector:
app: web
ports:
- port: 80
targetPort: 80The Deployment and Service selectors match the Pod template's app: web label. The readiness probe checks whether NGINX can serve HTTP requests. Resource requests inform scheduling; 100m CPU means one tenth of a CPU unit, not a dedicated physical core.
Check that your active context points to the learning cluster before creating anything. Then create a namespace, apply the manifest, and inspect the result:
kubectl config current-context
kubectl create namespace k8s-intro
kubectl apply -n k8s-intro -f web.yaml
kubectl rollout status -n k8s-intro deployment/web --timeout=120s
kubectl get pods -n k8s-intro -l app=web
kubectl get service -n k8s-intro web
kubectl port-forward -n k8s-intro service/web 8080:80These commands create or update the declared resources, wait for the rollout, list the matching Pods and Service, and start local port forwarding.
While the final command is running, open http://localhost:8080 in your browser. Port forwarding selects a Pod through the Service; it doesn't test load distribution across both replicas or create a public load balancer. Stop it with Ctrl+C when you're done.
How Kubernetes handles recovery
“Self-healing” describes several mechanisms, not a guarantee of uninterrupted service:
- Container restart: The kubelet can restart a failed container within its existing Pod according to its restart policy.
- Health checks: A failing liveness probe can trigger a restart. A failing readiness probe stops the Pod from receiving normal Service traffic; it doesn't itself restart the container.
- Pod replacement: A workload controller can create a replacement for a lost Pod. The scheduler may place the replacement on another node; the original Pod isn't moved.
Recovery depends on available capacity, scheduling constraints, storage availability, and application behavior. Multiple replicas help, but availability also requires sensible placement and an application that tolerates instance loss.
Application scaling vs node scaling
Maintaining two replicas isn't autoscaling. A HorizontalPodAutoscaler, or HPA, changes the desired replica count using configured metrics and targets. For CPU-utilization-based scaling, it needs CPU requests on the relevant containers and a resource metrics source, commonly Metrics Server.
If your cluster provides resource metrics, save this optional example as web-hpa.yaml:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60kubectl apply -n k8s-intro -f web-hpa.yaml
kubectl get hpa -n k8s-intro webThis configures a range of two to five replicas with a target average CPU utilization of 60% of requested CPU—not 60% of the node's CPU. Once HPA manages scaling, avoid repeatedly reapplying a fixed Deployment replica count; that can overwrite its scaling decisions.
Node scaling is separate. A configured node autoscaler, such as Cluster Autoscaler, can add capacity for Pods that can't be scheduled. It needs provider integration and capacity constraints; it doesn't simply use the HPA's CPU metric. More Pods without enough node capacity can remain Pending.
Clean up the tutorial resources
After stopping port forwarding, delete only the namespace you created for this exercise. This removes its Deployment, Service, and optional HPA.
kubectl delete namespace k8s-introStorage, configuration, and secrets still need a plan
Starting containers doesn't make application data durable. A container's writable layer is ephemeral. PersistentVolumeClaims request persistent storage, backed by an available volume or a storage provisioner; access modes and storage capabilities still constrain where and how applications use it. Plan backups separately.
ConfigMaps hold non-confidential configuration. Secrets hold sensitive values such as credentials, but the object name isn't a security guarantee: base64 encoding isn't encryption, and upstream Kubernetes stores Secrets unencrypted at rest by default unless encryption is configured. Restrict access and verify your provider's encryption configuration.
Is Kubernetes free?
Kubernetes itself is free, open-source software. Operating a cluster isn't necessarily free: self-managed installations require infrastructure and engineering work, while managed services can add cluster-management or control-plane fees to compute, storage, networking, and load-balancer charges.
Check the current pricing for Amazon EKS, Google Kubernetes Engine, or Azure Kubernetes Service. Provider, product tier, region, and infrastructure choices affect the bill; there isn't one universal “Kubernetes price.”
Common Mistakes
- Choosing Kubernetes just to run a container: Start by asking whether your application needs cluster orchestration. A simpler deployment platform may fit your team better.
- Treating the demo as production configuration: Review image security, permissions, resource sizing, observability, backups, and failure handling before deploying real workloads.
- Expecting Kubernetes to fix application design: Test shutdown, retries, and state management under instance loss rather than assuming replica replacement makes requests reliable.
Kubernetes gives you orchestration building blocks, not a complete application platform with every operational decision made for you. Adopt it when that flexibility earns its maintenance cost.
FAQ
What is Kubernetes used for?
Kubernetes deploys and manages containerized workloads across a cluster. It provides resources for maintaining replicas, rolling out application changes, connecting workloads, and recovering from certain failures.
Is Kubernetes the same as Docker?
No. Docker helps you build images and run containers, while Kubernetes manages containerized workloads across a cluster. Docker-built images can still run on Kubernetes even though its built-in dockershim adapter was removed in version 1.24.
What is a Kubernetes Pod?
A Pod is Kubernetes' smallest deployable unit: one or more closely related containers sharing networking and potentially storage volumes. A Deployment commonly manages multiple replicated Pods for an application.
Does Kubernetes automatically scale applications?
Not just because you create a Deployment. Application autoscaling requires an HPA or another scaling mechanism with suitable metrics and configuration; adding worker-node capacity requires a separately configured node-scaling mechanism.
Is Kubernetes free?
Kubernetes is free, open-source software, but running a cluster has infrastructure and operational costs. Managed Kubernetes can also include cluster-management or control-plane charges, depending on the provider and product tier.
Further Reading
- Docker: What is a container? — Containers, VMs, and kernel sharing.
- Kubernetes components — Control-plane and worker-node responsibilities.
- Deployments — Replicas, updates, and workload management.
- Services — Stable access to changing workloads.
- Pod lifecycle — Container restarts and Pod replacement.
- Horizontal Pod Autoscaling — Metrics, targets, and replica ownership.
- Node autoscaling — Adding and consolidating cluster capacity.
- Kubernetes Secrets — Configuration and security considerations.
