Kubernetes Deployments Rolling Updates and Rollbacks

A Deployment is the most commonly used resource in Kubernetes. It manages ReplicaSets, which manage Pods. On top of that, it gives you two critical capabilities: rolling updates to release new versions without downtime, and rollbacks to undo a bad release instantly.

What a Deployment Does

Think of a Deployment as the production manager of a factory floor. The manager keeps the right number of workers (Pods) active at all times. When the factory upgrades to a new production process (new image version), the manager replaces workers one batch at a time — never shutting everyone down simultaneously, so the factory keeps producing throughout the transition.

Deployment (Manager)
     └── ReplicaSet v1 (old) ── [Pod] [Pod] [Pod]
     └── ReplicaSet v2 (new) ── [Pod] [Pod] [Pod]

During update: old ReplicaSet shrinks, new one grows
After update: old ReplicaSet has 0 Pods (kept for rollback)

Writing a Deployment YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app-container
        image: my-app:v1.0
        ports:
        - containerPort: 8080

The strategy section controls how updates roll out. maxSurge: 1 means at most 1 extra Pod can exist above the desired count during the update. maxUnavailable: 1 means at most 1 Pod can be missing during the update.

Deploying and Checking Status

kubectl apply -f deployment.yaml
kubectl get deployments
kubectl rollout status deployment/my-app

Output:

Waiting for deployment "my-app" rollout to finish:
1 out of 3 new replicas have been updated...
2 out of 3 new replicas have been updated...
deployment "my-app" successfully rolled out

Rolling Updates: Zero-Downtime Releases

When you update the container image, Kubernetes does not kill all old Pods at once. It replaces them gradually — one or a few at a time — while keeping the rest running. Traffic continues to flow to the healthy old Pods while the new ones start up and pass their readiness probes.

Start:  [v1] [v1] [v1]  ← 3 old Pods
Step 1: [v1] [v1] [v2]  ← 1 new Pod started, 1 old remains for now
Step 2: [v1] [v2] [v2]  ← 2 new Pods running
Step 3: [v2] [v2] [v2]  ← Update complete, 0 downtime

To trigger a rolling update, change the image version and re-apply:

kubectl set image deployment/my-app app-container=my-app:v2.0

Or update the YAML file and run kubectl apply again.

Rollbacks: Undoing a Bad Release

Kubernetes keeps a history of previous ReplicaSets. If the new version has a bug, you roll back to the previous version with one command:

kubectl rollout undo deployment/my-app

This reverts to the immediately previous version. To roll back to a specific revision:

kubectl rollout history deployment/my-app        # List revision history
kubectl rollout undo deployment/my-app --to-revision=2

Rollback works just like a forward update — it replaces Pods gradually, keeping the app available throughout.

Pausing and Resuming a Rollout

You can pause a rollout midway — useful for canary-style testing where you want to check the new version on a small subset of Pods before continuing:

kubectl rollout pause deployment/my-app
# Check the new Pods, run tests
kubectl rollout resume deployment/my-app

Deployment Strategies Explained

RollingUpdate (Default)

Pods are replaced gradually. The app stays available. Use this for stateless web services where any Pod can handle any request.

Recreate

All old Pods are terminated first, then new Pods start. There is a brief downtime window. Use this only when old and new versions cannot run at the same time — for example, when a database schema change makes the old app version incompatible with the new schema.

strategy:
  type: Recreate

Useful Deployment Commands

CommandWhat It Does
kubectl get deploymentsList all Deployments and their Pod counts
kubectl describe deployment my-appFull details including events
kubectl rollout status deployment/my-appWatch the update progress
kubectl rollout history deployment/my-appSee all past revisions
kubectl scale deployment my-app --replicas=5Scale to 5 replicas
kubectl rollout undo deployment/my-appRoll back one version

Annotations for Deployment History

Add a change-cause annotation to every update so rollout history is readable:

kubectl annotate deployment/my-app kubernetes.io/change-cause="Deploy v2.0 with login fix"

Now rollout history shows a meaningful description next to each revision, making it easy to pick the correct revision during rollback.

Key Points

  • A Deployment manages ReplicaSets and adds rolling update and rollback capabilities.
  • Rolling updates replace Pods one at a time so your app stays available during releases.
  • maxSurge and maxUnavailable control the speed and safety of the rollout.
  • kubectl rollout undo reverts to the previous version in seconds.
  • Use the Recreate strategy only when old and new versions cannot coexist.

Leave a Comment