The Journey of 100DaysofCode aka 100DaysofMongoDB (@Aasawari_24)

Day11 as #100DaysofMongoDB as 100daysofcode

Starting a pattern today for the next 10 days n I hope I keep up with it.

Calling it Day11 as First Day of using MongoDB in a kubernetes deployment.

Kubernetes is an orchestration framework which allows you to scale, automate and manage containerised application.
By Containerised, means, to bundle and package the application in one and run on a cloud or different deployment.

This is fir for modern applications which are based on Microservice architectures, have frequent deployments or statefulsets.

Let’s see a sample deployment where MongoDB is deployed in Kubernetes with a creation of replica sets.

The statefulsets and deployments are two ways through which the MongoDB can be deployed in a kubernetes environment.
The difference occurs when:
1. Deployment model: This is preferred when a stateless application is preferred. All the pods of the application use the same volume specified in the deployment.yaml files. The pod names are deployed with a different name every-time the pod is deleted.
2. Statefulset model : This deployment is preferred when each pod of the deployment used its own independent set and volume. The pods here are deployed with the same name every-time the pods are deleted.

Each deployment of the application has config-map and secrets which contains non-sensitive data and sensitive data respectively.

Deploying MongoDB as Deployment

  1. Creating a Secret:
apiVersion: v1
data:
  password: cGFzc3dvcmQxMjM= #Encoded with Base64 (password)
  username: YWRtaW51c2Vy #Encoded with Base64 (password)
kind: Secret
metadata:
  creationTimestamp: null
  name: mongo-creds
  1. Creating a deployement.yaml file
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: mongo
  name: mongo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongo
  strategy: {}
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - image: mongo
        name: mongo
        args: ["--dbpath","/data/db"]
        livenessProbe:
          exec:
            command:
              - mongo
              - --disableImplicitSessions
              - --eval
              - "db.adminCommand('ping')"
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 6
        readinessProbe:
          exec:
            command:
              - mongo
              - --disableImplicitSessions
              - --eval
              - "db.adminCommand('ping')"
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 6
        env:
        - name: MONGO_INITDB_ROOT_USERNAME
          valueFrom:
            secretKeyRef:
              name: mongo-creds
              key: username
        - name: MONGO_INITDB_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongo-creds
              key: password
        volumeMounts:
        - name: "mongo-data-dir"
          mountPath: "/data/db"
      volumes:
      - name: "mongo-data-dir"
        persistentVolumeClaim:
          claimName: "mongo-data"

Specifying a few key value pairs defined above:

kind: Deployment.. defines the applications is of type deployment.
replicas : 1 specifics that the application will have only one replica pod.
livenessProbe: To make sure that the pods are not stuck and are redeployed after the timeouts mentioned.
Persistent Volumes: is a storage provisioned by the admin
Persistent volume Chains: Works for a dynamic volume provisioning enabled system

Once the deployments and service files created with

kubectl create -f deployment.yaml/service.yaml files

Once the pods are up and running the deployment will look like the following:

aasawari.sahasrabuddhe@Aasawaris-MacBook-Pro mongodb % kubectl get all
NAME                                             READY     STATUS    RESTARTS   AGE
pod/mongo-cd755c96f-67sc8           1/1     Running   0          6d
pod/mongo-client-6c7bc768c4-bp5hq   1/1     Running   0          6d

NAME                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
service/kubernetes           ClusterIP   10.96.0.1       <none>        443/TCP           6d7h
service/mongo-nodeport-svc   NodePort    10.101.236.24   <none>        27017:32000/TCP   6d

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mongo          1/1     1            1           6d
deployment.apps/mongo-client   1/1     1            1           6d

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/mongo-cd755c96f           1         1         1       6d
replicaset.apps/mongo-client-6c7bc768c4   1         1         1       6d

aasawari.sahasrabuddhe@Aasawaris-MacBook-Pro mongodb %

In-order to login to the database

kubectl exec deployment/mongo-client -it – /bin/bash
mongo --host mongo-nodeport-svc --port 27017 -u adminuser -p password123

Deploying MongoDB as Statefulset

Creating ststefulset.yaml and service.yaml files deploying MongoDB as deployment files:


statefulset.yaml: 
apiVersion: apps/v1
kind: StatefulSet.  #Defining the MongoDB deployment as statefulset
metadata:
  name: mongo
spec:
  selector:
    matchLabels:
      app: mongo
  serviceName: "mongo"
  replicas: 4.     #Three copies of MongoDB pods will be deployed.
  template:
    metadata:
      labels:
        app: mongo
    spec:
      terminationGracePeriodSeconds: 10.  #When pod is deleted, it will take this time to terminate
      containers:
      - name: mongo
        image: mongo
        command:
        - mongod
        - "--bind_ip_all".   #Allowing MongoDB to allow all IPs
        - "--replSet"
        - rs0
        ports:
        - containerPort: 27017.   # Defining port
        volumeMounts:
        - name: mongo-volume
          mountPath: /data/db
  volumeClaimTemplates:
  - metadata:
      name: mongo-volume
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

service.yaml file:

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

After kubectl create -f . The deployment will look like the following:



aasawari.sahasrabuddhe@Aasawaris-MacBook-Pro mongodb % kubectl get all
NAME                                READY   STATUS    RESTARTS   AGE
pod/mongo-0                         1/1     Running   0          2d5h
pod/mongo-1                         1/1     Running   0          2d5h
pod/mongo-2                         1/1     Running   0          2d5h
pod/mongo-3                         1/1     Running   0          6h20m

NAME                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
service/mongo                ClusterIP   None            <none>        27017/TCP         2d5h


NAME                     READY   AGE
statefulset.apps/mongo   4/4     2d5h
aasawari.sahasrabuddhe@Aasawaris-MacBook-Pro mongodb %

You can exec to any of the 4 MongoDB commands using
kubectl exec -it <pod-name> mongo or mongosh

and explore the databases and perform various operations.

Will be discussing MongoDB deployment for the next 10 days in this sections of #100DaysOfMongoDB

Thanks
Aasawari

Share on twitter: https://twitter.com/Aasawari_24

3 Likes