DEV Community

Saravanan Gnanaguru
Saravanan Gnanaguru

Posted on • Edited on

Kubernetes Learning Part III: K8s Workload Resources - Deployment and ReplicaSet

Table of Contents

Introduction

  • This article is part-III of Kubernetes Learning Series
  • Since we are going to discuss concepts, this article is theoretical and TLDR in nature :-)
  • Please do checkout the Kubernetes Learning Series for other parts in the series

K8s Workload Resources

Kubernetes provides several built-in workload resources:

  • Deployment and ReplicaSet (replacing the legacy resource ReplicationController). Deployment is a good fit for managing a stateless application workload on your cluster, where any Pod in the Deployment is interchangeable and can be replaced if needed.
  • StatefulSet lets you run one or more related Pods that do track state somehow. For example, if your workload records data persistently, you can run a StatefulSet that matches each Pod with a PersistentVolume. Your code, running in the Pods for that StatefulSet, can replicate data to other Pods in the same StatefulSet to improve overall resilience.
  • DaemonSet defines Pods that provide node-local facilities. These might be fundamental to the operation of your cluster, such as a networking helper tool, or be part of an add-on. Every time you add a node to your cluster that matches the specification in a DaemonSet, the control plane schedules a Pod for that DaemonSet onto the new node.
  • Job and CronJob define tasks that run to completion and then stop. Jobs represent one-off tasks, whereas CronJobs recur according to a schedule.

  • In this article, we will see about managing the Deployment and Replica set and the behaviour when updating the deployments

Kubernetes Object Management

  • When we talk about creating Kubernetes manifest definition, it is important to know about 3 types of object management

  • kubectl tool supports three kinds of object management:

  • Imperative commands :

    • When using imperative commands, a user operates directly on live objects in a cluster. The user provides operations to the kubectl command as arguments or flags.
    • This is the recommended way to get started or to run a one-off task in a cluster. Because this technique operates directly on live objects, it provides no history of previous configurations.
kubectl create deployment nginx --image nginx 
Enter fullscreen mode Exit fullscreen mode
  • Imperative object configuration :
    • In imperative object configuration, the kubectl command specifies the operation (create, replace, etc.), optional flags and at least one file name. The file specified must contain a full definition of the object in YAML or JSON format.
kubectl create -f nginx.yaml 
Enter fullscreen mode Exit fullscreen mode

Also, we can use kubectl edit , kubectl delete and kubectl replace in this method of object configuration

  • Declarative object configuration :
    • When using declarative object configuration, a user operates on object configuration files stored locally, however the user does not define the operations to be taken on the files.
    • Create, update, and delete operations are automatically detected per-object by kubectl.
    • This enables working on directories, where different operations might be needed for different objects.

Deployments

  • A Deployment provides declarative updates for Pods and ReplicaSets.
  • We can describe a desired state in a Deployment, and the Deployment Controller changes the actual state to the desired state.
  • Deployments can be used to create new ReplicaSets, or to remove existing Deployments and adopt all their resources with new Deployments.
  • Example of a Deployment. It creates a ReplicaSet to bring up 3 nginx Pods:
  • Create a deployment manifest and save it as deployment.yml
apiVersion: 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.21-alpine ports: - containerPort: 80 resources: limits: memory: "128Mi" cpu: "500m" 
Enter fullscreen mode Exit fullscreen mode

In this example:

  • A Deployment named nginx-deployment is created, indicated by the .metadata.name field.

  • The Deployment creates 3 replicated Pods, indicated by the .spec.replicas field.

  • The .spec.selector field defines how the Deployment finds which Pods to manage. In this case, you select a label that is defined in the Pod template (app: nginx).

  • The template field contains the following sub-fields:

    • The Pods are labeled app: nginx using the .metadata.labels field.
    • The Pod template's specification, or .template.spec field, indicates that the Pods run one nginx container, which runs the nginx Docker Hub image at version 1.21-alpine.
  • Create one container and name it nginx using the .spec.template.spec.containers[0].name field.

