Deployment Rolling Update and Rollback with Kubernetes
Using deployment rolling updates we can upgrade the image used by a deployment. The state of a deployment is saved which allows us to rollback to previous versions of a deployment.
Below is a simple example of a rolling update and undo operation (rollback) is explained.
1. First we create a new Deployment:
$ kubectl create deployment mynginx -image=nginx:1.16-alpinedeployment.extensions “mynginx” created
Now we can list the Deployment, the ReplicaSet and the Pod running nginx:1.16-alpine:
$ kubectl get deployments,replicasets,pods -l app=mynginxNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.extensions/mynginx 1 1 1 1 21mNAME DESIRED CURRENT READY AGE
replicaset.extensions/mynginx-75cd85c66f 1 1 1 21mNAME READY STATUS RESTARTS AGE
pod/mynginx-75cd85c66f-9mww7 1/1 Running 0 21m
2. There is only one pod running NGINX. We can increase the number of replicas to three using the scale command:
$ kubectl scale deployment mynginx — replicas=3deployment.extensions “mynginx” scaled
There should be three pods running NGINX:
$ kubectl get pods -l app=mynginxNAME READY STATUS RESTARTS AGE
mynginx-75cd85c66f-6cvmt 1/1 Running 0 2m
mynginx-75cd85c66f-9mww7 1/1 Running 0 49m
mynginx-75cd85c66f-jhblc 1/1 Running 0 2m
The desired attribute of the associated ReplicaSet is now 3:
$ kubectl get replicasets -l app=mynginxNAME DESIRED CURRENT READY AGE
mynginx-75cd85c66f 3 3 3 50m
To see more details about the Deployment, we can use the describe command:
$ kubectl describe deployment mynginxName: mynginx
Namespace: default
CreationTimestamp: Wed, 02 Oct 2019 23:40:20 +0200
Labels: app=mynginx
Annotations: deployment.kubernetes.io/revision=1
Selector: app=mynginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=mynginx
Containers:
nginx:
Image: nginx:1.16-alpine
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: mynginx-75cd85c66f (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 55m deployment-controller Scaled up replica set mynginx-75cd85c66f to 1
Normal ScalingReplicaSet 8m deployment-controller Scaled up replica set mynginx-75cd85c66f to 3
Rollout history shows the list of revisions:
$ kubectl rollout history deployment mynginxdeployments “mynginx”
REVISION CHANGE-CAUSE
1 <none>
Currently we have only one Deployment. To get details about the deployment, we provide the revision number:
$ kubectl rollout history deployment mynginx --revision=1deployments "mynginx" with revision #1
Pod Template:
Labels: app=mynginx
pod-template-hash=75cd85c66f
Containers:
nginx:
Image: nginx:1.16-alpine
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
3. To demonstrate a rolling update we upgrade the image to nginx:1.17-alpine.
$ kubectl set image deployment mynginx nginx=nginx:1.17-alpinedeployment.apps "mynginx" image updated
The image is now updated. If we check the rollout history, we will see that we have two revisions:
kubectl rollout history deployment mynginxdeployments "mynginx"
REVISION CHANGE-CAUSE
1 <none>
2 <none>
If we check the details of the revision 2, we should see the new image number (nginx:1.17-alpine):
$ kubectl rollout history deployment mynginx --revision=2deployments "mynginx" with revision #2
Pod Template:
Labels: app=mynginx
pod-template-hash=58c6fb8c76
Containers:
nginx:
Image: nginx:1.17-alpine
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Let’s look at our objects:
$ kubectl get deployments,replicasets,pods -l app=mynginxNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.../mynginx 3 3 3 3 23hNAME DESIRED CURRENT READY AGE
replicaset.../mynginx-58c6fb8c76 3 3 3 7m
replicaset.../mynginx-75cd85c66f 0 0 0 23hNAME READY STATUS RESTARTS AGE
pod/mynginx-58c6fb8c76-d225h 1/1 Running 0 7m
pod/mynginx-58c6fb8c76-kt4fz 1/1 Running 0 7m
pod/mynginx-58c6fb8c76-w86jz 1/1 Running 0 7m
We have three pods running NGINX. The initial ReplicaSet (75cd85c66f) is not running and is scaled down to zero. New ReplicaSet (58c6fb8c76) is running with three pods with the image nginx:1.17-alpine.
4. We can everytime rollback to revision one. Lets try…
$ kubectl rollout undo deployment mynginx --to-revision=1deployment.apps "mynginx"
Now the rollback was successful. The second ReplicaSet (58c6fb8c76) is now scaled down to zero and the first ReplicaSet with old image version 1.16 is scaled up to three pods.
$ kubectl get deployments,replicasets,pods -l app=mynginxNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.../mynginx 3 3 3 3 1dNAME DESIRED CURRENT READY AGE
replicaset.../mynginx-58c6fb8c76 0 0 0 42m
replicaset.../mynginx-75cd85c66f 3 3 3 1dNAME READY STATUS RESTARTS AGE
pod/mynginx-75cd85c66f-blmqw 1/1 Running 0 19s
pod/mynginx-75cd85c66f-lcsbz 1/1 Running 0 20s
pod/mynginx-75cd85c66f-w4fng 1/1 Running 0 20s
The rollout history is now changed:
$ kubectl rollout history deployment mynginxdeployments "mynginx"
REVISION CHANGE-CAUSE
2 <none>
3 <none>
Revision #1 is not available, it is now became the revision #3.