Goglides Dev 🌱

Cover image for Deployment Object in Kubernetes. Why Deployment object over ReplicaSet?
Niraj Pradhan
Niraj Pradhan

Posted on

Deployment Object in Kubernetes. Why Deployment object over ReplicaSet?

In the previous post, we have discussed about ReplicaSet, how it is used to manage, create multiple instances of Pod.

Deployment

Deployment is a kubernetes object that is used to manage, organize, combine pods. When deployment is created, then it creates replicaset. Replicaset create pods according to the number specified in the replicas option.
Deployments are used to scale our application by increasing the number of running pods or update the running application.

Create deployment object

We can create deployment object in two ways:

Method 1: Using manifest file (yaml)

~ vim deployment.yaml
Enter fullscreen mode Exit fullscreen mode
apiVersion: apps/v1
kind: Deployment
metadata:
  name: portfolio-deployment
  labels:
    app: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: portfolio-container
        image: nirajpdn/react-app:v1
        ports:
        - containerPort: 80
Enter fullscreen mode Exit fullscreen mode

Lets apply above file to create deployment,

~ kubectl apply -f deployment.yaml

  deployment.apps/portfolio-deployment created
Enter fullscreen mode Exit fullscreen mode

or

~ kubectl create -f deployment.yaml

  deployment.apps/portfolio-deployment created
Enter fullscreen mode Exit fullscreen mode

To view deployments in kubernetes cluster,

~ kubectl get deployment
Enter fullscreen mode Exit fullscreen mode

Output

NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
portfolio-deployment   3/3     3            3           81s
Enter fullscreen mode Exit fullscreen mode

Above output shows that, 3 instances of pods are deployed.
Lets check those Pods,

~ kubectl get pods --show-labels
Enter fullscreen mode Exit fullscreen mode
NAME                                    READY   STATUS    RESTARTS     AGE     LABELS

portfolio-deployment-67746bf69d-9njm5   1/1     Running   0            113s     app=frontend,pod-template-hash=67746bf69d
portfolio-deployment-67746bf69d-wkqsq   1/1     Running   0            113s     app=frontend,pod-template-hash=67746bf69d
portfolio-deployment-67746bf69d-zdvkt   1/1     Running   0            113s     app=frontend,pod-template-hash=67746bf69d


Enter fullscreen mode Exit fullscreen mode

As we have seen that, pods with label app:frontend and pod-template-hash=67746bf69d. pod-template-hash is added automatically by deployment controller.

Pods are associated with deployment and replicaset with the help of labels as shown in the figure below:

Deployment Image

Do you notice Deployment and ReplicaSet have almost similar scripts in manifest file and what's the actual difference and why we need deployment object ?

Replica Vs Deployment

ReplicaSet Vs Deployment

ReplicaSet ensures the number of running pods in the cluster. Pods are the replicas and the mechanism of specifying the number of running pods in the cluster. Changing the ReplicaSet will not have any effect in existing Pods. So it is not easy to change image version in the container.

Deployment is a higher-level abstraction that manages one or more ReplicaSet to provide controlled rollout of a new version. When image version is changed in Deployment, a new ReplicSet is new version will be created with initially zero replicas. Then it will be scaled up, after that is running the old ReplicaSet will be scaled down.

  • Deployment resource make it easier for updating pods to new version.
  • Deployment doesn't directly interact with Pods but it does rolling out update using ReplicaSets.

Lets update the version of image from nirajpdn/react-app:v1 to nirajpdn/react-app:v2.

You can describe the pod to know the current version of image used with command kubectl describe pods <pod-name>.

~ kubectl describe pods portfolio-deployment-67746bf69d-9njm5
Enter fullscreen mode Exit fullscreen mode

Or just view the deployments with current image and container,

~ kubectl get deployments -o wide
Enter fullscreen mode Exit fullscreen mode

Output

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS            IMAGES                  SELECTOR
portfolio-deployment       3/3     3            3           90m   portfolio-container   nirajpdn/react-app:v1   app=frontend

Enter fullscreen mode Exit fullscreen mode

After that lets update manifest file,

apiVersion: apps/v1
kind: Deployment
metadata:
  name: portfolio-deployment
  labels:
    app: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: portfolio-container
        image: nirajpdn/react-app:v2
        ports:
        - containerPort: 80
Enter fullscreen mode Exit fullscreen mode

Lets apply above file to create deployment,

~ kubectl apply -f deployment.yaml

  deployment.apps/portfolio-deployment created
Enter fullscreen mode Exit fullscreen mode
NAME                                    READY   STATUS              RESTARTS      AGE

portfolio-deployment-67746bf69d-9njm5   1/1     Running             0             94m
portfolio-deployment-67746bf69d-wkqsq   1/1     Running             0             94m
portfolio-deployment-67746bf69d-zdvkt   1/1     Running             0             94m
portfolio-deployment-7f67bddbc5-wh5w6   0/1     ContainerCreating   0             8s
Enter fullscreen mode Exit fullscreen mode

