Dev Ops Kubernetes

Kubernetes ReplicaSet Tutorial

Kubernetes is often seen as this huge body of interrelated concepts like nodes and pods , services, deployments, etc which are often difficult to untangle. In this post, let’s slowly unravel a key abstraction which is ReplicaSet. We will begin by creating a small .yaml file for a Kubernetes pod, which would have a label to it, and then create a ReplicaSet which would ensure that a certain number of pods with the same label are always running in the cluster . This is what project authors actually intended when they were designing Kubernetes. So let’s start.

Prerequisites

The first thing you would need will be access to a Kubernetes cluster. You can create one using Minikube or use Docker for Windows or Docker for Mac both of which now come with a single node Kubernetes distribution which you can enable in Docker’s settings.

You would also need to have some a priori knowledge about Kubernetes. Here’s a really good starting point.

Creating Pods

Typically, we create pods using a yaml file which specifies what container image to use, which ports to expose, etc. Here is a simple file to create an nginx pod.

apiVersion: v1
kind: Pod
metadata:
name:  nginx-1
label:
app: webserver
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80

Save it under the name nginx-pod.yaml in a directory, and then from inside the same directory run the command:

$ kubectl create -f ./nginx-pod.yaml
## Verify that the pod is created by running:
$ kubectl get pods

You will notice that a single pod named “nginx-1” is up and running. But you can’t scale this single pod. Running kubectl create again will give you an error since the name nginx-1 can’t be reused again.

Kubernetes has given the capability create pods to higher abstractions like Deployments and ReplicaSets. Which create pods from a given pod template specifying what images to use, what ports to expose in each of the new pods, etc, but nothing too specific about a single pod. ReplicaSet (and Deployments, as well) then go about creating new pods, giving each new pod a unique name as well as a non-unique label which helps the ReplicaSet to keep track of the pods that were created from a given template.

ReplicaSet ensures that at any given instant a certain number of pods of a given label are always up and running. If, for example, a node goes down, it is the job of ReplicaSet to create more pods across other nodes to compensate for the loss. To write a replicaset yaml file, we would follow the pattern similar to writing a pod. It will have an api version (apps/v1), a type (ReplicaSet) and a name in the metadata. The replicaset itself can have labels on it, but we will keep things simple for now and just give it a unique name my-replicaset.

We then need move from metadata section to the meat of matter spec. Here we provide the number of replications we want under the section replicas. Then we give this ReplicaSet a selector which would be used to match a label, say, app to a value, say, webserver, amongst the currently running pods. If there are fewer of these pods, then it will create pods according to the given template and add the same label to these new pods. If there are more pods than required, then it deletes a few.

Specifying a template which would act as a base for creating new pods is the most involved step. This template will not have a name, since replicaset will create a new name for every new pod created. The will have labels, however, and you can notice that the same label app=webserver that the template has is selected via the selector parameter in the replicaset spec.

apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: my-replicaset
 
spec:
replicas: 3
selector:
matchLabels:
app: webserver
template:
metadata:
labels:
app: webserver
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80

Save this file as nginx-replicaset.yaml and create the replicaset using the command:

$ kubectl create -f nginx-replicaset.yaml

Because we previously created a pod with the same label app=webserver, the replicaset would just create two more pods. You can list all the pods using the command:

$ kubectl get pods
NAME                  READY     STATUS    RESTARTS   AGE
my-replicaset-nmvt9   1/1       Running   0          9s
my-replicaset-xf9mx   1/1       Running   0          9s
nginx-1               1/1       Running   0          28s

Each of the pods will have a unique name associated to them. Like the very first pod we created had a name nginx-1. You can try deleting this one using the command:

$ kubectl delete pod nginx-1
$ kubectl get pods
 
NAME                  READY     STATUS    RESTARTS   AGE
my-replicaset-nmvt9   1/1       Running   0          1m
my-replicaset-pkn4q   1/1       Running   0          22s
my-replicaset-xf9mx   1/1       Running   0          1m

You will notice that almost instantaneously the controller ReplicaSet created a new pod to replace the one we deleted. Thus ensuring that the number of running pods, with label app=webserver is always 3, as specified in our replicaset manifest, above.

You get a lot of control thanks to labels and selectors. You can further spread the pods across multiple nodes using nodeSelectors, which are used to allocate a certain number of pods on a certain nodes.

What replicasets don’t allow are updates. If a newer version of your app, say, nginx:1.8 comes along, you will have to delete this replicaset and create a new one with that image mentioned in the replicaset’s yaml manifest. This is where the concept of deployments comes in handy. It includes the idea of replicasets and extends by providing additional support for updating yours apps. Now that you are comfortable with replicasets, it may be a good idea to look into Kubernetes Deployments.

References

  1. Creating Pods
  2. Creating ReplicaSets

About the author

Ranvir Singh

Ranvir Singh

I am a tech and science writer with quite a diverse range of interests. A strong believer of the Unix philosophy. Few of the things I am passionate about include system administration, computer hardware and physics.