Kubernetes – Deployments and ReplicaSets
It’s my third post in my Kubernetes – Objects series. In my previous posts, we have discussed about Kubernetes (K8S) two primary objects that is Pods and Services. If interested, please access them with below links:
In this post, we are going to discuss two more important K8S (Kubernetes) Objects that is ReplicaSet and Deployments.
1. Introduction
Both ReplicaSet and Deployments objects are another important objects in K8S world. They are used to manage Pods easily.
A Deployment is a Kubernete’s object which is used to create, update and delete a set of Identical Pods. Yes identical Pods. That means it creates one or more set of the same Pods with the same container(s). Identical Pods are known as Replicas. In simple words, an instance of a Pod is a Replica.
Internally Deployment object uses ReplicaSet (which is another Kubernete’s object ) to manage Pods easily.
As shown in the above picture, ReplicaSet will take care of the managing Pod objects and Deployment is a wrapper of that ReplicaSet.
2. Why do we need Deployment? Why not just use Pods?
Here we need to understand why do we need a separate Kubernetes Deployment object, why cannot we use just Pods directly.
As discussed in my previous post at Kubernetes – Pods, Pods are ephemeral resources. That means they have very short life. They are deleted at any time. So we need to create, update and delete Pods manually. It’s not possible to check every Pod status and create whenever it’s required.
If your application needs high availability (i.e. available to users all the time, no downtime), that means when a Pod is deleted or down, a new Pod should be created automatically. And also we need to maintain more than one Pod (Identical Pods) so that user can access your application all the time. Those user requests traffic is managed parallel with multiple pods (multiple replicas)
Here Identical Pods means multiple instances of the same Pod, which contains the same containers but they have different IP addresses as shown below. Identical Pods are also known as Replicas.
As shown in the diagram, Deployment object will take care of all these things automatically. If we mention we need 3 replicas of my nginx pods, Deployment object creates a ReplicaSet object with 3 replicas with the same nginx pod. If one of the Pod gets deleted or down, Deployment object will create new Pod and replace it with deleted pod automatically. That means your application is accessible all the time.
If we combine Deployment object with Service object, they both take care of Load balancing and Highly availability of Pods.
NOTE:- In old versions of Kubernetes API, we were using ReplicationController as a Kind to support replication mechanism for Pods. Now its replaced by ReplicaSet kind.
2.1. Benefits of Deployment/ReplicaSet objects?
We need to understand the major benefits of using Deployment/ReplicaSet objects to mange pods:
- Highly Availability: As we can run multiple instances of the same Pod, they are accessible all the time even though one of Pods is down or killed.
- Failure Tolerance: As we can run multiple instances of the same Pod, we can get the benefit of failure tolerance. If one of the Pod is down or killed, other replica (the same Pod) is created automatically and provide the same services to the user.
- Horizontal Scalability: By running multiple instances of the same Pod, we can get horizontal scaling of our Pods automatically.
- Rolling Update: We can update new versions of our applications very easily without downtime.
- Decoupling: Deployment/ReplicaSet are loosely coupled with Pods that means they don’t own Pods and they are connecting each other with label selector.
3. How to know apiVersion value?
Every Kubernetes object has its API version and its defined using apiVersion element in YAML file. We can easily find out what is the apiVersion in different ways. Here we will discuss few ways.
We can find out the apiVersion of a K8S object by accessing this URL: Kubernetes API Reference Doc
3.1. apiVersion of Deployment object
Please click this URL: Kubernetes API Reference Doc then click on Deployment v1 apps from left panel we can understand what is the version of Deployment object as shown below:
We can use kubectl command to know the apiVersion of Deployment object as shown below:
The apiVersion of Deployment object is apps/v1
3.2. apiVersion of ReplicaSet object
Please click this URL: Kubernetes API Reference Doc then click on ReplicaSet v1 apps from left panel we can understand what is the version of ReplicaSet object as shown below:
We can use kubectl command to know the apiVersion of ReplicaSet object as shown below:
The apiVersion of ReplicaSet object is apps/v1
4. Kubernetes Deployment operations
Like Pods and Services objects, we can perform create, update, delete, list, scale-up and scale-down of a Deployment objects in two different ways:
- Imperative approach
- Declarative approach
For most of the scenarios, we recommend to follow Declarative approach to perform all K8S (Kubernetes) objects operations.
We will discuss each approach in detail in the coming sections with some useful examples.
4.1. Imperative Approach
In this section we will discuss how to create nginx deployment, nginx pod and its replicas using Deployment YAML file in imperative way.
We can create all three of them (Pod, ReplicaSet and Deployment) in a single step or separately.
To create a Deployment object and its associated Pod and ReplicaSet objects, please execute the following kubectl create command:
kubectl create deployments inginx-deploy --image=nginx
It creates all 3 objects as shown below:
We can also use deploy or deployment to do the same as shown below:
kubectl create deploy inginx-deploy --image=nginx kubectl create deployment inginx-deploy --image=nginx
All three deploy or deployment or deployments refer to the same Deployment object.
As shown in the above picture, please use this command to list all available K8S objects in the default namespace:
kubectl get all
If you want to access individual objects, please use these commands
To get all available Deployment objects in the default namespace:
kubectl get deploy kubectl get deployment kubectl get deployments
To get all available ReplicaSet objects in the default namespace:
kubectl get replicaset kubectl get rs
To get all available Pod objects in the default namespace:
kubectl get pods
To delete all 3 objects (Pod, ReplicaSet and Deployment), please execute the following command
kubectl delete deploy inginx-deploy
It deletes inginx-deploy Deployment object and also its associated Pod and ReplicaSet objects as shown in the below picture:
If we want delete only Deployment object and leave its associated Pod and ReplicaSet objects, please set –cascade flag as shown below. By default this flag is set to delete all its dependents too.
kubectl delete deploy inginx-deploy --cascade=orphan
It deletes only inginx-deploy Deployment object and leaves its associated objects as is as shown below.
NOTE:- Please go through 4.2.5. Cascading deletion section to understand how this –cascade flag works and all possible values.
If we observe above commands output, we can observe that we have created only one replicas of nginx Pod. If we want to create more than one replicas of a Pod, we need to use –replicas flag. By default, this flag is set to 1 thats why previous command has created only one replicas of our nginx pod.
Please use this command to create more than one replicas of nginx Pod
kubectl create deploy inginx-deploy --image=nginx --replicas=3
To scale up or down our replicas, we need to use kubectl scale command as shown below.
To scale up (increase number of Pods) nginx pods from 3 to 5, please run this command
kubectl scale deploy inginx-deploy --replicas=5
We can observe how many nginx pods are created as shown below:
To scale down (decrease number of Pods) nginx pods from 5 to 3, please run this command
kubectl scale deploy inginx-deploy --replicas=3
We can observe how many nginx pods are deleted as shown below:
Here we can observe that two replicas are deleted and only 3 replicas are up and running.
4.2. Declarative Approach
In this section we will discuss how to create nginx deployment, nginx pod and its replicas using Deployment YAML file in declarative way.
4.2.1. Deployment YAML Syntax
Here we will discuss Deployment object YAML file syntax with possible values.
apiVersion: apps/v1 kind: Deployment metadata: spec: replicas: selector: templage:
Here we need to understand mainly 4 the following things:
- apiVersion: Its Kubernetes API version. Each Kubernetes has its own API version. For Deployment and ReplicaSet objects, we need to use apps/v1 version.
- kind: In Kubernetes, everything is an Object. Here we need to define what kind of object we are going to create using this yaml file. For instance, Pod, Deployment, Service etc.
- metadata: We need to define the newly create deployment name.
- spec: It defines there major things:
- replicas: To define how many number of replicas we want for the given Pod. By default one replica is created.
- selector: To define matching labels between Deployment and Pod objects.
- template: To define required container details to deploy them into that pod.
4.2.2. Create a Deployment object
Create nginx deployment with three replicas using the following YAML file.
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels:
app: nginx
spec:
containers:
-name: nginx
image: nginx
Here we are trying to create a Deployment object with “nginx-deployment” name and 3 replicas of a Pod. That Pod should contain nginx container as defined in containers filed.
The “replicas” field defines three replicas we required as part of this deployment object.
Please execute the following kubectl command to create all three objects Deployment, ReplicaSet and Pod automatically.
kubectl apply -f nginx-deployment.yaml
Here we are using -f flag to specify deployment yaml file. We can also use “-file” flag, both “-f” and “-file” does the same. The “kubectl apply” command is used to create Kubernetes objects with the given YAML file. In this example, it creates a Deployment object with 3 ReplicaSets and each ReplicaSet with one Pod which contains an nginx container.
Please execute the following kubectl command to see all newly created objects in the current K8S cluster.
kubectl get all
We can observe the following objects are created:
We can observe that one deployment object is created with the given name “nginx-deployment” in that YAML file as shown below in the metadata section.
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment
One replicaset object is also created with the name “nginx-deployment-76d6c9b8c”. Here we can observe that replicaset name starts with it’s deployment name like <deployment-name>-<hash-code>.
Deployment name: nginx-deployment
Pod Template hash: 76d6c9b8c
So our replicatset name is nginx-deployment-76d6c9b8c
Please execute the following kubectl command to see only available replicaset objects in the current K8S cluster
kubectl get replicaset
or we can use this shortcut name “rs” also to list all available replicaset objects
kubectl get rs
Here please observe DESIRED, CURRENT and READY column values. That means how many Replicas of nginx Pod we have request, how many pods are created and how many pods are ready to use.
- DESIRED : How many pods we want, here we have requested 3 nginx pods. We can call it as Desired State.
- CURRENT: How many pods are up and running, here all 3 required nginx pods are created. We can call it as Current State.
- READY : How many pods are up and ready to use, here all 3 nginx pods are ready to access. We can call it as Ready State.
DESIRED CURRENT READY ------- ------- ----- 3 3 3
In the same way, please execute the following kubectl command to know how many pods are created and how many pods are ready to use at the moment.
kubectl get pods
Here we can observe that 3 nginx pods are create and up, running and ready to use at the moment. If we observe pod names, we can understand that pod names start with or prefix with replicaset name that is <replicaset-name>-hash so our pod names are
nginx-deployment-76d6c9b8c-mrh9b nginx-deployment-76d6c9b8c-n97dx nginx-deployment-76d6c9b8c-vwfw9
4.2.3. What happens when we delete ReplicaSet only
Let us see what happen if we delete this nginx-deployment-76d6c9b8c ReplicaSet only.
When a ReplicaSet is associated with a Deployment and if we delete that ReplicaSet, we can observe that same ReplicaSet is recreated but it’s replicas that is Pods are deleted and recreated with different hash value. We can observe the same in the above picture. When we run kubectl get pods for first time, we saw zero nginx Pods are ready under READY column, later one by one all 3 Pods are created because we defined our nginx-deployment Deployment object with replicas=3.
Now we can observe 3 different nginx Pods are created as shown below:
nginx-deployment-76d6c9b8c-4s8wx nginx-deployment-76d6c9b8c-bhwlh nginx-deployment-76d6c9b8c-vrcwb
4.2.4. What happens when we delete Pod only
In the same way, if we delete one of those 3 Pods, it will happen the same thing. It is deleted first then recreated automatically because we defined our nginx-deployment Deployment object with replicas=3 as shown below:
4.2.5. Cascading deletion
When we delete a Deployment object, we can use –cascade flag to let the Kubernetes API Server what to do its dependents that is ReplicaSet and Pods. This flag allows one of these 3 values:
- background: If we use this –cascade=background option, the Kubernetes API Server deletes the main object (that is Deployment object) immediately and deletes its dependents in the background. This is the default value if we don’t use this flag.
- foreground: If we use this –cascade=foreground option, the Kubernetes API Server moves the main object (that is Deployment object) into deletion in progress state then it deletes its dependents first then it deletes main object.
- orphan: If we use this –cascade=orphan option, the Kubernetes API Server deletes the main object (that is Deployment object) immediately and leaves its dependents as is.
When we delete a Deployment object, by default it deletes Deployment object and all its associated ReplicaSet and Pods automatically as shown below:
kubectl delete -f nginx-deployment.yaml
Here by default –cascade=background option is used.
When we delete a Deployment object with –cascade=orphan option, it deletes only Deployment object and leave all its associated ReplicaSet and Pods as is as shown below:
kubectl delete -f nginx-deployment.yaml --cascade=orphan
Here we can observe that only nginx Deployment object is created and all its associated objects are working as is.
5. How Deployment or ReplicaSet pickups it’s dependents?
Like Service objects, as we discussed in our previous post Kubernetes – Services, Deployment or ReplicaSet objects are also uses Label Selector to search and pickup it’s dependents.
If we observe nginx Deployment object’s Selector, we know that it has app=inginx-deploy as selector clause as shown below:
and observe its associated ResultSet object’s Selector clause as shown below:
Here we can observe two labels are defined for ResultSet object app=inginx-deploy and pod-template-hash=58bc7b6cc4. Deployment object selects this subset of Labels that is app=inginx-deploy and consider it as its dependent.
In the same way, object this nginx Pod Labels as shown below:
Here also we can observe that the same two labels are defined for Pod object app=inginx-deploy and pod-template-hash=58bc7b6cc4. So that ResultSet object uses these Labels and consider it as it’s dependent.
In K8S world, Labels and Selector clause pay a key role in connecting objects with it’s dependents.
Here we have taken all 3 objects which are created in imperative approach. We can observe the same thing in Declarative approach where we define all Labels and Selector clause in YAML file as shown below:
Even if we create 3 different YAML files for 3 different objects that is Pod, ResultSet and Deployment, we can define this Label Selector easily.
6. Create Objects separately
So far we have discussed how to create 3 objects in a single step that is one kubectl command in imperative way or one YAML file in declarative way. But we create them separate by defining correct Labels and Selectors as shown below.
6.1. Create Deployment, ResultSet and Pods separately in Imperative way
Here we will discuss how to create these 3 objects using different kubectl commands in imperative way.
First create a nginx Pod using below kubectl command with our required labels:
kubectl run nginx --image=image -l app=nginx-deployment,pod-template-hash=5fbdf85c67
Here we can observe that our new nginx Pod is created with the following two labels:
app=nginx-deployment pod-template-hash=5fbdf85c67
As I’m going to use the same app Label Selector in creating Deployment and ReplicaSet objects and also by default ReplicaSet Selector clause use the pod-template-hash label. This label is created by default with current nginx container image. Please check this value with your ReplicaSet object.
Please execute the following the kubectl command to create Deployment and ReplicaSet objects with required labels and Label Selector as shown below:
kubectl create deployment nginx-deployment --image=nginx
By default this command creates two objects:
- One nginx-deployment Deployment object with the same label and Label Selector value that is app=nginx-deployment
- One nginx-deployment-5fbdf85c67 ReplicaSet object with the same label value that is app=nginx-deployment and Label Selector value as app=nginx-deployment,pod-template-hash=5fbdf85c67
That’s why we have created our nginx Pod with these two labels app=nginx-deployment,pod-template-hash=5fbdf85c67 in previous step.
To prove all these 3 objects (Pod, Deployment and ReplicaSet objects) are connected each other or not, please execute the following kubectl command:
kubectl delete deploy nginx-deployment
Here we can observe that all 3 objects are deleted automatically that means they all are connected each other.
6.2 Create Deployment, ResultSet and Pods separately in Declarative way
Here we will discuss how to create these 3 objects using 3 different YAML files in declarative way.
First we define a yaml file to create nginx Pod object(s) as shown below:
apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx-deploy spec: containers: - name: nginx image: nginx
Here we used the same file like my previous posts on Pods or Services, but added one new section that is labels as shown below:
labels: app: nginx-deploy
Here we defined a label so that ReplicaSet object, which having similar kind of Label Selector will pickup this Pod automatically.
Now we define a yaml file to create nginx ReplicaSet object as shown below:
apiVersion: apps/v1 kind: ReplicaSet metadata: name: nginx-rs labels: app: nginx-deploy spec: replicas: 3 selector: matchLabels: app: nginx-deploy template: metadata: labels: app: nginx-deploy spec: containers: - name: nginx image: nginx
We are seeing ReplicaSet’s YAML file for first time, but it looks like similar to Deployment object’s YAML file. Yes everything is same except kind field is assigned to ReplicaSet value.
Here we need to observe Labels and Selector clause. Lebel Selector clause is having the same value like Pod’s label definition.
Now we define a yaml file to create nginx Deployment object as shown below:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx-deploy spec: replicas: 3 selector: matchLabels: app: nginx-deploy template: metadata: labels: app: nginx-deploy spec: containers: - name: nginx image: nginx
This is almost similar YAML file, we discussed in Declarative section in this post except we changed some labels and Label Selector values to match with ReplicaSet’s YAML file label values.
Now we have 3 separate YAML files available. It’s time to start creating them one by one and check whether they are connected each other or not at end.
Please execute the following kubectl command to create our new nginx pod as shown below:
kubectl apply -f nginx-pod.yaml
Here we can observe that only one nginx Pod is created. It’s about to up and running. We will see its status in the coming images.
Please execute the following kubectl command to create our new nginx ReplicaSet as shown below:
kubectl apply -f nginx-replicaset.yaml
Here we can observe that ReplicaSet has taken existing Pod (because it matches with ReplicaSet’s Label Selector clause) and create two more replicas that means we can observe 3 nginx pods are created.
Please execute the following kubectl command to create our new nginx Deployment as shown below:
kubectl apply -f nginx-deployment.yaml
Now we can observe that all 3 objects are created. Just to prove whether they all are connected to each other or not, please execute the following kubectl command:
kubectl delete -f nginx-deployment.yaml or kubectl delete deploy nginx-deployment
Now we can observe that all objects (one Deployment and its associated objects that is one ReplicaSet and 3 Pod replicas) are deleted automatically because they all are connected to each other with the correct Label and Label Selectors as shown below:
7. Conclusion
So Deployment and ReplicaSets are other important objects in Kubernetes (K8S) cluster.
Deployment object is used to manage ReplicaSet easily and ReplicaSet objects are used to create multiple instances of the same Pod. An instance of a Pod is also known as a replica.
If we use Deployment and ReplicaSet to manage our Pods, we will get many benefits like High Availability, High Scalability, Zero downtime, Rolling updates, etc.
It’s recommended to follow a declarative approach to create, update and delete any kind of K8S objects. But sometimes imperative approach is useful.
That’s it about Kubernetes Deployment and ReplicaSet objects. We will meet in my next post with another important concept of K8S.
Happy Learning!
8. Download
This was an example of how to create K8S (Kubernetes) Deployment and ReplicaSet objects in declarative way.
You can download the full source code of this example here: Kubernetes – Deployments and ReplicaSet