Rolling Updates and Rollbacks
In this tutorial we will discuss about rolling updates and rollbacks in Kubernetes deployment.
Before we discuss at how we upgrade our application, lets try to understand rollout and versioning in a deployment.
When we first create a deployment, it triggers a rollout. A new rollout creates a new deployment revision. Lets call it as revision 1.
In the future, when the application is upgraded meaning when the container version is updated to a new one. A new rollout is triggered and new deployment revision is created named version 2.
This helps us keep track of the changes made to our deployment and enables us to roll back to a previous version of deployment if necessary.
We can see the status of our rollout by using following command
$ kubectl rollout status deployment/myapp-deployment
To check the revisions and history of rollout, you can use following command
$ kubectl rollout history deployment/myapp-deployment
The above command will show you the revisions and history of the deployment.
There are 2 types of deployment strategies. Say for example you have 5 replicas of your web application instance deployed.
One way to upgrade these to a newer version is to destroy all of these and then create newer versions of application instances. This means First destroy the 5 running instances and then deploy 5 new instances of the new application version.
The problem with this, as you can imagine is that during the period after the older versions are down and before any newer version is up. The application is down and inaccessible to users. This strategy is known as the recreate strategy and thankfully this is not the default strategy.
The second strategy is where we did not destroy all of them at once. Instead we take down the older version and bring up a newer version one by one. This way the application never goes down and the upgrade is seamless.
If you don’t specify a strategy while creating the deployment it will assume it to be rolling update. In other words rolling update is the default deployment strategy.
So how exactly do we update our deployment. When we say update, it could be different things such as updating our application version by updating the version of docker containers used, updating their labels or updating the number of replicas etc.
Since we have already have a deployment definition file it is easy for us to modify this file. Once we make the necessary changes, we run the following command to apply the changes.
$ kubectl apply -f deployment-definition.yaml
Once we run the above command, a new rollout is triggered and a new revision after deployment is created.
But there is another way to do the same thing. You could use the following command to update the image of your application.
$ kubectl set image deployment/myapp-deployment nginx=nginx:1.7.1
But remember doing it this way will result in the deployment definition file having a different configuration. So you must be careful when using the same definition file to make changes in the future.
The difference between the recreate and rolling update strategies can also be seen when you view the deployments in detail by running the following command.
$ kubectl describe deployment myapp-deployment
You will notice when the recreate strategy was used, the events indicate that the old replica set was scaled down to zero first and then the new replica sets scaled up to 5.
However when the rolling update strategy was used the old replica set was scaled down one at a time, simultaneously scaling up the new replica set one at a time.
Lets look at how a deployment performs an upgrade. When a new deployment is created say to deploy 5 replicas, it first creates a ReplicaSet automatically, which in turn creates a ReplicaSet automatically, which in turn creates the number of PODs required to meet the number of replicas.
When you upgrade your application, the Kubernetes deployment object creates a new replicaset under the hood and starts deploying the containers there.
At the same time, taking down the PODs in the old replica set following a rolling update strategy.
This can be seen when you try to list the replicasets using the following command.
$ kubectl get replicasets NAME DESIRED CURRENT READY AGE myapp-deployment-6874c6gd 0 0 0 35m myapp-deployment-8e57cbd8 5 5 5 15m
Here we see the old replicaset with 0 PODs and the new replicaset with 5 PODs.
Say for instance, once you upgrade your application you realize something is inferior right. Something is wrong with the new version of the build when you used to upgrade.
So you would like to roll back your update. Kubernetes deployments allow you to roll back to a previous revision. To undo a change, run the following command.
$ kubectl rollout undo deployment/myapp-deployment
Once you run the above command, the deployment will then destroy the PODs in the new replicaset and bring the older ones in the old replicaset. And your application is back to its older format.
When you compare the output of the kubectl get replicasets command, before and after the rollback, you will be able to notice this difference.