Here we can see, new instance of Pod is creating. After it is running, the new ReplicaSet with new version is scaled up and old ReplicaSet is scaled down.

Lets check Pods again,

NAME                                    READY   STATUS    RESTARTS      AGE

portfolio-deployment-7f67bddbc5-lnvxf   1/1     Running   0             18s
portfolio-deployment-7f67bddbc5-rcr6b   1/1     Running   0             21s
portfolio-deployment-7f67bddbc5-wh5w6   1/1     Running   0             99s

Enter fullscreen mode Exit fullscreen mode

We have successfully updated the pods with new version of image. We can describe the new pod again.

~ kubectl describe pods portfolio-deployment-7f67bddbc5-lnvxf
Enter fullscreen mode Exit fullscreen mode

Output

Name:         portfolio-deployment-7f67bddbc5-lnvxf
Namespace:    default
Priority:     0
Node:         minikube/192.168.49.2
Start Time:   Fri, 24 Jun 2022 10:21:14 +0545
Labels:       app=frontend
              pod-template-hash=7f67bddbc5
Annotations:  <none>
Status:       Running
IP:           172.17.0.14
IPs:
  IP:           172.17.0.14
Controlled By:  ReplicaSet/portfolio-deployment-7f67bddbc5
Containers:
  portfolio-container:
    Container ID:   docker://fe23f5b33ba9593bf9c3f31cdf984856bb57edbabe9d70249a3bd3125d5e4fbc
    Image:          nirajpdn/react-app:v2
    Image ID:       docker-pullable://nirajpdn/react-app@sha256:c4352340615dd6d2f4df28c66d8e1ec23fd30588bf2b8ca405c369b3f6e05b66
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Fri, 24 Jun 2022 10:21:16 +0545
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hpr4m (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-hpr4m:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
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  5m35s  default-scheduler  Successfully assigned default/portfolio-deployment-7f67bddbc5-lnvxf to minikube
  Normal  Pulled     5m33s  kubelet            Container image "nirajpdn/react-app:v2" already present on machine
  Normal  Created    5m33s  kubelet            Created container portfolio-container
  Normal  Started    5m33s  kubelet            Started container portfolio-container
Enter fullscreen mode Exit fullscreen mode

And this is why deployment object is needed to scale, manage, upgrade the pods as per our requirement.

Method 2: Using CLI

We can create deployment with command kubectl create deployment <deployment-name> --image=<image>

~ kubectl create deployment portfolio-deployment-cli --image=nirajpdn/react-app:v1

  deployment.apps/portfolio-deployment-cli created
Enter fullscreen mode Exit fullscreen mode

View Deployments

~ kubectl get deployments
Enter fullscreen mode Exit fullscreen mode
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
portfolio-deployment-cli   1/1     1            1           18s
portfolio-deployment       3/3     3            3           109m

Enter fullscreen mode Exit fullscreen mode

By default, one instance of Pod is created.

Scaling application

~ kubectl scale deployment/portfolio-deployment-cli --replicas=3

  deployment.apps/portfolio-deployment-cli scaled
Enter fullscreen mode Exit fullscreen mode

Lets check,

~ kubectl get deployments -o wide
Enter fullscreen mode Exit fullscreen mode

Output

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS            IMAGES                  SELECTOR
portfolio-deployment       3/3     3            3           124m    portfolio-container   nirajpdn/react-app:v2   app=frontend
portfolio-deployment-cli   3/3     3            3           8m20s   react-app             nirajpdn/react-app:v1   app=portfolio-deployment-cli

Enter fullscreen mode Exit fullscreen mode

Lets update the image with CLI

We can update image version with command: kubectl set image deployment/<deployment-name> <container-name>=<image>

kubectl set image deployment/portfolio-deployment-cli react-app=nirajpdn/react-app:v2

Enter fullscreen mode Exit fullscreen mode

Lets check deployment again,

~ kubectl get deployments -o wide
Enter fullscreen mode Exit fullscreen mode

Output

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS            IMAGES                  SELECTOR
portfolio-deployment       3/3     3            3           132m   portfolio-container   nirajpdn/react-app:v2   app=frontend
portfolio-deployment-cli   3/3     3            3           15m    react-app             nirajpdn/react-app:v2   app=portfolio-deployment-cli
Enter fullscreen mode Exit fullscreen mode

Delete deployment

We can delete deployment as follows:

~ kubectl delete deployment/portfolio-deployment-cli

  deployment.apps "portfolio-deployment-cli" deleted
Enter fullscreen mode Exit fullscreen mode

Lets confirm,

~ kubectl get deployments
Enter fullscreen mode Exit fullscreen mode

Output

NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
portfolio-deployment   3/3     3            3           139m
Enter fullscreen mode Exit fullscreen mode

Alright, this much for deployment object of kubernetes in this post.

Top comments (0)