MongoDB NoSQL Document-Based Database on Kubernetes Cluster

MongoDB Sharded Install Using Helm

#0
helm install mongodb-sharded --create-namespace --namespace mongodb oci://registry-1.docker.io/kahanit/mongodb-sharded --version 1.0.1

export MONGODB_ROOT_PASSWORD=$(kubectl get secret --namespace mongodb mongodb-sharded -o jsonpath="{.data.mongodb-root-password}" | base64 -d)

kubectl run --namespace mongodb mongodb-sharded-client --rm --tty -i --restart='Never' \
  --image docker.io/kahanit/mongodb-sharded:8.2.3-r1 \
  --command -- mongosh admin --host mongodb-sharded --authenticationDatabase admin -u root -p $MONGODB_ROOT_PASSWORD

MongoDB Sharded Install Manually

#1
kubectl create namespace mongodb
kubectl config set-context --current --namespace=mongodb

kubectl get ns mongodb

openssl rand -base64 756 > mongodb-keyfile

# Expected: > 700 bytes
wc -c mongodb-keyfile

ls -l mongodb-keyfile

kubectl create secret generic mongodb-keyfile \
  --from-file=keyfile=mongodb-keyfile

kubectl get secret mongodb-keyfile
#2
# configsvr-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: configsvr
spec:
  clusterIP: None
  ports:
    - port: 27019
      name: mongo
  selector:
    app: mongo-config
#3
kubectl apply -f configsvr-service.yaml

kubectl get svc configsvr
#4
# configsvr-statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: configsvr
spec:
  serviceName: configsvr
  replicas: 3
  selector:
    matchLabels:
      app: mongo-config
  template:
    metadata:
      labels:
        app: mongo-config
    spec:
      securityContext:
        fsGroup: 999

      initContainers:
        - name: prepare-keyfile
          image: busybox:1.36
          command:
            - sh
            - -c
            - |
              cp /secret/keyfile /work/keyfile
              chown 999:999 /work/keyfile
              chmod 400 /work/keyfile
          volumeMounts:
            - name: keyfile-secret
              mountPath: /secret
            - name: keyfile-work
              mountPath: /work

      containers:
        - name: mongod
          image: mongo:8.0
          command:
            - mongod
            - "--configsvr"
            - "--replSet"
            - "configReplSet"
            - "--bind_ip_all"
            - "--keyFile"
            - "/etc/mongo-keyfile/keyfile"
          ports:
            - containerPort: 27019
          volumeMounts:
            - name: data
              mountPath: /data/db
            - name: keyfile-work
              mountPath: /etc/mongo-keyfile
              readOnly: true

      volumes:
        - name: keyfile-secret
          secret:
            secretName: mongodb-keyfile
        - name: keyfile-work
          emptyDir: {}

  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 10Gi
#5
kubectl apply -f configsvr-statefulset.yaml

kubectl get pods -l app=mongo-config

kubectl logs configsvr-0

kubectl exec -it configsvr-0 -- \
  mongosh --host 127.0.0.1 --port 27019
#6
rs.initiate({
  _id: "configReplSet",
  configsvr: true,
  members: [
    { _id: 0, host: "configsvr-0.configsvr.mongodb.svc.cluster.local:27019" },
    { _id: 1, host: "configsvr-1.configsvr.mongodb.svc.cluster.local:27019" },
    { _id: 2, host: "configsvr-2.configsvr.mongodb.svc.cluster.local:27019" }
  ]
})

rs.status().members.map(m => ({ name: m.name, state: m.stateStr }))

exit
#7
# shard1-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: shard1
spec:
  clusterIP: None
  ports:
    - port: 27018
      name: mongo
  selector:
    app: mongo-shard1
#8
kubectl apply -f shard1-service.yaml
#9
# shard1-statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: shard1
spec:
  serviceName: shard1
  replicas: 3
  selector:
    matchLabels:
      app: mongo-shard1
  template:
    metadata:
      labels:
        app: mongo-shard1
    spec:
      securityContext:
        fsGroup: 999

      initContainers:
        - name: prepare-keyfile
          image: busybox:1.36
          command:
            - sh
            - -c
            - |
              cp /secret/keyfile /work/keyfile
              chown 999:999 /work/keyfile
              chmod 400 /work/keyfile
          volumeMounts:
            - name: keyfile-secret
              mountPath: /secret
            - name: keyfile-work
              mountPath: /work

      containers:
        - name: mongod
          image: mongo:8.0
          command:
            - mongod
            - "--shardsvr"
            - "--replSet"
            - "shard1ReplSet"
            - "--port"
            - "27018"
            - "--bind_ip_all"
            - "--keyFile"
            - "/etc/mongo-keyfile/keyfile"
          ports:
            - containerPort: 27018
          volumeMounts:
            - name: data
              mountPath: /data/db
            - name: keyfile-work
              mountPath: /etc/mongo-keyfile
              readOnly: true

      volumes:
        - name: keyfile-secret
          secret:
            secretName: mongodb-keyfile
        - name: keyfile-work
          emptyDir: {}

  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 20Gi
#10
kubectl apply -f shard1-statefulset.yaml

kubectl get pods -l app=mongo-shard1

kubectl exec -it shard1-0 -- \
  mongosh --host 127.0.0.1 --port 27018
#11
rs.initiate({
  _id: "shard1ReplSet",
  members: [
    { _id: 0, host: "shard1-0.shard1.mongodb.svc.cluster.local:27018" },
    { _id: 1, host: "shard1-1.shard1.mongodb.svc.cluster.local:27018" },
    { _id: 2, host: "shard1-2.shard1.mongodb.svc.cluster.local:27018" }
  ]
})

