K8s Objects - Part 1 [Pods and Replicasets]
Tags: kubernetes, beginners, pods, replicasets
Published: 2021-10-21 20:07:26

The Kubernetes objects are the persistent entities of the K8s system that collectively represent the state of the system. An object includes two attributes spec and status. Spec is the desired or requested state while status is the current state of the object. These object types are also referred to as API resources in the K8s ecosystem.

In this blog series, we will understand the concept behind a few K8s objects and create them. We can create K8s objects by using Yaml files and Kubectl (Kubernetes command line interface is used to communicate with the K8s cluster). You need to setup Kubernetes (use minikube if you are a newbie to K8s ecosystem) and install Kubectl in order to create K8s objects in your machine.

Let's begin!

**Intro to K8s object - Yaml file:**

The resource specifications are provided in the Yaml descriptor file and Kubectl uses this file to create the required K8s object with given specifications. 

Let’s understand the four basic / widely used fields in the Yaml descriptor file used to create K8s objects.

`apiVersion` -> This is the version of the Kubernetes we are using to create the Pod. We need to make sure that the object we want to create is supported in the given version. 
Example: v1, apps/v1

`Kind` -> The object / resource type we are intending to create.
Example: Pod, ReplicaSet, Deployment

`Metadata` -> It is the data about the object.
Example:
name -> Takes a string value that indicates the name of the object
labels -> It is a list of key value pairs. You can add your custom keys and values here. We will see how this is used later in this series of blogs. 

`Spec` -> This field is used to describe what exactly you want Kubernetes to build. The values/structure of this section varies from object to object.
Example: 
For Pod objects, this section will contain container specifications
For Service objects, this section will contain Pod selector specifications 

Given that we know how to create yaml descriptor files using the above fields, lets understand and create a few K8s objects.

**Pod**

The smallest deployable unit that can be created and managed in the K8s architecture is Pod. It is a collection of one or more containers, along with volume storage, network stack and namespace.

In Microservices architecture, every service can be analogized to a single Pod with multiple containers. Yes, even though a single container is sufficient to run your application, Pod which is a collection of containers is visualized to be a single application / service. 

This is because all the containers in the Pod are relatively tightly coupled. The other containers act as helper applications to support the primary application. For example, the helper applications can be data pullers, data pushers or proxies. This kind of pattern where one container is the main application and another container supports/improves the main application functioning is called the **Sidecar patter**

> Scalability Factor

* Say you want to scale out instances of your containerised application, the right way is to increase the number of Pods and not the number of containers inside the same Pod.
* You need to 'replicate' the Pod - with the same number of containers to achieve scalability in K8s world.

> Networking

* There are two types of communication in K8s involving Pods, Intra-Pod and Inter-Pod communication.
* Intra-Pod communication is where two or more containers within the same Pod communicate with each other. These containers share the same network namespace via localhost through Port binding for each container.
* Inter-Pod communication is where, each Pod is assigned a  cluster-private IP address. Hence the Pods use assigned IP address to communicate with other Pods within the same K8s Cluster private network. 

> Resilience 

* When the process running in your container crashes for some reason, K8s assures Pod resilience of starting it again. 
* On root process crash, the container status will go into 'Error' state. K8s will restart the container in the same Pod. It would come back into 'Running' state with restart count incremented.

> Let's see it in action

In order to create a Pod object, we need a Yaml file similar to the one given below,

pod-demo.yaml

![Pod demo configuration yaml file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/il14t8ypt2cw2z5njm25.png) 
 
```
 Kubectl apply -f pod-demo.yaml
```

Executing the above command will create a Pod named frontend-pod. It will be created with the ‘tier’ label with the value as ‘front-tier’. This will wrap a container which uses nginx image and has an environment variable with name as some-key and value as some-value

```
kubectl get pods 
```

This command will show the Pods running in the default namespace where you can find frontend-pod.
or just get your pod by suffixing your Pod name

```
kubectl get pods frontend-pod
```
To get detailed report, you can suffix `-o wide`

```
kubectl get pods frontend-pod -o wide
```

![Kubectl commands](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yhotzu3dfe4gfonn6fnj.png)
 
Having known about Pods now, lets check out Replicaset! 

