DEV Community

Sina Tavakkol
Sina Tavakkol

Posted on

40 Days Of Kubernetes (8/40)

Day 8/40

Kubernetes Deployment, Replication Controller and ReplicaSet Explained

Video Link
@piyushsachdeva
Git Repository
My Git Repo

We're going to learn about deployment and replicaset.
Assume there's a pod containing a nginx container running and because of an issue, the pod is stopped and crashed.
Actually in the real world, we don't tolerate stopping services, because we have some important customer and we are committed to our SLA with them and need to back to up and running state.
So, to overcome that type of problem we implement HA with having at least a copy of our app beside.

Let's say we are going to use replication controller that's manage by controller manager.
Note there's difference between replication controller and replicaset.

ReplicationController It creates a certain number of identical pods, and if a pod fails, replaces it. It also lets you update several pods or delete pods with one command. It's responsible for load balancing the traffic between replicas. replicas can be deploy on different nodes.

Image description
(Photo from the video)

1. Create a ReplicationController

---
apiVersion: v1

kind: ReplicationController

metadata:
  name: nginx-rc
  labels:
    env: demo

spec:
  template:
    metadata:
      name: nginx-pod
      labels:
        env: demo-pod
        type: frontend

    spec:
      containers:
      - name: nginx-container
        image: nginx
        ports:
          - containerPort: 80

  replicas: 3
Enter fullscreen mode Exit fullscreen mode
root@localhost:~# kubectl apply -f day08-rc.yaml
replicationcontroller/nginx-rc created
root@localhost:~# kubectl get rc
NAME       DESIRED   CURRENT   READY   AGE
nginx-rc   3         3         3       9s
root@localhost:~# kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
nginx-rc-5x9bx   1/1     Running   0          17s
nginx-rc-ljwqs   1/1     Running   0          17s
nginx-rc-rsvfg   1/1     Running   0          17s
root@localhost:~# kubectl get pod -o wide
NAME             READY   STATUS    RESTARTS   AGE    IP           NODE                 NOMINATED NODE   READINESS GATES
nginx-rc-5x9bx   1/1     Running   0          3m2s   10.244.1.3   lucky-luke-worker    <none>           <none>
nginx-rc-ljwqs   1/1     Running   0          3m2s   10.244.2.4   lucky-luke-worker2   <none>           <none>
nginx-rc-rsvfg   1/1     Running   0          3m2s   10.244.2.5   lucky-luke-worker2   <none>           <none>

Enter fullscreen mode Exit fullscreen mode

ReplicaSet is the new version of ReplicationController and is declared in the same way, except it has more options for selectors.

---
apiVersion: apps/v1

kind: ReplicaSet

metadata:
  name: nginx-rs
  labels:
    env: demo

spec:
  template:
    metadata:
      name: nginx-pod
      labels:
        env: demo-pod
        type: frontend

    spec:
      containers:
      - name: nginx-container
        image: nginx
        ports:
          - containerPort: 80

  replicas: 3
  selector:
    matchLabels:
      env: demo-pod
Enter fullscreen mode Exit fullscreen mode
root@localhost:~# kubectl apply -f day08-rs.yaml
replicaset.apps/nginx-rs created
root@localhost:~# kubectl get rs
NAME       DESIRED   CURRENT   READY   AGE
nginx-rs   3         3         3       8s
root@localhost:~# kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
nginx-rc-5x9bx   1/1     Running   0          14m
nginx-rc-ljwqs   1/1     Running   0          14m
nginx-rc-rsvfg   1/1     Running   0          14m
nginx-rs-fw8xc   1/1     Running   0          13s
nginx-rs-mn2wp   1/1     Running   0          13s
nginx-rs-wvt7n   1/1     Running   0          13s
root@localhost:~# kubectl get pod -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP           NODE                 NOMINATED NODE   READINESS GATES
nginx-rc-5x9bx   1/1     Running   0          14m   10.244.1.3   lucky-luke-worker    <none>           <none>
nginx-rc-ljwqs   1/1     Running   0          14m   10.244.2.4   lucky-luke-worker2   <none>           <none>
nginx-rc-rsvfg   1/1     Running   0          14m   10.244.2.5   lucky-luke-worker2   <none>           <none>
nginx-rs-fw8xc   1/1     Running   0          19s   10.244.2.6   lucky-luke-worker2   <none>           <none>
nginx-rs-mn2wp   1/1     Running   0          19s   10.244.1.5   lucky-luke-worker    <none>           <none>
nginx-rs-wvt7n   1/1     Running   0          19s   10.244.1.4   lucky-luke-worker    <none>           <none>
root@localhost:~# kubectl delete -f day08-rc.yaml
replicationcontroller "nginx-rc" deleted
root@localhost:~# kubectl get pod -o wide
NAME             READY   STATUS    RESTARTS   AGE     IP           NODE                 NOMINATED NODE   READINESS GATES
nginx-rs-fw8xc   1/1     Running   0          3m19s   10.244.2.6   lucky-luke-worker2   <none>           <none>
nginx-rs-mn2wp   1/1     Running   0          3m19s   10.244.1.5   lucky-luke-worker    <none>           <none>
nginx-rs-wvt7n   1/1     Running   0          3m19s   10.244.1.4   lucky-luke-worker    <none>           <none>

Enter fullscreen mode Exit fullscreen mode

Live edit ReplicaSet and change the replicas to 5.

root@localhost:~# kubectl edit rs nginx-rs
replicaset.apps/nginx-rs edited
root@localhost:~# kubectl get rs
NAME       DESIRED   CURRENT   READY   AGE
nginx-rs   5         5         5       5m59s
root@localhost:~# kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
nginx-rs-5bxcm   1/1     Running   0          11s
nginx-rs-fw8xc   1/1     Running   0          6m6s
nginx-rs-jv4sd   1/1     Running   0          11s
nginx-rs-mn2wp   1/1     Running   0          6m6s
nginx-rs-wvt7n   1/1     Running   0          6m6s
root@localhost:~# kubectl get pod -o wide
NAME             READY   STATUS    RESTARTS   AGE     IP           NODE                 NOMINATED NODE   READINESS GATES
nginx-rs-5bxcm   1/1     Running   0          18s     10.244.1.6   lucky-luke-worker    <none>           <none>
nginx-rs-fw8xc   1/1     Running   0          6m13s   10.244.2.6   lucky-luke-worker2   <none>           <none>
nginx-rs-jv4sd   1/1     Running   0          18s     10.244.2.7   lucky-luke-worker2   <none>           <none>
nginx-rs-mn2wp   1/1     Running   0          6m13s   10.244.1.5   lucky-luke-worker    <none>           <none>
nginx-rs-wvt7n   1/1     Running   0          6m13s   10.244.1.4   lucky-luke-worker    <none>           <none>
Enter fullscreen mode Exit fullscreen mode

We can use 2 other ways to increase/decrease the replicas. One by editing the manifest and then apply with kubectl command, and other is what you can see below:

root@localhost:~# kubectl scale --replicas=10 rs/nginx-rs
replicaset.apps/nginx-rs scaled
root@localhost:~# kubectl get rs
NAME       DESIRED   CURRENT   READY   AGE
nginx-rs   10        10        10      11m
root@localhost:~# kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
nginx-rs-5bxcm   1/1     Running   0          5m29s
nginx-rs-7n6vt   1/1     Running   0          6s
nginx-rs-9qk4m   1/1     Running   0          6s
nginx-rs-dwtcb   1/1     Running   0          6s
nginx-rs-fw8xc   1/1     Running   0          11m
nginx-rs-hbxb8   1/1     Running   0          6s
nginx-rs-jv4sd   1/1     Running   0          5m29s
nginx-rs-kh4gq   1/1     Running   0          6s
nginx-rs-mn2wp   1/1     Running   0          11m
nginx-rs-wvt7n   1/1     Running   0          11m
root@localhost:~# kubectl get pod -o wide
NAME             READY   STATUS    RESTARTS   AGE     IP            NODE                 NOMINATED NODE   READINESS GATES
nginx-rs-5bxcm   1/1     Running   0          5m41s   10.244.1.6    lucky-luke-worker    <none>           <none>
nginx-rs-7n6vt   1/1     Running   0          18s     10.244.1.8    lucky-luke-worker    <none>           <none>
nginx-rs-9qk4m   1/1     Running   0          18s     10.244.2.9    lucky-luke-worker2   <none>           <none>
nginx-rs-dwtcb   1/1     Running   0          18s     10.244.2.8    lucky-luke-worker2   <none>           <none>
nginx-rs-fw8xc   1/1     Running   0          11m     10.244.2.6    lucky-luke-worker2   <none>           <none>
nginx-rs-hbxb8   1/1     Running   0          18s     10.244.2.10   lucky-luke-worker2   <none>           <none>
nginx-rs-jv4sd   1/1     Running   0          5m41s   10.244.2.7    lucky-luke-worker2   <none>           <none>
nginx-rs-kh4gq   1/1     Running   0          18s     10.244.1.7    lucky-luke-worker    <none>           <none>
nginx-rs-mn2wp   1/1     Running   0          11m     10.244.1.5    lucky-luke-worker    <none>           <none>
nginx-rs-wvt7n   1/1     Running   0          11m     10.244.1.4    lucky-luke-worker    <none>           <none>

Enter fullscreen mode Exit fullscreen mode

2. Deployment

It provides some additional functionalities to the ReplicaSet. As a user, we create the deployment and it creates the ReplicaSet and then the ReplicaSet creates pod.
So, they are part of the deployment
Image description
(Photo from the video)
In RollingUpdate we can update the version of our app in almost zero downtime, which is very important to us and our customers. Also we can do the RollBack the changes we made easily.

Let's do it

---
apiVersion: apps/v1

kind: Deployment

metadata:
  name: nginx-deploy
  labels:
    env: demo

spec:
  template:
    metadata:
      name: nginx-pod
      labels:
        env: demo-pod
        type: frontend

    spec:
      containers:
      - name: nginx-container
        image: nginx
        ports:
          - containerPort: 80

  replicas: 3
  selector:
    matchLabels:
      env: demo-pod
Enter fullscreen mode Exit fullscreen mode
root@localhost:~# kubectl apply -f day08-deploy.yaml
deployment.apps/nginx-deploy created
root@localhost:~# kubectl get node,deploy,rs,pod
NAME                            STATUS   ROLES           AGE     VERSION
node/lucky-luke-control-plane   Ready    control-plane   5h44m   v1.30.0
node/lucky-luke-worker          Ready    <none>          5h43m   v1.30.0
node/lucky-luke-worker2         Ready    <none>          5h43m   v1.30.0

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deploy   0/3     3            0           3s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deploy-6bfd44d944   3         3         0       3s

NAME                                READY   STATUS              RESTARTS   AGE
pod/nginx-deploy-6bfd44d944-24lf8   0/1     ContainerCreating   0          3s
pod/nginx-deploy-6bfd44d944-5bfm4   0/1     ContainerCreating   0          3s
pod/nginx-deploy-6bfd44d944-hfgbq   0/1     ContainerCreating   0          3s
root@localhost:~#
root@localhost:~# kubectl get all
NAME                                READY   STATUS    RESTARTS   AGE
pod/nginx-deploy-6bfd44d944-24lf8   1/1     Running   0          2m45s
pod/nginx-deploy-6bfd44d944-5bfm4   1/1     Running   0          2m45s
pod/nginx-deploy-6bfd44d944-hfgbq   1/1     Running   0          2m45s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   5h47m

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deploy   3/3     3            3           2m45s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deploy-6bfd44d944   3         3         3       2m45s

Enter fullscreen mode Exit fullscreen mode

Changing the version of our app

