This is part 3 of the series on Managing Microservices with Kubernetes. You can read part 1 here, and part 2 here.
In part 1, we understood how Kubernetes is used to deploy a Microservice. In that blog, I mentioned that a couple of Kubernetes objects are used to deploy the voting application – Namespaces, Labels and Selectors, Pods, ReplicaSets, Deployment, and Service Objects. In part 2 we explored some of the Kubernetes objects used in building the microservice application. We also explored scaling a microservice's application using the ReplicaSet Controller object.
In this blog, I will show you how to use the Deployment Object to scale the microservice. I will mention the additional features that a deployment has that are not present in a replicaset object. We will explore the additional features in the next couple of blogs.
Here is the flow when a deployment object is created:
Deployment-->ReplicaSet-->Pod-->Container
This means that each time you create a deployment, it will create a ReplicaSet, a Pod, and a Container.
The deployment object provides features not available to Replicaset. It can do everything a ReplicaSet can do and even more, such that we don’t have a need to use the Replicaset directly. With Replicaset, you can update your images on the fly with configurations such as rolling updates, Blue-Green deployment as well as Canary deployments. In production environments, developers typically just stick to using deployment objects.
Firstly, let us explore the YAML file provided by the vote-app project. Unlike before, where we had to create the YAML files for the Pod and the Replicaset, here we will use the YAML file provided. In working with microservices applications you will typically create 2 files for each microservice: the deployment object YAML file and the service object YAML file as you can see in this listing. Here, each deployment file has a corresponding service object file.
cloudexperts@master1:~/example-voting-app/k8s-specifications$ ls -al total 44 drwxrwxr-x 2 cloudexperts cloudexperts 4096 Jun 9 12:02 . drwxrwxr-x 8 cloudexperts cloudexperts 4096 Jun 8 14:52 .. -rw-rw-r-- 1 cloudexperts cloudexperts 646 Jun 4 17:57 db-deployment.yaml -rw-rw-r-- 1 cloudexperts cloudexperts 209 Jun 4 17:57 db-service.yaml -rw-rw-r-- 1 cloudexperts cloudexperts 510 Jun 4 17:57 redis-deployment.yaml -rw-rw-r-- 1 cloudexperts cloudexperts 221 Jun 4 17:57 redis-service.yaml -rw-rw-r-- 1 cloudexperts cloudexperts 408 Jun 4 17:57 result-deployment.yaml -rw-rw-r-- 1 cloudexperts cloudexperts 239 Jun 4 17:57 result-service.yaml -rw-rw-r-- 1 cloudexperts cloudexperts 394 Jun 4 17:57 vote-deployment.yaml -rw-rw-r-- 1 cloudexperts cloudexperts 234 Jun 4 18:06 vote-service.yaml -rw-rw-r-- 1 cloudexperts cloudexperts 335 Jun 4 17:57 worker-deployment.yaml
Here is the file for the Deployment object.
apiVersion: apps/v1 kind: Deployment metadata: labels: app: vote name: vote namespace: vote spec: replicas: 1 selector: matchLabels: app: vote template: metadata: labels: app: vote spec: containers: - image: dockersamples/examplevotingapp_vote:before name: vote ports: - containerPort: 80 name: vote
Comparing this file to the ReplicaSet file (in part 2 here), observe that there is just no difference apart from specifying that the Kind is Deployment rather than ReplicaSet. Like the RelicaSet, it has 4 sections:
We can create the Deployment object using kubectl command
Kubectl create -f vote-deployment.yaml
But we had it running from the previous sessions, so let’s delete it and then create it again
cloudexperts@master1:~/example-voting-app/k8s-specifications$ kubectl get deploy -n vote NAME READY UP-TO-DATE AVAILABLE AGE db 1/1 1 1 16h redis 1/1 1 1 16h result 1/1 1 1 16h vote 5/5 5 5 16h worker 1/1 1 1 16h cloudexperts@master1:~/example-voting-app/k8s-specifications$ kubectl delete -f vote-deployment.yaml deployment.apps "vote" deleted cloudexperts@master1:~/example-voting-app/k8s-specifications$ kubectl create -f vote-deployment.yaml deployment.apps/vote created cloudexperts@master1:~/example-voting-app/k8s-specifications$ kubectl get deploy -n vote NAME READY UP-TO-DATE AVAILABLE AGE db 1/1 1 1 16h redis 1/1 1 1 16h result 1/1 1 1 16h vote 1/1 1 1 13s worker 1/1 1 1 16h
Just as we did with the Replicaset, let’s scale it:
cloudexperts@master1:~/example-voting-app/k8s-specifications$kubectl scale deploy vote --replicas=5 -n vote deployment.apps/vote scaled cloudexperts@master1:~/example-voting-app/k8s-specifications$ kubectl get deploy -n vote NAME READY UP-TO-DATE AVAILABLE AGE db 1/1 1 1 16h redis 1/1 1 1 16h result 1/1 1 1 16h vote 5/5 5 5 108s worker 1/1 1 1 16h cloudexperts@master1:~/example-voting-app/k8s-specifications$ kubectl get rs -n vote NAME DESIRED CURRENT READY AGE db-6789fcc76c 1 1 1 16h redis-554668f9bf 1 1 1 16h result-79bf6bc748 1 1 1 16h vote-7478984bfb 5 5 5 2m30s worker-dd46d7584 1 1 1 16h cloudexperts@master1:~/example-voting-app/k8s-specifications$ kubectl get pods -n vote NAME READY STATUS RESTARTS AGE db-6789fcc76c-kkfnk 1/1 Running 0 16h redis-554668f9bf-7qt2x 1/1 Running 0 16h result-79bf6bc748-rhrv8 1/1 Running 58 16h vote-7478984bfb-2vhdz 1/1 Running 0 30s vote-7478984bfb-9cd48 1/1 Running 0 30s vote-7478984bfb-bmm2w 1/1 Running 0 30s vote-7478984bfb-wwcv5 1/1 Running 0 30s vote-7478984bfb-xps5h 1/1 Running 0 2m1s worker-dd46d7584-4dzzx 1/1 Running 1 16h
As we scaled the deployment, the ReplicaSet is used to perform the actual scaling, so RelicaSet also reflects 5 replicas. When we check the pods, the Pods also reflect 5 Pods running. This shows us that as we scale the deployment, ReplicaSets and the Pods are being controlled by the Deployment object. If you look carefully, you will see a resemblance of the objects:
Name of Deployment object: vote
Name of ReplicaSet: vote-7478984bfb
Name of Pod: vote-7478984bfb-2vhdz
Deployment:
vote 5/5 5 5 108s
ReplicaSet:
vote-7478984bfb 5 5 5 2m30s
Pods:
vote-7478984bfb-2vhdz 1/1 Running 0 30s vote-7478984bfb-9cd48 1/1 Running 0 30s vote-7478984bfb-bmm2w 1/1 Running 0 30s vote-7478984bfb-wwcv5 1/1 Running 0 30s vote-7478984bfb-xps5h 1/1 Running 0 2m1s
With the Deployment object, we no longer need to use the ReplicaSet object directly. Instead, we can use the Deployment object to control the ReplicaSet and the Pod. The features of the deployment object mentioned in the summary will be addressed in other blogs. Before we do that, we need to understand the service object. This will be addressed in the next blog.