**ReplicaSet**

"Helps in deploying scalable applications"

This is one of the promises K8s offers you. But to scale Pods... Should we keep creating / deleting the Pods manually ?
And what if one of the running Pod goes down ? Should it be brought back manually ?
Of course, Not!

To enhance the capability of Pod by adding scalability and reliability is our next K8s object. Lets explore Replicaset!

Replicaset is an abstraction over Pod, which ensures the given number of Pods are always up and running.

Sounds like some Magic, right? :) 
Well it does it with the help of Reconciliation control loop.

> Reconciliation control loop 

* The first phase is "Observe". K8s keeps observing two states.

=> Desired state -> State provided in the request.
=> Current state -> State of the K8s cluster

* Next it "detects" out the difference between both the states.
* Then, takes necessary steps to "adjust" the difference. It can be removing an extra Pod or adding another Pod in case of failure.

![Reconciliation control loop](https://media.giphy.com/media/lXV4NHwDxi3cSggJvR/giphy.gif)

And as the name suggests, this keeps going in loops.
For explanation on how K8s internally does this, please checkout the K8s architecture blog. {% link https://dev.to/ktnl/get-introduced-to-kubernetes-architecture-14fo %}.

Well, how replicaset is able to track its Pods to arrive at a count ? Does it have any hash Key / identifier based on Pod configuration. Relax, it's not that complex 🧘‍♀️. It uses Labels and Selectors.

> Labels and Selectors

We already know what are labels, the metadata section of the Pod Yaml file offers us to define our custom labels. Based on these labels, the Pods are grouped. But for attaching this group to a replicaset, we need Selectors.

Selectors are again Key Value pairs similar to Labels, that are defined at replicaset level.

> Let's see it in action

A typical replicaset yaml file looks like this,

rs-demo.yaml

![Replicaset yaml file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4d6uzo41aie5cpeb00ua.png)
 

* As highlighted, the Pod configuration is given under template - This is like just copy pasting metadata and spec section of the Pod yaml to template section of replicaset yaml.

* The replica attribute in Spec section gives the number of Pods the replicaset should create and manage.
 
* The selector section's matchLabels and the container template labels should match. 

```
kubectl apply -f rs-demo.yaml
```

This will create a replicaset which is responsible for maintaining the 3 Pods with the afore mentioned spec configured.

To checkout the replicaset that got created use,

```
 Kubectl get replicaset 
```

or

```
 Kubectl get rs 
```

rs is the short form for replicaset. `replicaset` and `rs` can be used interchangeably for Kubectl commands.


> Power of `rs`

* When a Pod managed by replicaset goes down 💥 ...
Lets delete one of the Pods created by the replicaset above.

```
kubectl delete pod {pod_name}
```

In matter of few seconds you will see a new Pod with same configuration getting spun up.

![Deleting a Pod managed by Replicaset](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ybdedkd3ubnqppvi0pm.png)
 
* Dare to (you can't 😛) create an extra copy of Pods managed by replicaset
Now, lets create another pod with same label manually.

same-pod-config-demo.yaml

![same-pod-config-demo yaml file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdwotae92ya0u65ii1ru.png)
 
As guessed K8s will delete the latest or 4th or the extra Pod in few seconds to ensure only 3 (desired count) Pods are running.

![Creating extra Pod with same label](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/crglrpppf1zpouxcw7bc.png)

* Scale in / out your Pods

If you want to scale in / out your Pod count, you can modify the replicaset yaml and apply the change.

Say you need 4 Pods, just change `replicas` attribute in replicaset yaml to 4 from 3.

And apply the change with the same command.

You will notice that a new Pod with the same configuration will be started.

![Scale out Pods](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tsx98b1rb3j52ov34ux1.png)
 
Same works if you want to scale in Pods as well.

And...
* Get rid of it, at ease!

If you want to delete all the Pods managed by this replicaset... don't worry you are just one command away.

![Delete rs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l4b4n2dgmajv50ozglkm.png)
 

Hope you enjoyed knowing Pod and Replicaset concepts and ready to practise some in real projects. 

Stay tuned to know about other K8s Objects in the upcoming blogs of the same series.


Happy learning!