Deployments: Scaling, Self-Healing, and Rolling Updates
Run replicas of a Pod, update them without downtime, and roll back when a release goes wrong.
Pods are disposable, and a bare Pod that dies stays dead. A Deployment fixes that: you declare how many copies you want and which image to run, and Kubernetes keeps that many running and handles updates for you. This guide covers creating one, scaling it, updating it without downtime, and rolling it back.
Why you rarely create bare Pods
If a node fails or a Pod is deleted, nothing recreates a standalone Pod. In practice you almost never create Pods directly. You create a Deployment, which creates a ReplicaSet, which in turn creates and maintains the Pods. The Deployment adds what the ReplicaSet lacks: controlled updates and version history.
Write a Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
There are two metadata sections, and it helps to keep them straight. The top one describes the Deployment. The one under template describes the Pods it creates, and the template is simply a Pod manifest without a name. The selector tells the Deployment which Pods belong to it, so it must match the labels in the template, or Kubernetes will reject the manifest.
kubectl apply -f deployment.yaml
kubectl get deployment,replicaset,pods
You’ll see one Deployment, one ReplicaSet named after it plus a hash, and three Pods named after the ReplicaSet.
Labels and selectors: how objects find each other
Labels are key-value pairs you can attach to any object. Selectors query them, and this is how Kubernetes connects things: a Deployment finds its Pods, a Service finds its backends, and a network policy finds the Pods it governs.
kubectl get pods --show-labels
kubectl get pods -l app=web
To see how much a selector matters, remove the label from one Pod:
kubectl label pod POD_NAME app-
kubectl get pods --show-labels
The ReplicaSet no longer counts that Pod as one of its own, so it starts a replacement to get back to three. The relabeled Pod keeps running, but nothing manages it. Delete it with kubectl delete pod POD_NAME so it doesn’t linger.
Scale and watch self-healing
kubectl scale deployment web --replicas=5
kubectl get pods -w
In another terminal, delete a Pod and watch a replacement appear within moments. To change the replica count for good, edit replicas in the manifest and apply it again, since kubectl scale alone leaves your file out of date. You cannot get rid of a Deployment’s Pods by deleting them, because they keep coming back. Delete the Deployment itself, or scale it to zero.
Roll out a new version
Changing anything in the Pod template, such as the image, triggers a rolling update:
kubectl set image deployment/web nginx=nginx:1.26
kubectl rollout status deployment/web
The Deployment creates a second ReplicaSet for the new version, then gradually scales it up while scaling the old one down, so some Pods are always serving traffic. By default it allows up to 25% extra Pods (maxSurge) and up to 25% unavailable (maxUnavailable) during the change. You can tune this in the spec:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
With maxUnavailable: 0, an old Pod is only removed once a new one is ready. What “ready” means is decided by readiness probes, covered in a later guide. Changing the replica count is not a rollout, because it doesn’t touch the Pod template.
Roll back
Kubernetes keeps the old ReplicaSets, which is what makes rollback quick:
kubectl rollout history deployment/web
kubectl rollout undo deployment/web
kubectl rollout undo deployment/web --to-revision=1
undo returns to the previous revision, and --to-revision picks a specific one. The number of old revisions kept is set by revisionHistoryLimit, 10 by default. One caution: if your manifests live in Git and something like Argo CD applies them, prefer reverting the commit over rollout undo. The undo changes the cluster but not Git, so the two disagree until someone reconciles them.
Popular Guides
-
What Kubernetes Is and the Problems It Solves Why containers alone stop scaling, and how Kubernetes turns a group of machines into one platform. -
How a Kubernetes Cluster Works: Control Plane and Nodes The components that make a cluster tick, and what happens between kubectl apply and a running container. -
Services: Stable Networking for Ephemeral Pods Give Pods a stable address, expose them inside and outside the cluster, and restrict who can talk to whom. -
Debug a Failing Pod: describe, logs, exec, and port-forward A repeatable checklist for finding out why a Pod is Pending, crashing, or not answering.