How to run MondoDB on Kubernetes using StatefulSets ?

How to run MondoDB on Kubernetes using StatefulSets ?

MongoDB is a stateful workload which can be run on k8s using StatefulSets.

What are StatefulSets?

StatefulSets is a Kubernetes controller that can be used to manage stateful applications such as MongoDB, MySQL that require

  • Stable - Unique network identifiers, persistent storage

  • Ordered - Graceful deployment, scaling and automated rolling updates.

Prerequisites

Make sure that Docker is running.

Start the minikube cluster using minikube start.

Creating MongoDB Service

Create mongodb-svc.yaml

apiVersion: v1

kind: Service

metadata:

name: mongodb

labels:

app: mongodb

spec:

clusterIP: None

selector:

app: mongodb

ports:

 - port: 29000

targetPort: 29000

Use the following commands to create the MongoDB service

$ kubectl apply -f mongodb-svc.yaml 

service/mongodb created
$ kubectl get svc 

NAME    TYPE      CLUSTER-IP EXTERNAL-IP PORT(S)   AGE 

mongodb ClusterIP None       <none>      29000/TCP 14s

Create StatefulSet for MongoDB

Create mongo-statefulSet.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb
spec:
  selector:
    matchLabels:
      app: mongodb
  serviceName: mongodb
  replicas: 3 
  template:
    metadata:
      labels:
        app: mongodb # has to match .spec.selector.matchLabels
    spec:
      containers:
      - name: mongodb
        image: mongo:4.0.17
        ports:
        - containerPort: 29000
        volumeMounts:
        - name: pvc
          mountPath: /data/db
  volumeClaimTemplates:
  - metadata:
      name: pvc
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi
$ kubectl apply -f mongodb-statefulSet.yaml 

statefulset.apps/mongodb configured

Check the number of replicas running

$ kubectl get pod
NAME                                 READY   STATUS             RESTARTS   AGE
mongodb-0                            1/1     Running            0          79s
mongodb-1                            1/1     Running            0          7s
mongodb-2                            1/1     Running            0          4s

Scaling pods

We can scale the replicas using kubectl scale statefulset mongodb --replicas=3.

Connecting to mongo-shell

$ kubectl run -it mongo-shell --image=mongo:4.0.17 --rm -- /bin/bash
If you don't see a command prompt, try pressing enter.
root@mongo-shell:/# mongo mongodb-0.mongodb

In the mongo-shell, run mongo mongodb-0.mongodb to connect the mongo-db pod when mongodb-0 is the name of the pod.

After connecting to the desired pod, insert some datas

> db.test.insert({ name: "Pod1"})
WriteResult({ "nInserted" : 1 })
> db.test.find()
{ "_id" : ObjectId("6617aebbbdfaf1519746cc35"), "name" : "Pod1" }
> exit
bye
root@mongo-shell:/# exit
exit
Session ended, resume using 'kubectl attach mongo-shell -c mongo-shell -i -t' command when the pod is running
pod "mongo-shell" deleted

After exiting mongo-shell, delete the pod that you connected to above.

$ kubectl delete po mongodb-0
pod "mongodb-0" deleted

List the number of pods running.

$ kubectl get pod
NAME                                 READY   STATUS             RESTARTS   AGE
mongodb-0                            1/1     Running            0          13s
mongodb-1                            1/1     Running            0          9m7s
mongodb-2                            1/1     Running            0          9m4s

As you can see still there are 3 pods of mongodb running since we set the --replicas=3 . The pod mongodb-0 is created again instantly after the deletion of old pod, you can it was created 13s ago in AGE column. Now again login to the same pod using these commands.

$ kubectl run -it mongo-shell --image=mongo:4.0.17 --rm -- /bin/bash
If you don't see a command prompt, try pressing enter.
root@mongo-shell:/# mongo mongodb-0.mongodb

After connecting to mongodb-0 try to find the datas using

> db.test.find()

{ "_id" : ObjectId("6617aebbbdfaf1519746cc35"), "name" : "first pod" }

> exit

bye

You can see here that although we deleted the pod and it was recreated, the volume associated with the pod is persistent and not erased also when a pod is recreated the pod name doesn't change.

Deletion of pods

To terminate the pods and avoid recreation of pods set --replicas=0 and then delete you want to delete.

kubectl scale statefulset mongodb --replicas=0

Then run

kubectl delete pod mongodb-0