Rolling Updates and Rollbacks in Kubernetes
One of the benefits of using a Deployment is the ability to perform rolling updates and create a rollingupdatestrategy. Rolling updates allow us to update the configuration of the pods gradually.
An update strategy (k8s rollingupdate, k8s update strategy) is the most important option to configure rolling updates. In the Deployment definition, spec.strategy.type has two possible values:
- RollingUpdate: New pods are added gradually and the old pods are terminated gradually.
- Recreate: All old pods are terminated at once before any new pods are added.
There are 2 more options while updating the deployment using RollingUpdate.
- maxSurge: The number of pods that can be created above the desired number of pods during an update.
- maxUnavailable: The number of pods that can be unavailable during the update process.
Using deployment rolling updates we can upgrade the image used by a deployment. The state of deployment (kubectl rollout status) is saved which allows us to roll back to any previous versions of the deployment.
When an application fails due to an incorrect image or the deployment is unstable, we may want to rollback the Deployment (k8s rollback). By default, all of the Deployment's rollout history is kept in the system that can be used later to rollback in case of unstable deployment. We can use this history to rollback anytime we want.
To know more about Rolling update and Rollback, visit the Kubernetes' official documentation here.
In this article, we will update the deployment with the default Rolling update strategy and rollback the deployment. To rollback the deployment, we will use the incorrect image in one of the updates to the deployment.
Pre-requisites
- Kubernetes Cluster with at least 1 worker node.
If you want to learn to create a Kubernetes Cluster, click here. This guide will help you create a Kubernetes cluster with 1 Master and 2 Nodes on AWS Ubuntu 18.04 EC2 Instances.
What will we do?
- Rolling Update and Rollback
Rolling update and Rollback
Create a deployment definition file for Nginx with deployment's pod template. In this, we have specified Nginx version as "nginx:1.14.2".
vim my-deployment.yml
apiVersion: apps/v1 kind: Deployment metadata: name: rolling-update-demo labels: app: nginx spec: replicas: 4 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
Let's check for existing pods and create a deployment.
kubectl get pods
kubectl create -f my-deployment.yml
Get the details of the deployment we just created. This deployment created 4 pods and controlled by the replicaset.
kubectl get deployments
kubectl get pods
kubectl get replicaset
In the above screenshot, you can see that we have 1 deployment under which we have 1 replicaset and 4 pods controlled by the replicaset.
Now, let's change the Nginx version from "nginx:1.14.2" to "nginx:1.61.1"
vim my-deployment.yml
Apply the change to the deployment and get details of the pods, replicaset and deployment.
kubectl apply -f my-deployment.yml
kubectl get pods
kubectl get deployments
kubectl get replicaset
In the above screenshot, it can be seen that a new replicaset has been created and has 4 pods under it. But we still see the older replicaset with 0 pods.
Now, if we again change the Nginx version but this time we give a wrong Nginx Version, the deployment will fail as the Nginx Image does not exist for the wrong version.
vim my-deployment.yml
Let's apply the change to the deployment.
kubectl apply -f my-deployment.yml
kubectl get pods
kubectl get deployments
Now, let's try to get replicaset details.
kubectl get replicaset
In the above screenshot, it can be seen that the new Pods are failing with "ErrImagePull" error. The pods are failing as the Nginx Image does not exist for version "ngin:1.1.1".
Now, if we want to go back to the previous working images we can rollback to a previous revision if the rollout status is not ok.
To rollback, we can first get rollout history of the deployment rollout of the deployments using the following command.
kubectl rollout history deployments rolling-update-demo
Now, using the following command with "--revision=2" we can check the details of the deployment we have in "--revision=2"
kubectl rollout history deployments rolling-update-demo --revision=2
In the above screenshot, you can see that the revision-2 has Nginx Image version "nginx:1.16.1" which was working before we updated our deployment with Nginx version "ngin:1.1.1" which failed.
Now, let's rollback the deployment to the last revision we have before the current failed deployment.
kubectl get deployments
kubectl rollout undo deployment rolling-update-demo
kubectl get pods
kubectl get replicaset
In the above screenshot, you can see that we have reverted back the latest deployment and now we have a deployment revision which was working before the last update.
To know more about the deployment, it can be described using the following command.
kubectl get deployments
kubectl describe deployment rolling-update-demo
Conclusion
In this article, we saw the steps to create a deployment and update it. We saw how a deployment can be rolled back if it fails due to some reason, here the error we saw for the failed deployment was "ErrImagePull". We saw how deployment keeps its revision to which it can be rolled back in case we do not want to keep the latest updates in the deployment.