Rolling updates & rollbacks in Deployments (Kubernetes)

The important aspects of deployments are: Upgrade, Rollout, Rollback.
Upgrade: The ability to deploy latest major version and shut older version(s).
Rollout: The ability to deploy lates minor version (bugfix, hotfix, minor feature, enhancement) without downtime.
Rollback: The ability to restore back the older working version in case something goes wrong.
Here is what happens in the world of K8s:
- When we first create a deployment, it creates a rollout.
- A new rollout creates a new revision.
- In the future, when a new deployment (of same name) is triggered, a new rollout is created with increased version.
- This helps us keeps track of changes made and enables us to rollback to previous version deployment.
- To check status of rollout: `kubectl rollout status deployment <deployment-name>`
- To check the history, revision and change-cause of rollout: `kubectl rollout history deployment <deployment name>`
Deployment strategy #1 -> Recreate:
- Suppose there are 5 instances of your app running
- When deploying a new version, we can destroy the 5 instances of older version and then deploy 5 instances of newer version.
- The issue is there will be a downtime.
- This is majorly done during major changes, breaking changes or when backward compatibility is not possible.
- This is not the default strategy in K8s.
Deployment strategy #2 -> Rolling update:
- In this strategy, we do not drop all the already running instances.
- We drop instances by a certain percentage at a time and simultaneously spawn equal percentage of newer version pods.
- This upgrade is the default strategy in K8s.
- This has no downtime.
Lets understand with an example:
- Suppose there is an already existing deployment running 3 replicas of a pod with image nginx:1.7.0.
- Now you wish to change the version of the image.
- This can be done by changing the version of the image in deployment file and running the command: `kubectl apply -f <deployment file path>`
- The above can also be done by: `kubectl set image deployment myapp-deployment nginx=nginx.1.7.1`.
- Remember, if we do step #4, then there will be inconsistency in the actual file and the deployment definition in the cluster
- Run command: `kubectl describe deployment <deployment name>` to see the details of deployment, and notice the difference in both strategies.
How upgrades work under the hood:
- When a deployment is applied, it creates a replica-set and spins up pods with number of instances as mentioned in the deployment configuration.
- Then, when the deployment is re-applied with changes, it creates a new replica-set and spins up pods with number of instances as mentioned in the deployment configuration and drops pod simultaneously from older replica-set.
- But the thing to note is, the older replica-set still exists, which will be used for rollback if required.
- To rollback a deployment: `kubeclt rollout undo deployment <deployment name>` — this will also run in the similar sequence as it happened while upgrade.
- After rollback the new replicaset still persists.
- Remember in order to see change cause of historical revisions, we need to add — record flag while editing/applying deployments (needs to be set once per deployment)
- When we do a rollback, the revision to which the rollback happens is removed from history and a new entry is made in the history instead.
- If any error occurs during upgrade, kubernetes will proactively stop the upgrade and stop dropping previously running instances