Creating a Deployment

  • Now let us try out different kubectl commands to learn about the k8s deployment workload resource
  • Run minikube start to kick start the local k8s cluster

  • Use kubectl apply -f to execute the deployment manifest

#:~/github/learning2021/kubernetes$ kubectl apply -f deployment.yml deployment.apps/nginx-deployment created 
Enter fullscreen mode Exit fullscreen mode
  • Use kubectl get deployments command to list out the deployments manifest
#:~/github/learning2021/kubernetes$ kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 76s 
Enter fullscreen mode Exit fullscreen mode
  • Our manifest definition has 3 replicas of nginx pod defined in it.
  • List the pods using the command kubectl get po
#:~/github/learning2021/kubernetes$ kubectl get po NAME READY STATUS RESTARTS AGE nginx-deployment-c7768ddc9-6cxtc 1/1 Running 0 80s nginx-deployment-c7768ddc9-g7v7c 1/1 Running 0 80s nginx-deployment-c7768ddc9-hcj4s 1/1 Running 0 80s 
Enter fullscreen mode Exit fullscreen mode
  • Replica Sets can be viewed using the command kubectl get rs
#:~/github/learning2021/kubernetes$ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-c7768ddc9 3 3 3 101s 
Enter fullscreen mode Exit fullscreen mode
  • Now let us describe the deployment we just created.
  • Use the command kubectl describe
#:~/github/learning2021/kubernetes$ kubectl describe deployment nginx-deployment Name: nginx-deployment Namespace: default CreationTimestamp: Thu, 01 Oct 2021 12:27:22 +0530 Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=nginx Containers: nginx: Image: nginx:1.21-alpine Port: 80/TCP Host Port: 0/TCP Limits: cpu: 500m memory: 128Mi Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: nginx-deployment-c7768ddc9 (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 2m8s deployment-controller Scaled up replica set nginx-deployment-c7768ddc9 to 3 
Enter fullscreen mode Exit fullscreen mode

Replica Set

  • Purpose of the ReplicaSet is to maintain a stable set of replica Pods running at any given time.
  • As such, it is often used to guarantee the availability of a specified number of identical Pods.

  • It is recommended to use replica-set within deployment definition. Becuase a Deployment is a higher-level concept that manages ReplicaSets and provides declarative updates to Pods along with a lot of other useful features.

  • Replica set has been mentioned using the spec.replicas value in our deployment definition

  • We will now see, what happens when we update the deployment and what is the role of replica set while updating the deployments

Updating the deployment

  • We will now change the nginx image id from 1.21-alpine to 1.21
  • We will imperatively update the deployment definition using kubectl edit command
#:~/github/learning2021/kubernetes$ kubectl edit deployment/nginx-deployment deployment.apps/nginx-deployment edited 
Enter fullscreen mode Exit fullscreen mode
  • We have updated the deployment which already has running pods
  • So let us check the deployment status using kubectl rollout command
#:~/github/learning2021/kubernetes$ kubectl rollout status deployment/nginx-deployment deployment "nginx-deployment" successfully rolled out 
Enter fullscreen mode Exit fullscreen mode
  • Once the rollout is complete, we will check the status of pods and deployment using kubectl describe command
