Table of contents
1.
Introduction
2.
Kubernetes and MongoDB
2.1.
Kubernetes
2.2.
MongoDB
3.
Setting up the MongoDB on Kubernetes
3.1.
Step 1: Label the Node
3.2.
Step 2: Create a Storage class
3.3.
Step 3: Create Persistent Storage
3.4.
Step 4: Create ConfigMap
3.5.
Step 5: Create a StatefulSet
3.6.
Step 6: Create a Secret
3.7.
Step 7: Create a MongoDB Service
3.8.
Step 8: Using Kustomize to Apply the MongoDB configuration
3.9.
Step 9: Connect to a MongoDB instance.
4.
Deploy a ReplicaSet
4.1.
Step 1: Set up Role-Based Access Control (RBAC)
4.2.
Step 2: Create a StatefulSet Deployment
4.3.
Step 3: Create a headless Service
4.4.
Step 4: Set up the Replication Host
5.
Frequently Asked Questions
5.1.
What is Kubernetes used for?
5.2.
What is Kubernetes Pod?
5.3.
What is Kubernetes Service?
5.4.
What do you mean by ReplicaSet in Kubernetes?
5.5.
What is Kubernetes Namespace?
6.
Conclusion
Last Updated: Mar 27, 2024
Medium

Deploy, Run, and Install MongoDB on Kubernetes

Author Vidhi Sareen
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

MongoDB is a database suitable for many uses and stores information flexibly. Just like things need to grow bigger and be quick, MongoDB also cares about that. When MongoDB teams up with Kubernetes, they make large databases to produce and transmit information quickly. These unique databases are great when you have a lot of information, traffic, and user requests, which make it very busy.

Deploy, Run, and Install MongoDB on Kubernetes

This article is like a guidebook. It will show you how to put MongoDB on Kubernetes. It will explain how a user can Deploy, Run, and Install MongoDB on Kubernetes.

Kubernetes and MongoDB

Kubernetes

Kubernetes, often shortened to K8s, is a refined system that manages and coordinates containers. Containers comprise condensed packages that encompass all the essential components required to facilitate an application's seamless operation. Kubernetes attracts developers because it streamlines deployment complexity, enhances scalability, ensures consistency across different environments, accelerates updates, and optimizes resource usage.

MongoDB

MongoDB is a distinctive database type that differs from traditional ones reliant on tables and rows. As a NoSQL database, it offers flexibility by organizing data into documents rather than rigid structures. It excels in scalability, accommodating vast datasets and high traffic, and providing fast query performance. MongoDB's features encompass document-based storage, flexible schema, replication for data redundancy, geospatial data handling, and ad hoc querying. Developers opt for MongoDB because it can swiftly adjust to changing data requirements, seamless scalability, quick query responses, and accommodating various data formats.

Setting up the MongoDB on Kubernetes

Here are the steps involved in setting up the MongoDB on Kubernetes. Before running the following steps, verify whether you have installed the Kubectl correctly or not.

output

Step 1: Label the Node

Give a name that will be used in MongoDB deployment. This name helps determine which programs (pods) go to which node.

First, get the nodes of the cluster. To do so, run the following command.

kubectl get nodes

 

Second, choose the deployment node from the list.

output

 

Third, run the kubectl to label the node.

kubectl label nodes <node> <key>=<value>
output

Step 2: Create a Storage class

StorageClass is like a helper for pods. It helps them get volume on the node. To make a StorageClass, run the following command.

1) Using a text editor to keep the storage setup information, You need to make a particular file using a text editor.

nano StorageClass.yaml

 

2) Put the storage class setup details in the file. Here's an example of how the MongoDB-storage class is described and saved in the file.

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: mongodb-storageclass
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

Step 3: Create Persistent Storage

To save data for MongoDB on Kubernetes, make a persistent space that keeps data even if things restart. 

1) To do this, create a file written in YAML.

nano PersistentVolume.yaml

 

2) In the file, assign storage space that matches the style you defined earlier. Specify the node for pod deployment in the nodeAffinity section. This node is picked based on the unique label you made in Step 1.

