Deployment - Under the Hood
In the previous tutorial, we saw how to create a Deployment using a YAML file. Now, let's see what happens behind the scenes when a Deployment is created.
When you create a Deployment, Kubernetes performs several actions to ensure that the desired state of your application is achieved.
-
ReplicaSet Creation: Kubernetes creates a ReplicaSet to manage the Pods defined in the Deployment.
The settings/config for the ReplicaSet from the
deployment.yamlfile is:replicas: 1selector:matchLabels:app: nginxLet's check the ReplicaSets.
kubectl get replicasetsvagrant@vagrant:~$ kubectl get replicasets NAME DESIRED CURRENT READY AGE nginx-deployment-77bc6bd484 1 1 1 4h16m
Observe that the name of the ReplicaSet is of the format
[DEPLOYMENT-NAME]-[HASH]. This[HASH]is also applied as a label to the ReplicaSet.kubectl get rs --show-labelsvagrant@vagrant:~$ kubectl get rs --show-labels NAME DESIRED CURRENT READY AGE LABELS nginx-deployment-77bc6bd484 1 1 1 4h22m app=nginx,pod-template-hash=77bc6bd484
notekubectl get replicasetsis same askubectl get rs. It is the short form.How does the ReplicaSet know which Pods it needs to manage?
The answer is the label
app:nginx. If you observe, the label is passed to the ReplicaSet at.spec.selector.matchLabels. Meaning, manage the Pods that have the labelapp:nginxon them.warningDo not manage ReplicaSets owned by a Deployment. The Deployment may not work as expected.
-
Pod Creation: The ReplicaSet creates the specified number of Pods based on the template defined in the Deployment.
The settings/config for the Pods from the
deployment.yamlfile is:template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80Let's see the Pods created by this deployment along with the labels (--show-labels):
kubectl get pods --show-labelsvagrant@vagrant:~$ kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-77bc6bd484-qvsr2 1/1 Running 1 (23m ago) 3h30m app=nginx,pod-template-hash=77bc6bd484
The naming format of the Pods follow
[DEPLOYMENT-NAME]-[HASH]-[5 RANDOM HEX CHARS]. Look closely that the Pod has the same labelapp:nginxapplied to it. This is how the ReplicaSet manages/monitors the pods that are part of the deployment. -
Pod Management: The ReplicaSet continuously monitors the Pods and ensures that the desired number of replicas are running.
-
Rolling Updates: If you update the Deployment, Kubernetes will perform a rolling update to ensure that the application remains available during the update process.
Currently our deployment is running
nginx:1.14.2. Let's update tonginx:1.16.1. We can edit thedeployment.yamlmanifest file and then runningkubectl apply -f deployment.yamlor perform this update via imperative commands. Let's do this with the command, so that we learn different ways.kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1vagrant@vagrant:~$ kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 deployment.apps/nginx-deployment image updated
Alternatively, you can
editthe deployment by:kubectl edit deployment nginx-deploymentThis will open the Deployment as a YAML manifest file where you can edit the
imagetag and update the file.To see how the change is rolling out,
kubectl rollout status deployment/nginx-deploymentvagrant@vagrant:~/kubernetes-tutorial$ kubectl rollout status deploy/nginx-deployment 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... 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 out
Let's see the pods now
kubectl get podsvagrant@vagrant:~/kubernetes-tutorial$ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-59796869f5-qjw8g 1/1 Running 0 3m
We can see that a new pod
nginx-deployment-59796869f5-qjw8gis created.If you look at the pod name carefully, the
pod-template-hashhas been changed to 59796869f5. This is because when you update the Deployment's Pod template, a new ReplicaSet will be created.kubectl get replicasetsvagrant@vagrant:~$ kubectl get replicasets NAME DESIRED CURRENT READY AGE nginx-deployment-59796869f5 1 1 1 10m
-
Self-Healing: If a Pod becomes unhealthy or fails, Kubernetes will automatically replace it to maintain the desired state of the application.
Let's delete the existing Pod and see if the new Pod gets created.
kubectl delete pod nginx-deployment-59796869f5-qjw8gvagrant@vagrant:~/kubernetes-tutorial$ kubectl delete pod nginx-deployment-59796869f5-qjw8g pod "nginx-deployment-59796869f5-qjw8g" deleted
kubectl get pods -w # -w option to watch the command's outputvagrant@vagrant:~/kubernetes-tutorial$ kubectl get pods -w NAME READY STATUS RESTARTS AGE nginx-deployment-59796869f5-p9dc4 0/1 ContainerCreating 0 5s nginx-deployment-59796869f5-p9dc4 1/1 Running 0 7s
See a new Pod is getting created.
-
Scaling: You can scale the Deployment up or down by changing the number of replicas, and Kubernetes will adjust the number of Pods accordingly.
-
Rollback: If something goes wrong during an update, you can roll back to a previous version of the Deployment, and Kubernetes will restore the previous state of the application.
-
Status Monitoring: Kubernetes provides status information about the Deployment, including the number of available replicas, the number of unavailable replicas, and the overall health of the Deployment.
-
Event Logging: Kubernetes logs events related to the Deployment, such as Pod creation, scaling actions, and updates, which can be useful for troubleshooting and monitoring the application.
Overall, a Deployment provides a powerful and flexible way to manage the lifecycle of your application in Kubernetes, ensuring that it remains available, scalable, and resilient.