Update a Deployment Without Downtime

This page shows how to update a running Deployment to a new version using a rolling update. A rolling update gradually replaces old Pods with new ones, so your application remains available throughout the process.

Objectives

  • Trigger a rolling update on a Deployment.
  • Monitor rollout progress.
  • Pause and resume the rollout.
  • Configure rolling update strategy parameters.
  • (If required) Roll back to a previous revision.

Before you begin

You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:

You need an existing Deployment. If you do not have one, create the nginx Deployment from Run a Stateless Application Using a Deployment:

kubectl apply -f https://k8s.io/examples/application/deployment.yaml

Verify the Deployment runs two Pods:

kubectl get deployment nginx-deployment

The output is similar to:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           10s

Performing a rolling update

Any change to the .spec.template field of a Deployment triggers a rolling update. Kubernetes creates new Pods with the updated configuration and gradually terminates old Pods.

Updating with kubectl apply

You can trigger a rolling update by editing the Deployment manifest and applying the change. This approach works well when you keep manifests in version control.

Export the current Deployment to a local file:

kubectl get deployment nginx-deployment -o yaml > /tmp/nginx-deployment.yaml

Edit /tmp/nginx-deployment.yaml and change .spec.template.spec.containers[0].image from nginx:1.14.2 to nginx:1.16.1.

Before applying, compare your local changes against the cluster state:

kubectl diff -f /tmp/nginx-deployment.yaml

The output is similar to:

diff -u -N /tmp/LIVE/apps.v1.Deployment.default.nginx-deployment /tmp/MERGED/apps.v1.Deployment.default.nginx-deployment
--- /tmp/LIVE/apps.v1.Deployment...
+++ /tmp/MERGED/apps.v1.Deployment...
@@ -29,7 +29,7 @@
       containers:
-      - image: nginx:1.14.2
+      - image: nginx:1.16.1
         name: nginx

Apply the updated manifest:

kubectl apply -f /tmp/nginx-deployment.yaml

Updating only the container image

To update the container image without editing a manifest file, use kubectl set image:

kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1

The output is similar to:

deployment.apps/nginx-deployment image updated

Verify the image was updated:

kubectl get deployment nginx-deployment -o jsonpath='{.spec.template.spec.containers[0].image}'

The output is similar to:

nginx:1.16.1

Monitoring rollout progress

Use kubectl rollout status to watch the progress of a rolling update:

kubectl rollout status deployment/nginx-deployment

The output is similar to:

Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out

After the rollout completes, verify the Deployment:

kubectl get deployment nginx-deployment

The output is similar to:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           2m

Pausing and resuming a rollout

You can pause a rollout to inspect a partial update or to batch multiple changes into a single rollout.

Pausing a rollout

kubectl rollout pause deployment/nginx-deployment

The output is similar to:

deployment.apps/nginx-deployment paused

Making additional changes while paused

While the rollout is paused, you can make additional changes. These changes do not trigger a new rollout until you resume:

kubectl set image deployment/nginx-deployment nginx=nginx:1.17.0

Note:

You can make multiple changes to a paused Deployment. Kubernetes applies all changes together when you resume the rollout.

Resuming a rollout

kubectl rollout resume deployment/nginx-deployment

The output is similar to:

deployment.apps/nginx-deployment resumed

Verify the rollout completes:

kubectl rollout status deployment/nginx-deployment

Configuring rolling update strategy

Deployments support two update strategy types:

  • RollingUpdate (default): gradually replaces old Pods with new ones.
  • Recreate: terminates all existing Pods before creating new ones. This causes downtime.

For the RollingUpdate strategy, these parameters control how Kubernetes performs the update:

ParameterControlsDefaultExample
maxUnavailableMaximum number of Pods that can be unavailable during the update25%1 or 25%
maxSurgeMaximum number of extra Pods that can be created during the update25%1 or 25%

Note:

maxUnavailable and maxSurge accept an absolute number or a percentage. Kubernetes calculates percentages from the desired replica count, rounding down for maxUnavailable and rounding up for maxSurge.

To configure these parameters, use kubectl patch:

kubectl patch deployment nginx-deployment -p \
  '{"spec":{"strategy":{"rollingUpdate":{"maxUnavailable":"25%","maxSurge":"25%"}}}}'

You can also set these fields in a Deployment manifest under .spec.strategy.rollingUpdate. For detailed examples, see max unavailable and max surge in the Deployment concepts documentation.

Detecting a stalled rollout

If a rollout does not make progress within the time specified by .spec.progressDeadlineSeconds (default: 600 seconds), Kubernetes marks the Deployment condition Progressing as False. You can check for this condition by describing the Deployment:

kubectl describe deployment nginx-deployment

Look for the Progressing condition in the Conditions section of the output. A stalled rollout usually indicates that new Pods are failing to start. The Events section of the output can help diagnose the issue.

Rolling back to a previous revision

If a new version introduces issues, you can roll back to a previous revision.

Viewing rollout history

kubectl rollout history deployment/nginx-deployment

The output is similar to:

deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

Note:

The CHANGE-CAUSE column shows the value of the kubernetes.io/change-cause annotation at the time of each revision. This annotation is not set automatically, but if you are using an automated solution to manage Deployments, the tool you use may write some text into that annotation.

Rolling back to the previous revision

kubectl rollout undo deployment/nginx-deployment

The output is similar to:

deployment.apps/nginx-deployment rolled back

Rolling back to a specific revision

kubectl rollout undo deployment/nginx-deployment --to-revision=1

Verify the rollback completes:

kubectl rollout status deployment/nginx-deployment

Note:

A Deployment's revision history is stored in the ReplicaSets it controls. By default, Kubernetes retains 10 old ReplicaSets. You can change this limit by setting .spec.revisionHistoryLimit in the Deployment manifest. Setting it to 0 disables rollback entirely.

Cleaning up

Delete the Deployment:

kubectl delete deployment nginx-deployment

What's next


Last modified March 15, 2026 at 6:56 PM PST: Add task page: Update a Deployment Without Downtime (3610f32b0e)