How to roll back a Kubernetes Deployment

A failed Kubernetes Deployment rollout can leave new Pods unavailable while older Pods still carry part of the service. Rolling back returns the Deployment pod template to an earlier ReplicaSet revision so the controller can replace the failed release path with the last working template.

kubectl rollout undo uses the revision history kept by the Deployment controller. A normal undo targets the previous revision, while --to-revision targets a specific revision when history shows that the known-good template is not the immediately previous one.

The rollback changes the Deployment pod template, but it does not undo database migrations, persistent-volume writes, ConfigMap or Secret changes, or external traffic routing made outside the Deployment object. Confirm the target revision and run the application health check before treating service recovery as complete.

Steps to roll back a Kubernetes Deployment:

  1. Check the current Deployment rollout status.
    $ kubectl rollout status deployment/web --namespace app --timeout=30s
    Waiting for deployment "web" rollout to finish: 1 out of 2 new replicas have been updated...
    error: timed out waiting for the condition

    Use a short timeout during incident triage so the shell returns when the new ReplicaSet cannot become available.

  2. List the Deployment revision history.
    $ kubectl rollout history deployment/web --namespace app
    deployment.apps/web 
    REVISION  CHANGE-CAUSE
    1         <none>
    2         <none>

    If CHANGE-CAUSE is empty, use revision details, image tags, deployment records, and recent change notes to identify the intended rollback target.

  3. Inspect the known-good revision before undoing the rollout.
    $ kubectl rollout history deployment/web --namespace app --revision=1
    deployment.apps/web with revision #1
    Pod Template:
      Labels:	app=web
    	pod-template-hash=768666cfcc
      Containers:
       nginx:
        Image:	nginx:1.27-alpine
        Port:	80/TCP
    ##### snipped #####

    Replace 1 with the revision that should be restored. Use a specific revision only after confirming that its pod template matches the last working release.

  4. Roll back the Deployment to the previous revision.
    $ kubectl rollout undo deployment/web --namespace app
    deployment.apps/web rolled back

    Add --to-revision=1 when the target is not the immediately previous revision.

  5. Wait for the rollback rollout to finish.
    $ kubectl rollout status deployment/web --namespace app --timeout=180s
    Waiting for deployment "web" rollout to finish: 1 old replicas are pending termination...
    deployment "web" successfully rolled out
  6. Confirm that the Deployment returned to the expected image and availability.
    $ kubectl describe deployment web --namespace app
    Name:                   web
    Namespace:              app
    Annotations:            deployment.kubernetes.io/revision: 3
    Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
    ##### snipped #####
    Pod Template:
      Labels:  app=web
      Containers:
       nginx:
        Image:         nginx:1.27-alpine
    ##### snipped #####
    OldReplicaSets:  web-86b4c64596 (0/0 replicas created)
    NewReplicaSet:   web-768666cfcc (2/2 replicas created)

    A rollback creates a new Deployment revision, so the revision number can change even when the pod template matches the earlier working revision.

  7. Run the application smoke check against the rolled-back Pods.
    $ kubectl exec deployment/web --namespace app -- nginx -v
    nginx version: nginx/1.27.5

    Use the normal health endpoint, synthetic transaction, or log check for the application instead of nginx -v when the container is not an Nginx image.