Hello! Let's continue our journey through Kubernetes.
In our last lesson, we saw how to use a Deployment to run and scale a stateless application, ensuring a specific number of Pods are always available. This solved the problems of availability and basic scalability. But in the real world of platform engineering, applications are never static; they evolve constantly.
This brings us to a critical question: how do you update a running application to a new version without causing downtime for your users? Today's lesson will answer that by diving into one of the most powerful features of Kubernetes Deployments. We will focus on how to perform rolling updates to deploy new versions of your application seamlessly and how to perform rollbacks to quickly revert to a stable state if something goes wrong. This is a core competency for any DevOps or Platform Engineer.
1. The Rolling Update Strategy
When you update a Deployment, you don't want to terminate all old Pods at once and then create new ones. That would cause an outage. Instead, Kubernetes uses a rolling update strategy by default. This strategy gradually replaces old Pods with new ones, ensuring the application remains available throughout the process.
This process is controlled by two key parameters in your Deployment's manifest, under spec.strategy.rollingUpdate:
maxUnavailable: The maximum number of Pods that can be unavailable during the update. This can be an absolute number (e.g.,1) or a percentage of the total replicas (e.g.,25%). A lower value ensures higher availability.maxSurge: The maximum number of Pods that can be created above the desired number of replicas. This can also be an absolute number or a percentage. This allows Kubernetes to bring up new Pods before taking down old ones, speeding up the update.
The following video provides a clear, concise explanation of how these two parameters work together to orchestrate a zero-downtime deployment.
Most Common Kubernetes Deployment Strategies (Examples & Code)
Let's start with a clear visual explanation from Anton Putra on the default rolling update strategy and the roles of maxUnavailable and maxSurge.
Watch from 01:36 to 03:42. Focus on how Kubernetes uses the default 25% for both parameters to gradually roll out a new version without interrupting service.
As the video explains, if you have 4 replicas and the default settings (maxUnavailable: 25%, maxSurge: 25%), Kubernetes will:
- Ensure no more than 1 Pod (
25%of 4) is unavailable at any time. - Allow the creation of at most 1 new Pod (
25%of 4) above the desired replica count of 4, for a temporary total of 5 Pods.
The process typically looks like this:
- A new Pod with the new image version is created (total Pods: 5).
- Kubernetes waits for the new Pod to become
Ready(this is where readiness probes are critical!). - Once the new Pod is ready, an old Pod is terminated (total Pods: 4).
- This cycle repeats until all Pods are running the new version.
A visual comparison of the Recreate strategy (left), which causes downtime, and the Rolling Update strategy (right), which maintains availability by incrementally replacing Pods. This diagram is from the KodeKloud article "Rolling Updates Rollbacks", which we will refer to later.
2. Performing a Rolling Update
Now, let's trigger an update. The most common ways are:
- Declarative (Recommended): Modify the
imagetag in your Deployment YAML file and apply it withkubectl apply -f your-deployment.yaml. This aligns with GitOps principles, where your Git repository is the source of truth. - Imperative (Quick & Easy): Use the
kubectl set imagecommand. This is great for quick changes or scripting.
Let's focus on the imperative command for now. If you have the nginx-deployment from the previous lesson, you can update its container's image like this:
# First, check the current image of your pods
kubectl describe deployment nginx-deployment | grep Image
# Now, trigger the update to a new version
kubectl set image deployment/nginx-deployment nginx=nginx:1.23.3
As soon as you run this command, the Deployment controller starts the rolling update process.
Kubernetes Deployments: A Guide to the Rolling Update ...
This article from Semaphore provides a detailed walkthrough of the entire update process, from configuration to execution and monitoring.
Read the section 'Performing a Rolling Update'. It demonstrates how to use kubectl set image to trigger the update and how to use kubectl get pods to observe the Pods being terminated and created. Also, pay close attention to the kubectl rollout status and kubectl rollout history commands, which are essential for monitoring.
Monitoring the Rollout
While the update is in progress, you can monitor it in real-time. Open a new terminal and run:
kubectl rollout status deployment/nginx-deployment
You'll see messages indicating the progress, like "Waiting for rollout to finish: 2 of 3 new replicas have been updated...".
You can also use the --watch flag to see the Pods cycling through their states:
kubectl get pods -l app=nginx --watch
You will see old Pods Terminating and new Pods ContainerCreating, then Running.
3. Handling Failed Updates and Rolling Back
What happens if you accidentally push a bad image tag, like nginx:1.99.9 (which doesn't exist)? The rolling update will start, create a new Pod, but that Pod will fail to pull the image and get stuck in an ImagePullBackOff state.
Because the new Pod never becomes Ready, Kubernetes is smart enough to halt the rollout. Your application remains available, running on the remaining old Pods, but the deployment is in a broken, partially-updated state.
This is where rollbacks become your safety net.
Checking Deployment History
Kubernetes keeps a history of each change you make to a Deployment. You can view this history with:
kubectl rollout history deployment/nginx-deployment
This will show you a list of "revisions". Each time you update the Deployment's template (e.g., change the image), a new revision is created.
Performing a Rollback
If you detect an issue with your latest deployment (revision), you can immediately revert to the previous stable revision with a single command:
kubectl rollout undo deployment/nginx-deployment
This command triggers another rolling update, but this time the "new" version is the configuration from the previous revision. The process is identical: old (broken) Pods are gradually replaced by new (working) Pods.
The following video demonstrates a full cycle: updating, seeing the rollout, and then using undo to roll back.
Most Common Kubernetes Deployment Strategies (Examples & Code)
Let's watch a practical demonstration that includes not just the update, but also the crucial undo command for rollbacks.
Watch the segment from 06:17 to 07:53. The presenter first triggers an update, then demonstrates using kubectl rollout pause, resume, and finally undo to revert the deployment to its previous version.
You can also roll back to a specific, older revision if needed. For example, if you know revision 2 was the last stable one:
kubectl rollout undo deployment/nginx-deployment --to-revision=2
Test your understanding!
You have deployed a new version of your application. Your monitoring system starts firing alerts, and you suspect the new code is buggy. You check the rollout history and see the following:
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deployment/webapp webapp=app:v1.1 --record
3 kubectl set image deployment/webapp webapp=app:v1.2 --record
You are currently on revision 3, which is faulty. You want to go back to the last known stable version, v1.1. What command should you run?
Show answer
You should run the command:kubectl rollout undo deployment/webapp --to-revision=2
While kubectl rollout undo deployment/webapp would also work in this case (as it rolls back to the previous revision, which is 2), explicitly specifying --to-revision=2 is more precise and safer, especially if there were intermediate failed rollouts. The CHANGE-CAUSE column, populated by the --record flag, helps you identify which revision corresponds to which version tag.
Conclusion
You now have the tools to manage the complete lifecycle of a stateless application in Kubernetes. By leveraging rolling updates, you can deploy changes with confidence, knowing that your application will remain available. And with rollbacks, you have a powerful safety mechanism to quickly recover from failed deployments.
Key Takeaways:
- Rolling Updates are the default strategy for Deployments, ensuring zero downtime by gradually replacing Pods.
- The rollout process is fine-tuned using
maxSurgeandmaxUnavailable. - Updates are triggered declaratively with
kubectl applyor imperatively withkubectl set image. - You can monitor a rollout with
kubectl rollout statusand view past changes withkubectl rollout history. - If a new version is faulty, you can instantly revert to the previous stable version using
kubectl rollout undo. - Kubernetes automatically halts a rollout if new Pods fail to become
Ready, preventing a complete outage.
In our last few lessons, we've focused on running the application itself. But applications need configuration—database URLs, API keys, feature flags, etc. Hardcoding these into your container image is a bad practice. In our next lesson, we will explore ConfigMaps and Secrets, the Kubernetes-native way to manage application configuration and sensitive data.