rs.status().members.map(m => ({ name: m.name, state: m.stateStr }))

exit
#12
# shard2-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: shard2
spec:
  clusterIP: None
  ports:
    - port: 27018
      name: mongo
  selector:
    app: mongo-shard2
#13
kubectl apply -f shard2-service.yaml
#14
# shard2-statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: shard2
spec:
  serviceName: shard2
  replicas: 3
  selector:
    matchLabels:
      app: mongo-shard2
  template:
    metadata:
      labels:
        app: mongo-shard2
    spec:
      securityContext:
        fsGroup: 999

      initContainers:
        - name: prepare-keyfile
          image: busybox:1.36
          command:
            - sh
            - -c
            - |
              cp /secret/keyfile /work/keyfile
              chown 999:999 /work/keyfile
              chmod 400 /work/keyfile
          volumeMounts:
            - name: keyfile-secret
              mountPath: /secret
            - name: keyfile-work
              mountPath: /work

      containers:
        - name: mongod
          image: mongo:8.0
          command:
            - mongod
            - "--shardsvr"
            - "--replSet"
            - "shard2ReplSet"
            - "--port"
            - "27018"
            - "--bind_ip_all"
            - "--keyFile"
            - "/etc/mongo-keyfile/keyfile"
          ports:
            - containerPort: 27018
          volumeMounts:
            - name: data
              mountPath: /data/db
            - name: keyfile-work
              mountPath: /etc/mongo-keyfile
              readOnly: true

      volumes:
        - name: keyfile-secret
          secret:
            secretName: mongodb-keyfile
        - name: keyfile-work
          emptyDir: {}

  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 20Gi
#15
kubectl apply -f shard2-statefulset.yaml

kubectl get pods -l app=mongo-shard2

kubectl exec -it shard2-0 -- \
  mongosh --host 127.0.0.1 --port 27018
#16
rs.initiate({
  _id: "shard2ReplSet",
  members: [
    { _id: 0, host: "shard2-0.shard2.mongodb.svc.cluster.local:27018" },
    { _id: 1, host: "shard2-1.shard2.mongodb.svc.cluster.local:27018" },
    { _id: 2, host: "shard2-2.shard2.mongodb.svc.cluster.local:27018" }
  ]
})

rs.status().members.map(m => ({ name: m.name, state: m.stateStr }))

exit
#17
# mongos-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: mongos
spec:
  ports:
    - port: 27017
      name: mongo
  selector:
    app: mongos
#18
kubectl apply -f mongos-service.yaml
#19
# mongos-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongos
spec:
  replicas: 2
  selector:
    matchLabels:
      app: mongos
  template:
    metadata:
      labels:
        app: mongos
    spec:
      securityContext:
        fsGroup: 999

      initContainers:
        - name: prepare-keyfile
          image: busybox:1.36
          command:
            - sh
            - -c
            - |
              cp /secret/keyfile /work/keyfile
              chown 999:999 /work/keyfile
              chmod 400 /work/keyfile
          volumeMounts:
            - name: keyfile-secret
              mountPath: /secret
            - name: keyfile-work
              mountPath: /work

      containers:
        - name: mongos
          image: mongo:8.0
          command:
            - mongos
            - "--configdb"
            - "configReplSet/configsvr-0.configsvr.mongodb.svc.cluster.local:27019,configsvr-1.configsvr.mongodb.svc.cluster.local:27019,configsvr-2.configsvr.mongodb.svc.cluster.local:27019"
            - "--bind_ip_all"
            - "--keyFile"
            - "/etc/mongo-keyfile/keyfile"
          ports:
            - containerPort: 27017
          volumeMounts:
            - name: keyfile-work
              mountPath: /etc/mongo-keyfile
              readOnly: true

      volumes:
        - name: keyfile-secret
          secret:
            secretName: mongodb-keyfile
        - name: keyfile-work
          emptyDir: {}
#20
kubectl apply -f mongos-deployment.yaml

kubectl get pods -l app=mongos

kubectl exec -it deploy/mongos -- mongosh
#21
sh.addShard(
  "shard1ReplSet/shard1-0.shard1.mongodb.svc.cluster.local:27018," +
  "shard1-1.shard1.mongodb.svc.cluster.local:27018," +
  "shard1-2.shard1.mongodb.svc.cluster.local:27018"
)

sh.addShard(
  "shard2ReplSet/shard2-0.shard2.mongodb.svc.cluster.local:27018," +
  "shard2-1.shard2.mongodb.svc.cluster.local:27018," +
  "shard2-2.shard2.mongodb.svc.cluster.local:27018"
)

sh.status()

use admin

db.createUser({
  user: "admin",
  pwd: "ChangeMeStrongPassword",
  roles: [
    { role: "root", db: "admin" }
  ]
})

exit
#22
kubectl exec -it deploy/mongos -- \
  mongosh -u admin -p ChangeMeStrongPassword --authenticationDatabase admin
#23
sh.status()

exit

Update mongos-deployment.yaml add --auth

#24
command:
  - mongos
  - "--configdb"
  - "configReplSet/configsvr-0.configsvr.mongodb.svc.cluster.local:27019,configsvr-1.configsvr.mongodb.svc.cluster.local:27019,configsvr-2.configsvr.mongodb.svc.cluster.local:27019"
  - "--bind_ip_all"
  - "--keyFile"
  - "/etc/mongo-keyfile/keyfile"
  - "--auth"
#25
kubectl apply -f mongos-deployment.yaml
kubectl rollout status deployment/mongos

kubectl exec -it deploy/mongos -- \
  mongosh -u admin -p ChangeMeStrongPassword --authenticationDatabase admin
#26
sh.status()

exit
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted