Building a resilient deployment on Kubernetes-part 3: Keep the deployment up to date with the latest releases
I have been writing a series of articles on how to build a resilient deployment on Kubernetes.
In my previous articles, I covered the followings which are essential to a resilient deployment in Kubernetes. Please have a look at the summarize section in each article to get the gist of the things what I have talked about.
Part 1: Minimum Application Downtime
Part 2: Resources and Capacity Planning
In this article, I will be covering why the update is important, what are the things you should consider in an update process and how Kubernetes helps us to make the update process easier.
Why updating software is important?
When a bug or an improvement is identified in software, the developers include the fixes and the improvements in the next major release or patch releases to make the product stable. Hence, having these continuous upgrades in your deployment help to make it more stable and robust. Because of this, the clients who are engaging with the deployment will less likely to have a negative experience.
Updating Process
In general, due to the complexities in the updating process, the developers are less likely to be doing updates continuously. Because you have to think about a lot of the factors in an update process. Let’s look at a few of these factors as an example.
- Finding a maintenance window
When many clients are engaging with an application, you have to make sure that they are impacted at the minimum. Hence when you are doing any changes in a live deployment, it’s always a best practice to figure out a maintenance window.
2. Figure out the rollout strategy
Rollout strategy means how you plan to update the existing application. This strategy includes how many pods should be updated at a time, how many pods can be afforded to unavailable in a system at a given time during the update process, updating all at once or updating one by one etc.
3. Figure out the rollback strategy
Rollback means how you plan to revert back to a previous stable version in a case of a failure in updating process or a bug in the existing deployment.
For example, let’s say you have continuously updated an app multiple times and it passed initial testings. But when it’s in the production ,the app has a performance issue which wasn’t there in the previous version. Management instructs you to switch to the previous version as soon as possible. How can you easily switch to the previous version? What if you want to switch to a version before a few updates. How can you find the revision?
Each and every point we discussed above are crucial when a deployment is being updated continuously.
Update Application in Kubernetes
Kubernetes deployments, statefulSets and replicaSet and daemonSet have the capability to make the updating process smooth in Kubernetes cluster.
I will not discuss each Kubernetes resources. But I will take deployment as an example and explain so that you can follow the same with other kinds of aforementioned Kubernetes resources as well.
Let’s have a look update strategies related to the above Kubernetes resources.
updateStrategy
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
- The
updateStrategy
located within the spec section in each of the above Kubernetes resources.( spec section in deployment or replicationSet or statefulSet etc.) - This can be two approaches.
(i) Rolling update
- Rolling update ensures that the updating process happens such that both the existing version and the updating version co-exists until the update process successfully complete.
- To make sure this, RollingUpdate provides two options.
(a) maxSurge (Optional)
- maxSurge defines how many pods in deployment should be updated with the latest image at a given time during the updating process.
- This can be defined as a percentage or as a numeric value.
- Eg: maxSurge = 3 -> When you are updating, new 3 pods will be created and deployed with the new image. If this is a percentage (25%), then 25% (rounded up) of
desired pods
will be created and deployed with the new image. - Default value is 25%.
(b) maxUnvailable (Optional)
- maxUnavailable defined the number of pods that can be afforded to unavailable during the update process.
- This can be defined as a percentage or as a numeric value.
- Eg: maxUnavailable = 2-> When you are updating, once the pods with new image are created, the number of pods equal to
maxUnavailable
will be removed from the deployment. If this is a percentage (25%), then 25%(rounded up) ofdesired pods
will be removed. - Default value is 25%.
(ii). Recreate
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
strategy:
type: Recreate
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Recreate strategy allows the users to destroy the pods and create all the pods at the same time. This imposes an application downtime as the pods are destroyed all at once.
If you are in your local development environment, this is ideal as it is faster than rolling update
process.
Update Process
(i) Updating the image
- Using the imperative way, you can update the deployment using a single
kubectl
command. Here you have to specify the deployment name and the container name along with the updated image as shown below.
kubectl set image deployment <deployment-name> <container-name>:<image-name>
- If you have multiple containers inside a pod, you can choose the container name that you want to update using the above command.
(ii) Status Check
- The history of the updating process can be checked using the below command.
kubectl rollout history deployment <name of the deployment>
- At this point, if you are using rollingUpdate strategy, the update process will adhere to the maxSurge and the maxUnavailable properties.
- If you are using recreate strategy, then all the pods in the deployment will be updated with the new application.
What if something goes wrong:
In either of the above scenarios, you can use the following command to undo the updating process.
kubectl rollout undo deployment <deployment-name>
If you want to revert back to a revision, use the --to-revision=<revision-number>
For example:kubectl rollout undo deployment/nginx-deployment --to-revision=2
Summary
In this article, we discussed how important the update process is and how Kubernetes makes it easier.
Two update strategies:
(i) Rolling update: maxSurge and maxUnavailable to define the new pods and deleting pods. This allows no application downtime as both older and new version co-exist during the process.
(ii) Recreate: Application downtime is expected. Destroyed and recreate all at once.