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