Skip to main content

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.

  1. ReplicaSet Creation: Kubernetes creates a ReplicaSet to manage the Pods defined in the Deployment.

    The settings/config for the ReplicaSet from the deployment.yaml file is:

    replicas: 1
    selector:
    matchLabels:
    app: nginx

    Let's check the ReplicaSets.

    kubectl get replicasets

    vagrant@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-labels

    vagrant@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

    note

    kubectl get replicasets is same as kubectl 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 label app:nginx on them.

    warning

    Do not manage ReplicaSets owned by a Deployment. The Deployment may not work as expected.

  2. 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.yaml file is:

    template:
    metadata:
    labels:
    app: nginx
    spec:
    containers:
    - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

    Let's see the Pods created by this deployment along with the labels (--show-labels):

    kubectl get pods --show-labels

    vagrant@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 label app:nginx applied to it. This is how the ReplicaSet manages/monitors the pods that are part of the deployment.

  3. Pod Management: The ReplicaSet continuously monitors the Pods and ensures that the desired number of replicas are running.

  4. 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 to nginx:1.16.1. We can edit the deployment.yaml manifest file and then running kubectl apply -f deployment.yaml or 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.1

    vagrant@vagrant:~$ kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 deployment.apps/nginx-deployment image updated

    Alternatively, you can edit the deployment by:

    kubectl edit deployment nginx-deployment

    This will open the Deployment as a YAML manifest file where you can edit the image tag and update the file.

    To see how the change is rolling out,

    kubectl rollout status deployment/nginx-deployment

    vagrant@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 pods

    vagrant@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-qjw8g is created.

    If you look at the pod name carefully, the pod-template-hash has been changed to 59796869f5. This is because when you update the Deployment's Pod template, a new ReplicaSet will be created.

    kubectl get replicasets

    vagrant@vagrant:~$ kubectl get replicasets NAME DESIRED CURRENT READY AGE nginx-deployment-59796869f5 1 1 1 10m

  5. 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-qjw8g

    vagrant@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 output

    vagrant@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.

  6. Scaling: You can scale the Deployment up or down by changing the number of replicas, and Kubernetes will adjust the number of Pods accordingly.

  7. 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.

  8. 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.

  9. 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.