apiVersion: v1
kind: PersistentVolume
metadata:
    name: mongodb-pv
spec:
  capacity:
    storage: 2Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: mongodb-storageclass
  local:
    path: /mnt/data
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: size
          operator: In
          values:
            - large

 

3) Create an additional YAML file to configure the persistent volume claim. 

nano PersistentVolumeClaim.yaml

 

4) Name the claim "mongodb-pvc" and direct Kubernetes to request volumes that are part of the "mongodb-storageclass."

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mongodb-pvc
spec:
  storageClassName: mongodb-storageclass
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 2Gi

Step 4: Create ConfigMap

The ConfigMap file holds non-encrypted configuration details that pods use.

1) Create a YAML file to save the deployment configuration.

nano ConfigMap.yaml

 

2) Use the file to keep data about system paths, users, and roles. Here's an example of a ConfigMap file.

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongodb-configmap
data:
  mongo.conf: |
    storage:
      dbPath: /data/db

 

ninja-users.js: 

Below is the js for for creating the user:

const codingNinjasDbStr = 'test';
const codingNinjasRootUser = cat('/etc/k8-test/admin/NINJA_ROOT_USERNAME');
const codingNinjasRootPass = cat('/etc/k8-test/admin/NINJA_ROOT_PASSWORD');
const codingNinjasUsersStr = cat('/etc/k8-test/NINJA_USERS_LIST');

const adminDb = db.getSiblingDB('admin');
adminDb.auth(codingNinjasRootUser, codingNinjasRootPass);
print('Successfully authenticated!!');

const codingNinjasDb = db.getSiblingDB(codingNinjasDbStr);

const customRoles = adminDb
  .getRoles({ rolesInfo: 1, showBuiltinRoles: false })
  .map(role => role.role)
  .filter(Boolean);
codingNinjasUsersStr
  .trim()
  .split(';')
  .map(s => s.split(':'))
  .forEach(user => {
    const codingNinjasUsername = user[0];
    const rolesStr = user[1];
    const codingNinjasPassword = user[2];
    if (!rolesStr || !codingNinjasPassword) {
      return;
    }
    const roles = rolesStr.split(',');
    const userDoc = {
      user: codingNinjasUsername,
      pwd: codingNinjasPassword,
    };
    userDoc.roles = roles.map(role => {
      if (!~customRoles.indexOf(role)) {
        return role;
      }
      return { role: role, db: 'admin' };
    });
    try {
      codingNinjasDb.createUser(userDoc);
    } catch (err) {
      if (!~err.message.toLowerCase().indexOf('duplicate')) {
        throw err;
      }
    }
  });
You can also try this code with Online Javascript Compiler
Run Code

Step 5: Create a StatefulSet

Kubernetes uses the StatefulSet controller to deploy stateful applications, as these types of apps need distinct identities since they interact with other pods.

1) Create a YAML file.

nano StatefulSet.yaml

 

2) Put deployment details into the file, including the MongoDB Docker image to use. The file also points to the ConfigMap, and PersistentVolumeClaim made earlier.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb-test
spec:
  serviceName: mongodb-test
  replicas: 1
  selector:
    matchLabels:
      app: database
  template:
    metadata:
      labels:
        app: database
        selector: mongodb-test
    spec:
      containers:
      - name: mongodb-test
        image: mongo:4.0.8
        env:
          - name: NINJA_INITDB_ROOT_USERNAME_FILE
            value: /etc/k8-test/admin/NINJA_ROOT_USERNAME
          - name: NINJA_INITDB_ROOT_PASSWORD_FILE
            value: /etc/k8-test/admin/NINJA_ROOT_PASSWORD
        volumeMounts:
        - name: k8-test
          mountPath: /etc/k8-test
          readOnly: true
        - name: mongodb-scripts
          mountPath: /docker-entrypoint-initdb.d
          readOnly: true
        - name: mongodb-configmap
          mountPath: /config
          readOnly: true
        - name: mongodb-data
          mountPath: /data/db
      nodeSelector:
        size: large
      volumes:
      - name: k8-test
        secret:
          secretName: mongodb-secret
          items:
          - key: NINJA_ROOT_USERNAME
            path: admin/NINJA_ROOT_USERNAME
            mode: 0444
          - key: NINJA_ROOT_PASSWORD
            path: admin/NINJA_ROOT_PASSWORD
            mode: 0444
          - key: MONGO_USERNAME
            path: MONGO_USERNAME
            mode: 0444
          - key: MONGO_PASSWORD
            path: MONGO_PASSWORD
            mode: 0444
          - key: NINJA_USERS_LIST
            path: NINJA_USERS_LIST
            mode: 0444
      - name: mongodb-scripts
        configMap:
          name: mongodb-configmap
          items:
          - key: ninja-users.js
            path: ninja-users.js
      - name: mongodb-configmap
        configMap:
          name: mongodb-configmap
          items:
          - key: mongo.conf
            path: mongo.conf
      - name: mongodb-data
        persistentVolumeClaim:
          claimName: mongodb-pvc

