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.
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:
## 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.
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:
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:
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 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.