root@localhost:~# kubectl set image deployment/nginx-deploy nginx-container=nginx:1.9.1
deployment.apps/nginx-deploy image updated
root@localhost:~# kubectl get all
NAME                                READY   STATUS              RESTARTS   AGE
pod/nginx-deploy-6bfd44d944-24lf8   1/1     Running             0          6m37s
pod/nginx-deploy-6bfd44d944-5bfm4   1/1     Running             0          6m37s
pod/nginx-deploy-6bfd44d944-hfgbq   1/1     Running             0          6m37s
pod/nginx-deploy-c4b878cbf-s9skb    0/1     ContainerCreating   0          11s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   5h51m

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deploy   3/3     1            3           6m37s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deploy-6bfd44d944   3         3         3       6m37s
replicaset.apps/nginx-deploy-c4b878cbf    1         1         0       12s
root@localhost:~# kubectl get all
NAME                                READY   STATUS              RESTARTS   AGE
pod/nginx-deploy-6bfd44d944-5bfm4   1/1     Running             0          6m49s
pod/nginx-deploy-6bfd44d944-hfgbq   0/1     Terminating         0          6m49s
pod/nginx-deploy-c4b878cbf-2b7l2    1/1     Running             0          11s
pod/nginx-deploy-c4b878cbf-qkdql    0/1     ContainerCreating   0          1s
pod/nginx-deploy-c4b878cbf-s9skb    1/1     Running             0          23s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   5h51m

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deploy   3/3     3            3           6m50s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deploy-6bfd44d944   1         1         1       6m50s
replicaset.apps/nginx-deploy-c4b878cbf    3         3         2       25s
root@localhost:~# kubectl get all
NAME                               READY   STATUS    RESTARTS   AGE
pod/nginx-deploy-c4b878cbf-2b7l2   1/1     Running   0          24s
pod/nginx-deploy-c4b878cbf-qkdql   1/1     Running   0          14s
pod/nginx-deploy-c4b878cbf-s9skb   1/1     Running   0          36s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   5h51m

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deploy   3/3     3            3           7m2s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deploy-6bfd44d944   0         0         0       7m2s
replicaset.apps/nginx-deploy-c4b878cbf    3         3         3       37s

Enter fullscreen mode Exit fullscreen mode

Having the logs of our change

root@localhost:~# kubectl describe deploy nginx-deploy
Name:                   nginx-deploy
Namespace:              default
CreationTimestamp:      Thu, 27 Jun 2024 21:01:48 +0000
Labels:                 env=demo
Annotations:            deployment.kubernetes.io/revision: 2
Selector:               env=demo-pod
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:  env=demo-pod
           type=frontend
  Containers:
   nginx-container:
    Image:         nginx:1.9.1
    Port:          80/TCP
    Host Port:     0/TCP
    Environment:   <none>
    Mounts:        <none>
  Volumes:         <none>
  Node-Selectors:  <none>
  Tolerations:     <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  nginx-deploy-6bfd44d944 (0/0 replicas created)