Step 6: Create a Secret

The Secret object serves the purpose of storing sensitive deployment information.

1) Generate a Secret YAML using your text editor.

nano Secret.yaml

 

2) Input the details needed to access the MongoDB database and save the file.

apiVersion: v1
kind: Secret
metadata:
  name: mongodb-secret
type: Opaque
data:
  NINJA_ROOT_USERNAME: VIDHI
  NINJA_ROOT_PASSWORD: vidhi@2405
  NINJA_USERNAME: vidhi
  NINJA_PASSWORD: vidhi@2405
  NINJA_USERS_LIST: dGVzdDpkYkFkbWluLHJlYWRXcml0ZTpwYXNzd29yZAo=

Step 7: Create a MongoDB Service

To create a MongoDB Service:

1) Generate a headless service object.

nano Service.yaml

 

A headless service permits users to connect directly to pods.

 

2) Incorporate the service name and definition into the YAML file and then save the file.

apiVersion: v1
kind: Service
metadata:
  name: mongodb-test
  labels:
    app: database
spec:
  clusterIP: None
  selector:
    app: database

Step 8: Using Kustomize to Apply the MongoDB configuration

Apply the MongoDB configuration files effortlessly using Kustomize.

1) Create a kustomization.yaml file.

nano kustomization.yaml

 

2) List all the YAML files created in the previous steps in the resources section.

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ConfigMap.yaml
  - PersistentVolumeClaim.yaml
  - PersistentVolume.yaml
  - Secret.yaml
  - Service.yaml
  - StatefulSet.yaml
  - StorageClass.yaml

 

3) Place the file in the directory alongside the other files. Execute the command to deploy MongoDB.

kubectl apply -k .
output

4) Check if the pod is ready using kubectl.

kubectl get pod

 

Once the pod displays 1/1 in the READY column, move on to the next step.

output

Step 9: Connect to a MongoDB instance.

1) Connect to the MongoDB pod using the following kubectl command.

kubectl exec -it mongodb-test-0 -- sh

 

2) Type the following when the # prompt appears.

mongo
output

3) Move to the test database.

use test

4) Verify your identity with this command.

db.auth('[codingNinjasUsername]','[codingNinjasPassword]')

 

When you see number 1 in the output, it means authentication was successful.

output

Deploy a ReplicaSet

Deploying MongoDB as a ReplicaSet ensures that you have a certain number of pods running all the time. People suggest using ReplicaSet deployments for production environments.

Step 1: Set up Role-Based Access Control (RBAC)

1) Use a text editor to create a YAML file.

nano rbac.yaml

 

2) Set up access rules for your MongoDB deployment. The example below demonstrates creating an RBAC YAML file.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: mongo-account
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: mongo-role
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["*"]
- apiGroups: [""]
  resources: ["deployments"]
  verbs: ["list", "watch"]
- apiGroups: [""]
  resources: ["services"]
  verbs: ["*"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: mongo_role_binding
subjects:
- kind: ServiceAccount
  name: mongo-account
  namespace: default
roleRef:
  kind: ClusterRole
  name: mongo-role
  apiGroup: rbac.authorization.k8s.io

 

3) Save the file and then apply it using kubectl.

