MongoDB is an open-source document-oriented no SQL database. It uses JSON and BSON to store the data. MongoDB replicaset is the cluster of MongoDB nodes divided into a primary node and one or more secondary nodes. Primary node acts as the master node and is responsible for write operations. The secondary nodes and the primary node can both be used for read operation. From hereon, we will be using replicaset to denote MongoDB replicaset and not the Kubernetes replicaset.
Prerequisites:
- A Kubernetes Cluster (I will be using minikube single node cluster on my local system)
Deploying the MongoDB Cluster
Deploy the Headless Service for node discovery
We will need to deploy a headless service so that the mongodb nodes can communicate with each other. So we create the yaml manifest mongodb-headless.yml
apiVersion: v1
kind: Service
metadata:
name: mongodb-headless
spec:
clusterIP: None
publishNotReadyAddresses: true
ports:
- name: mongodb
port: 27017
targetPort: 27017
selector:
app: mongodb
Use the following command to deploy the above yaml manifest.
kubectl apply -f mongodb-headless.yml
Deploy the Config Map
We will need to deploy a Config Map with the scripts to elect a primary node when the replicaset is initialized. So we create the yaml manifest mongo-config.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: mongo-config
data:
script.sh: |-
#!/bin/bash
if [[ "$POD_NAME" = "mongodb-0" ]];
then
export MONGODB_REPLICA_SET_MODE="primary"
else
export MONGODB_INITIAL_PRIMARY_PORT_NUMBER="27017"
export MONGODB_REPLICA_SET_MODE="secondary"
fi
exec /opt/bitnami/scripts/mongodb/entrypoint.sh /opt/bitnami/scripts/mongodb/run.sh
Use the following command to deploy the above yaml manifest.
kubectl apply -f mongo-config.yml
Persisting the Data
Since we are using minikube we will be using the minikube hostpath storage provisioner to create persistent volumes. For cloud based clusters, you can use any cloud native provisioners.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: minikube-hostpath
provisioner: k8s.io/minikube-hostpath
reclaimPolicy: Delete
Creating the StatefulSet
MongoDB is a stateful application. So we will be using statefulset to deploy the replicasets. Some key features to note are:
- We will be using bitnami image of mongodb as it is fully configurable using environment variable
- Containers of Bitnami images are non root containers running with user 1001.
- We will be using security contexts to change the group of the files in the volume mounted.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
namespace: capstone
spec:
serviceName: mongodb
selector:
matchLabels:
app: mongodb
replicas: 3
template:
metadata:
labels:
app: mongodb
spec:
securityContext:
fsGroup: 1001
containers:
- name: mongodb
image: bitnami/mongodb
imagePullPolicy: IfNotPresent
env:
- name: MONGODB_DISABLE_SYSTEM_LOG
value: "false"
- name: MONGODB_SYSTEM_LOG_VERBOSITY
value: "1"
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MONGODB_REPLICA_SET_NAME
value: "replicaset"
- name: MONGODB_INITIAL_PRIMARY_HOST
value: "mongodb-0.mongodb"
- name: MONGODB_ADVERTISED_HOSTNAME
value: "$(POD_NAME).mongodb"
- name: ALLOW_EMPTY_PASSWORD
value: "yes"
command:
- /scripts/script.sh
securityContext:
runAsUser: 1001
volumeMounts:
- name: config
mountPath: /scripts
- name: data
mountPath: /bitnami/mongodb
volumes:
- name: config
configMap:
name: mongo-config
defaultMode: 0755
items:
- key: script.sh
path: script.sh
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 1Gi
storageClassName: minikube-hostpath
Use the following command to deploy the above yaml manifest.
kubectl apply -f mongodb-sts.yml
Verifying the replica set deployment and accessing the replica set
If we execute the commands: kubectl get sts mongodb
and kubectl get pods -l app=mongodb
, we see the cluster deployed.
We can exec into any of the nodes in the replicaset and check the status. So, we will be using the following command:
kubectl exec -it mongodb-0 -- mongo
After executing the command we will get get a prompt similar to:
Then execute the following command:
rs.status()
The above command returns the replica set status. We can see the list of members in the replica set from the configuration.
We can scale the number of replicas using the command:
kubectl scale sts mongodb --replicas 5
CONCLUSION
In this blog, we have setup a three node MongoDB cluster. We also looked at how to scale the number of nodes. In this blog, we have setup a cluster which does not require user authentication. We can also set up a cluster with authentication enabled. We need to use other environment variables listed in the project’s Github Readme. I have provided the link to the Github repository incase you need to head for additional informations.
REFERENCES
- Github Repository: https://github.com/bitnami/bitnami-docker-mongodb
- Replication and sharding: https://blog.knoldus.com/mongodb-replication-and-sharding/
2 thoughts on “How to deploy MongoDB cluster on Kubernetes4 min read”
Comments are closed.