Deployment Rollouts
In this session we will see how to do deployment rollouts and rollbacks
In this session we will see how to do deployment rollouts and rollbacks
The following are typical use cases for Deployments:
$ vi nginx-deployment.yamlapiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80$ kubectl create -f nginx-deployment.yamlOutput
deployment.apps/nginx-deployment created$ kubectl get allOutput
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-76bf4969df-c7jrz 1/1 Running 0 38s --+
pod/nginx-deployment-76bf4969df-gl5cv 1/1 Running 0 38s |-----> These Pods are spawned by ReplicaSet nginx-deployment-76bf4969df
pod/nginx-deployment-76bf4969df-kgmx9 1/1 Running 0 38s --+
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 172.168.0.1 <none> 443/TCP 3d23h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 3/3 3 3 38s ---------> Deployment
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-76bf4969df 3 3 3 38s ---> ReplicaSetAs we already know , Deployment controller uses labels to select the Pods In Yaml spec , you can see below selector fields.
selector:
matchLabels:
app: nginxLets examine the Pods. We can see that there are two labels. The pod-template-hash label is added by the Deployment controller to every ReplicaSet that a Deployment creates or adopts.
$ kubectl get pods --show-labelsOutput
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-76bf4969df-hm5hf 1/1 Running 0 3m44s app=nginx,pod-template-hash=76bf4969df
nginx-deployment-76bf4969df-tqn2k 1/1 Running 0 3m44s app=nginx,pod-template-hash=76bf4969df
nginx-deployment-76bf4969df-wjmqp 1/1 Running 0 3m44s app=nginx,pod-template-hash=76bf4969dfYou may see the parameters of a replicaset using below command.
$ kubectl get replicasets nginx-deployment-76bf4969df -o yaml --exportWe can update the nginx image to a new version using set image.
Here we are executing both set image and rollout status together so that we can monitor the status.
$ kubectl set image deployment nginx-deployment nginx=nginx:1.9.1 ; kubectl rollout status deployment nginx-deploymentOutput
deployment.extensions/nginx-deployment image updated
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled outTo view the history of rollout
$ kubectl rollout history deployment nginx-deploymentOutput
deployment.extensions/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>To see the changes we made on each version, we can use below commands
$ kubectl rollout history deployment nginx-deployment --revision=1First revision have image nginx:1.7.9
deployment.extensions/nginx-deployment with revision #1
Pod Template:
Labels: app=nginx
pod-template-hash=76bf4969df
Containers:
nginx:
Image: nginx:1.7.9
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>First revision have image nginx:1.9.1
$ kubectl rollout history deployment nginx-deployment --revision=2deployment.extensions/nginx-deployment with revision #2
Pod Template:
Labels: app=nginx
pod-template-hash=779fcd779f
Containers:
nginx:
Image: nginx:1.9.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>Now lets rollback the update.
$ kubectl rollout undo deployment nginx-deployment ;kubectl rollout status deployment nginx-deploymentOutput
deployment.extensions/nginx-deployment rolled back
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled outNow we have revision 2 and 3.
When we rollback version 1 become 3 . In this way the latest active one and the previous revision will be the highest and second highest revisions respectively. This logic will allow quick rollbacks.
$ kubectl rollout history deployment nginx-deploymentdeployment.extensions/nginx-deployment
REVISION CHANGE-CAUSE
2 <none>
3 <none>Check each revision changes
$ kubectl rollout history deployment nginx-deployment --revision=2deployment.extensions/nginx-deployment with revision #2
Pod Template:
Labels: app=nginx
pod-template-hash=779fcd779f
Containers:
nginx:
Image: nginx:1.9.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>$ kubectl rollout history deployment nginx-deployment --revision=3deployment.extensions/nginx-deployment with revision #3
Pod Template:
Labels: app=nginx
pod-template-hash=76bf4969df
Containers:
nginx:
Image: nginx:1.7.9
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>Lets check the status of replicaset
$ kubectl get rsNAME DESIRED CURRENT READY AGE
nginx-deployment-76bf4969df 3 3 3 145m
nginx-deployment-779fcd779f 0 0 0 69mHere we can see two replicaset
$ kubectl describe rs nginx-deployment-76bf4969dfName: nginx-deployment-76bf4969df
Namespace: default
Selector: app=nginx,pod-template-hash=76bf4969df
Labels: app=nginx
pod-template-hash=76bf4969df
Annotations: deployment.kubernetes.io/desired-replicas: 3
deployment.kubernetes.io/max-replicas: 4
deployment.kubernetes.io/revision: 3
deployment.kubernetes.io/revision-history: 1
Controlled By: Deployment/nginx-deployment
Replicas: 3 current / 3 desired <<<<<<<<<<<<<<-------------------------
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=nginx
pod-template-hash=76bf4969df
Containers:
nginx:
Image: nginx:1.7.9 <<<<<<<<<<<<<<-------------------------
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Events: <none>$ kubectl describe rs nginx-deployment-779fcd779fName: nginx-deployment-779fcd779f
Namespace: default
Selector: app=nginx,pod-template-hash=779fcd779f
Labels: app=nginx
pod-template-hash=779fcd779f
Annotations: deployment.kubernetes.io/desired-replicas: 3
deployment.kubernetes.io/max-replicas: 4
deployment.kubernetes.io/revision: 2
Controlled By: Deployment/nginx-deployment
Replicas: 0 current / 0 desired <<<<<<<<<<<<<<-------------------------
Pods Status: 0 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=nginx
pod-template-hash=779fcd779f
Containers:
nginx:
Image: nginx:1.9.1 <<<<<<<<<<<<<<-------------------------
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Events: <none>We can pause and resume a rollout using below commands
$ kubectl rollout pause deployment nginx-deployment$ kubectl rollout resume deployment nginx-deploymentWe can use revisionHistoryLimit field in a Deployment to specify how many old ReplicaSets for this Deployment you want to retain. The rest will be garbage-collected in the background. By default, it is 10
We can read more about strategy here