kubectl apply -f rbac.yaml

Step 2: Create a StatefulSet Deployment

1) Create a StatefulSet deployment YAML.

nano StatefulSet.yaml

 

2) In the file, state how many replicas you want, which MongoDB image to use, and the template for claiming storage that can change.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb-replica
  namespace: default
spec:
  serviceName: mongo
  replicas: 2
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
        selector: mongo
    spec:
      terminationGracePeriodSeconds: 30
      serviceAccount: mongo-account
      containers:
      - name: mongodb
        image: docker.io/mongo:4.2
        env:
        command: ["/bin/sh"]
        args: ["-c", "mongod --replSet=rs0 --bind_ip_all"]
        resources:
          limits:
            cpu: 1
            memory: 1500Mi
          requests:
            cpu: 1
            memory: 1000Mi
        ports:
        - name: mongo-port
          containerPort: 27017
        volumeMounts:
        - name: mongo-data
          mountPath: /data/db
  volumeClaimTemplates:
  - metadata:
      name: mongo-data
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi

 

3) Save the file, then use "kubectl apply" to make the deployment happen.

kubectl apply -f StatefulSet.yaml

Step 3: Create a headless Service

1) Create a YAML file for the service.

nano Service.yaml

 

2) Establish a service that assigns direct communication with pods.

apiVersion: v1
kind: Service
metadata:
  name: mongo
  namespace: default
  labels:
    name: mongo
spec:
  ports:
    - port: 27017
      targetPort: 27017
  clusterIP: None
  selector:
    app: mongo

 

3) Execute the YAML using kubectl.

kubectl apply -f Service.yaml

Step 4: Set up the Replication Host

To set up pod replication follow the following steps.

1) Access the pod using kubectl exec using the following command.

kubectl exec -it mongodb-replica-0 -n default -- mongo

 

2) Initiate the replication by entering the following command at the shell prompt.

rs.initiate()
output

The line "ok" : 1 confirms the successful initiation.

3) Define a ‘cfg’ variable and execute the following command.

var cfg = rs.conf()

 

4) Use the variable to include the main server in the configuration.

cfg.members[0].host=”mongodb-replica-0.mongo:27017”
output

5) Ensure the configuration by carrying out the following command.

rs.reconfig(cfg)
output

6) Use the rs.add() instruction to include an additional pod in the configuration.

rs.add("mongodb-replica-1.mongo:27017")
output

7) Check the status

rs.status()

The "members" section is expected to display a pair of replicas, with the primary replica featured at the top of the results.

output

Frequently Asked Questions

What is Kubernetes used for?

Kubernetes are used in Containerized application deployment. Scalability and management are all automated by Kubernetes. It offers methods and tools for high availability and effective container lifecycle management.

What is Kubernetes Pod?

The smallest deployable unit in the Kubernetes ecosystem is a Kubernetes Pod. It may include one or more containers with the same IP address, storage volumes, and network namespace.

What is Kubernetes Service?

A Kubernetes Service abstraction gives one or more pods a reliable network identity and endpoint. Network traffic is divided among several pods to achieve load balancing and automatic failover.

What do you mean by ReplicaSet in Kubernetes?

In Kubernetes, a ReplicaSet is a controller that ensures a certain number of replicas, or identical pod copies are always active.

What is Kubernetes Namespace?

You can build virtual clusters inside of actual clusters using Kubernetes Namespaces. Teams can manage and isolate several applications or environments inside the cluster since it gives resources.

Conclusion

In this article, we learn how we can deploy, run, and install MongoDB on Kubernetes. One must follow different steps to install MongoDB correctly on Kubernetes. Be careful while putting the correct variable path in your system. We have deployed ReplicaSet.

Check out the link to learn more about such a topic.


You can find more informative articles or blogs on our platform. You can also practice more coding problems and prepare for interview questions from well-known companies on your platform, Coding Ninjas Studio.

Live masterclass