Deployment Rolling Update and Rollback with Kubernetes

Ilyas Keser
4 min readOct 3, 2019

--

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 21m
NAME DESIRED CURRENT READY AGE
replicaset.extensions/mynginx-75cd85c66f 1 1 1 21m
NAME 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 23h
NAME DESIRED CURRENT READY AGE
replicaset.../mynginx-58c6fb8c76 3 3 3 7m
replicaset.../mynginx-75cd85c66f 0 0 0 23h
NAME 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 1d
NAME DESIRED CURRENT READY AGE
replicaset.../mynginx-58c6fb8c76 0 0 0 42m
replicaset.../mynginx-75cd85c66f 3 3 3 1d
NAME 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.

--

--

Ilyas Keser

This is my notebook for snippets. Freelancer/Software Engineer, Hanover/Germany, Interests: AWS, Spring Framework, Java, REST/HTTP