#:~/github/learning2021/kubernetes$ kubectl describe deployment nginx-deployment Name: nginx-deployment Namespace: default CreationTimestamp: Thu, 16 Sep 2021 12:27:22 +0530 Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 2 Selector: app=nginx Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=nginx Containers: nginx: Image: nginx:1.21 Port: 80/TCP Host Port: 0/TCP Limits: cpu: 500m memory: 128Mi Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: nginx-deployment-6f88dfb7c7 (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 7m45s deployment-controller Scaled up replica set nginx-deployment-c7768ddc9 to 3 Normal ScalingReplicaSet 52s deployment-controller Scaled up replica set nginx-deployment-6f88dfb7c7 to 1 Normal ScalingReplicaSet 39s deployment-controller Scaled down replica set nginx-deployment-c7768ddc9 to 2 Normal ScalingReplicaSet 39s deployment-controller Scaled up replica set nginx-deployment-6f88dfb7c7 to 2 Normal ScalingReplicaSet 38s deployment-controller Scaled down replica set nginx-deployment-c7768ddc9 to 1 Normal ScalingReplicaSet 38s deployment-controller Scaled up replica set nginx-deployment-6f88dfb7c7 to 3 Normal ScalingReplicaSet 37s deployment-controller Scaled down replica set nginx-deployment-c7768ddc9 to 0 
Enter fullscreen mode Exit fullscreen mode
  • Now let us keenly observe the behaviour of deployment and replicas described above,
    • Deployment ensures that only a certain number of Pods are down while they are being updated. By default, it ensures that at least 75% of the desired number of Pods are up (25% max unavailable).
    • Deployment also ensures that only a certain number of Pods are created above the desired number of Pods. By default, it ensures that at most 125% of the desired number of Pods are up (25% max surge).
    • Here you see that when you first created the Deployment, it created a ReplicaSet (nginx-deployment-2035384211) and scaled it up to 3 replicas directly.
    • When you updated the Deployment, it created a new ReplicaSet (nginx-deployment-1564180365) and scaled it up to 1 and then scaled down the old ReplicaSet to 2, so that at least 2 Pods were available and at most 4 Pods were created at all times.
    • It then continued scaling up and down the new and the old ReplicaSet, with the same rolling update strategy. Finally, you'll have 3 available replicas in the new ReplicaSet, and the old ReplicaSet is scaled down to 0.

Spec Selector Behaviour of Replica Set

  • Each time when a new Deployment is observed by the Deployment controller, a ReplicaSet is created to bring up the desired Pods.
  • Once If the Deployment is updated, the existing ReplicaSet that controls Pods whose labels match .spec.selector but whose template does not match .spec.template are scaled down.
  • Eventually, the new ReplicaSet is scaled to .spec.replicas and all old ReplicaSets is scaled to 0.
#:~/github/learning2021/kubernetes$ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-6f88dfb7c7 3 3 3 69s nginx-deployment-c7768ddc9 0 0 0 8m2s #:~/github/learning2021/kubernetes$ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-6f88dfb7c7-25z2c 1/1 Running 0 106s nginx-deployment-6f88dfb7c7-m7hst 1/1 Running 0 119s nginx-deployment-6f88dfb7c7-zrbc2 1/1 Running 0 105s #:~/github/learning2021/kubernetes$ kubectl describe pod nginx-deployment-6f88dfb7c7-25z2c Name: nginx-deployment-6f88dfb7c7-25z2c Namespace: default Priority: 0 Node: minikube/192.168.49.2 Start Time: Thu, 16 Sep 2021 12:34:28 +0530 Labels: app=nginx pod-template-hash=6f88dfb7c7 Annotations: <none> Status: Running IP: 172.17.0.5 IPs: IP: 172.17.0.5 Controlled By: ReplicaSet/nginx-deployment-6f88dfb7c7 Containers: nginx: Container ID: docker://9fd85eb81263d16bc73752a1275c35d6cdc0eb3074734d0820bd327eb39b30b2 Image: nginx:1.21 Image ID: docker-pullable://nginx@sha256:853b221d3341add7aaadf5f81dd088ea943ab9c918766e295321294b035f3f3e Port: 80/TCP Host Port: 0/TCP State: Running Started: Thu, 16 Sep 2021 12:34:29 +0530 Ready: True Restart Count: 0 Limits: cpu: 500m memory: 128Mi Requests: cpu: 500m memory: 128Mi Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-4b8m4 (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-4b8m4: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: Guaranteed Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m18s default-scheduler Successfully assigned default/nginx-deployment-6f88dfb7c7-25z2c to minikube Normal Pulled 2m18s kubelet Container image "nginx:1.21" already present on machine Normal Created 2m18s kubelet Created container nginx Normal Started 2m18s kubelet Started container nginx 
Enter fullscreen mode Exit fullscreen mode

Conclusion

  • In this blog we have seen the concepts of deployment and replica set and their behaviour
  • In next blog we will see about stateful sets

Bibliography

workloads
Deployment
ReplicaSet

Top comments (0)