NewReplicaSet:   nginx-deploy-c4b878cbf (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  8m43s  deployment-controller  Scaled up replica set nginx-deploy-6bfd44d944 to 3
  Normal  ScalingReplicaSet  2m17s  deployment-controller  Scaled up replica set nginx-deploy-c4b878cbf to 1
  Normal  ScalingReplicaSet  2m5s   deployment-controller  Scaled down replica set nginx-deploy-6bfd44d944 to 2 from 3
  Normal  ScalingReplicaSet  2m5s   deployment-controller  Scaled up replica set nginx-deploy-c4b878cbf to 2 from 1
  Normal  ScalingReplicaSet  115s   deployment-controller  Scaled down replica set nginx-deploy-6bfd44d944 to 1 from 2
  Normal  ScalingReplicaSet  115s   deployment-controller  Scaled up replica set nginx-deploy-c4b878cbf to 3 from 2
  Normal  ScalingReplicaSet  111s   deployment-controller  Scaled down replica set nginx-deploy-6bfd44d944 to 0 from 1
Enter fullscreen mode Exit fullscreen mode

There are two revisions in the history of rollout of our deployment:

root@localhost:~# kubectl rollout history deploy/nginx-deploy
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

Enter fullscreen mode Exit fullscreen mode

We can rollback the changes:

root@localhost:~# kubectl rollout undo deploy/nginx-deploy
deployment.apps/nginx-deploy rolled back
root@localhost:~# kubectl rollout history deploy/nginx-deploy
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
2         <none>
3         <none>

root@localhost:~# kubectl get all
NAME                                READY   STATUS        RESTARTS   AGE
pod/nginx-deploy-6bfd44d944-82pwb   1/1     Running       0          2s
pod/nginx-deploy-6bfd44d944-pfgrk   1/1     Running       0          5s
pod/nginx-deploy-6bfd44d944-xbpzt   1/1     Running       0          8s
pod/nginx-deploy-c4b878cbf-2b7l2    1/1     Terminating   0          5m58s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   5h57m

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deploy   3/3     3            3           12m

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deploy-6bfd44d944   3         3         3       12m
replicaset.apps/nginx-deploy-c4b878cbf    0         0         0       6m11s
root@localhost:~# kubectl get all
NAME                                READY   STATUS    RESTARTS   AGE
pod/nginx-deploy-6bfd44d944-82pwb   1/1     Running   0          14s
pod/nginx-deploy-6bfd44d944-pfgrk   1/1     Running   0          17s
pod/nginx-deploy-6bfd44d944-xbpzt   1/1     Running   0          20s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   5h57m

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deploy   3/3     3            3           12m

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deploy-6bfd44d944   3         3         3       12m
replicaset.apps/nginx-deploy-c4b878cbf    0         0         0       6m23s
Enter fullscreen mode Exit fullscreen mode
root@localhost:~# kubectl describe deploy nginx-deploy
Name:                   nginx-deploy
Namespace:              default
CreationTimestamp:      Thu, 27 Jun 2024 21:01:48 +0000
Labels:                 env=demo
Annotations:            deployment.kubernetes.io/revision: 3
Selector:               env=demo-pod
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:  env=demo-pod
           type=frontend
  Containers:
   nginx-container:
    Image:         nginx
    Port:          80/TCP
    Host Port:     0/TCP
    Environment:   <none>
    Mounts:        <none>
  Volumes:         <none>
  Node-Selectors:  <none>
  Tolerations:     <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  nginx-deploy-c4b878cbf (0/0 replicas created)
NewReplicaSet:   nginx-deploy-6bfd44d944 (3/3 replicas created)
Events:
  Type    Reason             Age                From                   Message
  ----    ------             ----               ----                   -------
  Normal  ScalingReplicaSet  13m                deployment-controller  Scaled up replica set nginx-deploy-6bfd44d944 to 3
  Normal  ScalingReplicaSet  7m26s              deployment-controller  Scaled up replica set nginx-deploy-c4b878cbf to 1
  Normal  ScalingReplicaSet  7m14s              deployment-controller  Scaled down replica set nginx-deploy-6bfd44d944 to 2 from 3
  Normal  ScalingReplicaSet  7m14s              deployment-controller  Scaled up replica set nginx-deploy-c4b878cbf to 2 from 1
  Normal  ScalingReplicaSet  7m4s               deployment-controller  Scaled down replica set nginx-deploy-6bfd44d944 to 1 from 2
  Normal  ScalingReplicaSet  7m4s               deployment-controller  Scaled up replica set nginx-deploy-c4b878cbf to 3 from 2
  Normal  ScalingReplicaSet  7m                 deployment-controller  Scaled down replica set nginx-deploy-6bfd44d944 to 0 from 1
  Normal  ScalingReplicaSet  84s                deployment-controller  Scaled up replica set nginx-deploy-6bfd44d944 to 1 from 0
  Normal  ScalingReplicaSet  81s                deployment-controller  Scaled down replica set nginx-deploy-c4b878cbf to 2 from 3
  Normal  ScalingReplicaSet  76s (x4 over 81s)  deployment-controller  (combined from similar events): Scaled down replica set nginx-deploy-c4b878cbf to 0 from 1
Enter fullscreen mode Exit fullscreen mode
root@localhost:~# kubectl create deploy deploy/nginx-new --image=nginx --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: deploy/nginx-new
  name: deploy/nginx-new
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploy/nginx-new
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: deploy/nginx-new
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}
Enter fullscreen mode Exit fullscreen mode

Top comments (1)