Categories
DevOps Orchestration

Kubernetes Deployments, ReplicaSets Demo

Kubernetes deployments allow to define and enforce desired state of applications running in Kubernetes. Kubernetes deployments achieve that using ReplicaSets. ReplicaSet guarantees running the desired number of Kubernetes pods. Below, we’ll explore deployments and ReplicaSets concepts. In addition, I’ll demo how to manage them using kubectl. Keep reading to find out more.

Introduction

In the last post we explored Kubernetes Pods. We saw that they are the most basic Kubernetes objects and that they live only once. Today, I’ll introduce you to Kubernetes deployments and their relation to pods. In addition, we’ll see how to manage them using kubectl.

Kubernetes Deployments Concepts

We already know that Kubernetes can maintain the desired state of applications. More specifically, their availability and desired scale. How to declare desired state of the applications (their pods)? For that purpose Kubernetes deployments exist. In addition to declaring desired state of application pods, they allow rolling updates of pods. More specifically ReplicaSets of pods.

Kubernetes Deployment

Most common example of app desired state is its scale. More specifically, number of app pods. So, when we declare Kubernetes deployment, we have to specify the desired number of replicas (pods) of an application. How does ReplicaSet fit in? Well, Kubernetes deployments manage pods using ReplicaSets. In short, these are Kubernetes objects which ensure that the required number of pods are available. So, ReplicaSets provide important Kubernetes promises like: self-healing, fault tolerance and scale.

We said in Kubernetes Pods Introduction that we don’t have to create pods directly. I’ll add now that we don’t have to create ReplicaSets directly as well. The only thing we need to do is to create Kubernetes deployments.

Enough talking. Now, let’s see some Kubernetes deployments demo.

Prerequisites

Install on your machine:

  • minikube

The tutorial assumes familiarity with basic kubectl commands.

Declare Kubernetes Deployments using yaml

We usually create Kubernetes deployment using kubectl create and kubectl apply and supply deployment manifests as input.

While it’s possible to declare manifests using JSON, we’ll pick yaml. Mostly, because I find it more readable. But, where do we get the manifest? Should we write it ourselves? I’d rather not. Why? See yourself. Sample Kubernetes deployment is defined below:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.13.2
        ports:
        - containerPort: 80

Luckily, there’s a nice trick using kubectl which will save us.

Though first, let’s start Kubernetes cluster using minikube. kubectl will be auto-configured to use it. Let’s follow the same path as inKubernetes Pods Introduction and create a multi-node cluster.

minikube start --nodes 3 -p multinode-demo.

Next, we’ll generate deployment manifest in yaml format using kubectl:

kubectl create deploy nginx --image=nginx:1.13.2 --dry-run=client -o yaml > app.yaml

Thanks to --dry-run we get app.yaml that looks like below:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1                                                                                                                         
  selector:                                                                                                                           
    matchLabels:                                                                                                                      
      app: nginx                                                                                                                      
  strategy: {}                                                                                                                        
  template:                                                                                                                           
    metadata:                                                                                                                         
      creationTimestamp: null                                                                                                         
      labels:                                                                                                                         
        app: nginx                                                                                                                    
    spec:                                                                                                                             
      containers:                                                                                                                     
      - image: nginx:1.13.2                                                                                                           
        name: nginx                                                                                                                   
        resources: {}                                                                                                                 
status: {}   

Nice way to save time, right?

Now, let’s start the deployment.

Manage Kubernetes Deployments using kubectl

Start nginx deployment:

$ kubectl create -f app.yaml

After a little while, nginx images are pulled and run.

$ kubectl get deployments.apps 
NAME    READY   UP-TO-DATE   AVAILABLE   AGE                                                                                          
nginx   1/1     1            1           80s 

Any pods involved? Of course.

Deployment spec specifies container image nginx pods run. In addition, it specifies the label nginx pod will have: app: nginx. Of course, deployment itself has the same label. Let’s see all Kubernetes objects having this label.

$ kubectl get all -l app=nginx
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-6d67674bb5-kq9jh   1/1     Running   0          3m22s
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   1/1     1            1           3m22s
NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-6d67674bb5   1         1         1       3m22s

Noticed ReplicaSet object? While we haven’t created it explicitly, creating deployment did. It’s because Kubernetes deployment uses ReplicaSets to manage the pods. How does ReplicaSet know which pods to manage? Of course, it uses selector which matches the label app: nginx we specified in the deployment spec.

Let’s scale nginx and see ReplicaSet in action.

Run kubectl scale deploy nginx --replicas 3

Note 3 pods which is desired number of replicas ReplicaSet maintains:

$ kubectl get all -l app=nginx
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-6d67674bb5-5g9nm   1/1     Running   0          12s
pod/nginx-6d67674bb5-kq9jh   1/1     Running   0          18m
pod/nginx-6d67674bb5-wfjtt   1/1     Running   0          12s
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   3/3     3            3           18m
NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-6d67674bb5   3         3         3       18m

Moreover, describing ReplicaSet shows us that indeed ReplicaSet-Controller created the pods after we scaled the deployment.

$ kubectl describe rs -l app=nginx
...
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  23m    replicaset-controller  Created pod: nginx-6d67674bb5-kq9jh
  Normal  SuccessfulCreate  4m34s  replicaset-controller  Created pod: nginx-6d67674bb5-5g9nm
  Normal  SuccessfulCreate  4m34s  replicaset-controller  Created pod: nginx-6d67674bb5-wfjtt

What if we want to access our highly available nginx service. Of course, we can use kubectl port-forward as we did inKubernetes Pods Introduction:

$ kubectl port-forward deployment/nginx 8090:80

Navigating to http://localhost:8090/ will show nginx welcome screen.

Is nginx Kubernetes deployment load-balanced?

Not really.

To be sure, let’s open new terminal and run there:

$ minikube -p multinode-demo kubectl -- logs -f deployment/nginx
Found 3 pods, using pod/nginx-6d67674bb5-kq9jh

We see that only one pod pod/nginx-6d67674bb5-kq9jh serves the traffic. And if you are not convinced, inspect the logs of the mentioned pod while doing a few refreshes in the browser.

$ minikube -p multinode-demo kubectl -- logs pod/nginx-6d67674bb5-kq9jh

You should see GET requests there, while other pods` logs are empty.

So how to achieve load balancing between Kubernetes deployment pods? We’ll cover that in future posts when we talk about Kubernetes services and Ingress.

For cleaning up, let’s delete nginx deployment:

$ kubectl delete deployment/nginx

You will see that deployment, ReplicaSet and pods are gone:

$ kubectl get all -l app=nginx
No resources found in default namespace.

Finally, let’s stop our minikube cluster.

minikube stop -p multinode-demo

Summary

That’s it about Kubernetes deployment. Stay tuned for more Kubernetes related posts. And, as always, feel free to share and comment.

Bonus:

  • Become a Certified Kubernetes Administrator (CKA)!
  • Become a Certified Kubernetes Application Developer (CKAD)!
  • BUNDLE KUBERNETES FUNDAMENTALS & CKA CERTIFICATION (COURSE & CERTIFICATION) FOR THE BEST DEAL! $499 ONLY!
  • Recommended Kubernetes courses on Pluralsight:

    Sign up using this link to get exclusive discounts like 50% off your first month or 15% off an annual subscription)

    Recommended Kubernetes books on Amazon: