In-depth understanding of Deployments in Kubernetes
When running apps on Kubernetes, most of you must have used Deployments to manage ReplicaSet and Pods. However, it’s hard to say that we’ve used Deployments effectively, and yet in this post, I am going to cover some valuable features that Deployments itself provide.
Topics:
- Pausing and Resuming Deployments
- Proportional scaling
- Rolling back to the previous version
- Clean up Policy
- Canary Deployments
1. Pausing and Resuming Deployments
This feature is useful when you use a command line to update deployment directly instead of using yml file, and you don’t want to trigger unnecessary rollout while updating multiple properties of Deployment.
You can use a command line kubectl rollout pause to pause a Deployment.
kubectl rollout pause deployment/backend
You should be able to see a similar output after executing the above command
Now try updating a new image version of our backend app
kubectl set image deployment/backend node-app=10.80.80.148:5000/node-app:0.0.15
Check rollout history
kubectl rollout history deployment/backend
Notice that there is no rollout that has been made after we updated a new image version.
Therefore, we can continuously update as many resources as we like. Then to resume it back we can use a command kubectl rollout resume
kubectl rollout resume deployment/backend
2. Proportional Scaling
With proportional scaling, you can have the ability to run multiple versions of the app at the same time. This helps guarantee the stability of the new app before completely replacing the old version.
To support proportional scaling, you need to set .spec.strategy.type=RollingUpdate.
There are 2 types of strategy; one is RollingUpdate and another one is Recreate. By using the strategy type Recreate, it will stop all existing pods or replicas before creating a new version.
Rolling Update Deployment supports 2 extra properties: maxUnavailable and maxSurge.
.spec.strategy.rollingUpdate.maxUnavailable specifies the number of pods that can be unavailable during the rolling-out update. The value can be an absolute number or percentage.
.spec.strategy.rollingUpdate.maxSurge specifies the total number of pods that can exceed the desired replicas. The value can be an absolute number or percentage.
For instance, assuming that have a Deployment running with 3 replicas and you set maxSurge=3 and maxUnavailable=2.
Now, I am trying to set a non-existing image.
kubectl set image deployment/backend node-app=10.80.80.148:5000/node-app:unknown-tag
Then, run kubectl get rs to see how many ReplicaSet has been created.
We can see that it has just created a new ReplicaSet with the maxSurge number and scaled-down old ReplicaSet to 1 since the unAvailable number is 2. However, in this example, I have set an unavailable image to our Deployment, so it old ReplicaSet will not scale to 0 until a new ReplicaSet is ready.
3. Rolling back to the previous version
Sometimes when you successfully deployed the app to production, but it contained a critical bug or is not stable enough, then you probably want to go back to the previous stable version. By using Kubernetes Deployment, it offers you the ability to fall back to any version that you wish.
Deployment use .spec.revisionHistoryLimit to store the number of history of the ReplicaSets, so you can roll back to any version that has been stored within the specified range. By default, it is set to 10 which means 10 old ReplicaSet will be kept, but you can customize it based on your own needs.
I have set .spec.revisionHistoryLimit=1, so there will be 1 old Replicaset kept.
To go back to a previous version before the current running one you can use kubectl rollout undo deployment_name
kubectl rollout undo deployment/backend
It will output like this
In case, you want to roll back to any other versions, you can check the deployment history first to get a revision number.
kubectl rollout history deployment/backend
Since I have only set .spec.revisionHistoryLimit to 1 so I can set it to revision number 20, but if you have more you can set it to any number.
kubectl rollout history deployment/backend --revision=20
Output is similar here
I think this post is long enough, so I am going to keep 2 more topics for the part 2 post. Thanks for reading.