--- tags: DevOps title: deploy mongodb sharded cluster on k8s --- # deploy mongodb sharded cluster on k8s ### Create Namespace :::spoiler namespace config file ```yaml= kind: Namespace apiVersion: v1 metadata: name: mongodb labels: kubernetes.io/metadata.name: mongodb name: mongodb spec: finalizers: - kubernetes ``` ::: ### Config Server : :::spoiler config server headless-service and statefulset and volume claim .yaml config ```yaml= apiVersion: v1 kind: Service metadata: name: mongodb-configdb-headless-service namespace: mongodb labels: name: mongodb-configdb spec: ports: - port: 27019 targetPort: 27019 clusterIP: None selector: role: mongodb-configdb --- apiVersion: apps/v1 #change this version based on master version kind: StatefulSet metadata: name: mongodb-configdb namespace: mongodb spec: selector: matchLabels: role: mongodb-configdb # has to match .spec.template.metadata.labels serviceName: mongodb-configdb-headless-service replicas: 1 template: metadata: labels: role: mongodb-configdb tier: configdb spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: tier operator: In values: - configdb topologyKey: kubernetes.io/hostname terminationGracePeriodSeconds: 10 containers: - name: mongodb-configdb-container image: mongo command: - "mongod" - "--port" - "27019" - "--dbpath" - "/mongo-disk" - "--bind_ip" - "0.0.0.0" - "--configsvr" - "--replSet" - rs0 resources: requests: cpu: 50m memory: 100Mi ports: - containerPort: 27019 volumeMounts: - name: mongodb-configdb-persistent-storage-claim mountPath: /mongo-disk volumeClaimTemplates: - metadata: name: mongodb-configdb-persistent-storage-claim annotations: volume.beta.kubernetes.io/storage-class: microk8s-hostpath spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 5Gi ``` ::: ### Sharded Server: :::spoiler sharded server headless-service and statefulset and volume claim config ```yaml= apiVersion: v1 kind: Service metadata: name: mongodb-shardX-headless-service namespace: mongodb labels: name: mongodb-shardX spec: ports: - port: 27017 targetPort: 27017 clusterIP: None selector: role: mongodb-shardX --- apiVersion: apps/v1 kind: StatefulSet metadata: name: mongodb-shardX namespace: mongodb spec: selector: matchLabels: role: mongodb-shardX # has to match .spec.template.metadata.labels serviceName: mongodb-shardX-headless-service replicas: 1 template: metadata: labels: role: mongodb-shardX tier: maindb replicaset: ShardX spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: replicaset operator: In values: - ShardX topologyKey: kubernetes.io/hostname terminationGracePeriodSeconds: 10 containers: - name: mongodb-shardX-container image: mongo command: - "mongod" - "--port" - "27017" - "--bind_ip" - "0.0.0.0" - "--replSet" - "ShardX" - "--dbpath" - "/mongo-disk" resources: requests: cpu: 50m memory: 100Mi ports: - containerPort: 27017 volumeMounts: - name: mongo-shardX-persistent-storage-claim mountPath: /mongo-disk volumeClaimTemplates: - metadata: name: mongo-shardX-persistent-storage-claim annotations: volume.beta.kubernetes.io/storage-class: microk8s-hostpath spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 5Gi ``` ::: :::spoiler command after copy above config ```bash= # replace the series number to your current sharded server number sed -e "s/shardX/shard1/g; s/ShardX/Shard1/g" mongodb-maindb-service-stateful.yaml ``` ::: ### Mongos(Mongo Sharded Utils) Deployment :::spoiler mongos deployment yaml config file ```yaml= apiVersion: apps/v1 kind: Deployment metadata: name: mongos namespace: mongodb spec: replicas: 2 selector: matchLabels: role: mongos tier: routers template: metadata: labels: role: mongos tier: routers spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: tier operator: In values: - routers topologyKey: kubernetes.io/hostname terminationGracePeriodSeconds: 10 containers: - name: mongos-container image: mongo command: - "mongos" - "--port" - "27017" - "--bind_ip" - "0.0.0.0" - "--configdb" - conf/mongodb-configdb-headless-service.mongodb.svc.cluster.local:27019 resources: requests: cpu: 50m memory: 100Mi ports: - containerPort: 27017 ``` ::: ### Configure Sharding :::spoiler configure bash file(you can also run in dashboard's pod terminal) ```bash= echo "Replicaset Init mongodb-shard1-0 " kubectl exec --namespace=mongodb mongodb-shard1-0 -c mongodb-shard1-container -- mongo --port 27017 --eval "rs.initiate({_id: \"Shard1\", version: 1, members: [ {_id: 0, host: \"mongodb-shard1-0.mongodb-shard1-headless-service.mongodb.svc.cluster.local:27017\"} ] });" echo "Replicaset Init mongodb-shard2-0 " kubectl exec --namespace=mongodb mongodb-shard2-0 -c mongodb-shard2-container -- mongo --port 27017 --eval "rs.initiate({_id: \"Shard2\", version: 1, members: [ {_id: 0, host: \"mongodb-shard2-0.mongodb-shard2-headless-service.mongodb.svc.cluster.local:27017\"} ] });" ``` ::: :::spoiler ```bash= echo "Adding Shard 1 : Shard1 " kubectl exec --namespace=mongodb $(kubectl get pod -l "tier=routers" -o jsonpath='{.items[0].metadata.name}' --namespace=mongodb ) -c mongos-container -- mongosh --port 27017 --eval "sh.addShard(\"Shard1/mongodb-shard1-0.mongodb-shard1-headless-service.mongodb.svc.cluster.local:27017\");" echo "Adding Shard 2 : Shard2 " kubectl exec --namespace=mongodb $(kubectl get pod -l "tier=routers" -o jsonpath='{.items[0].metadata.name}' --namespace=mongodb ) -c mongos-container -- mongosh --port 27017 --eval "sh.addShard(\"Shard2/mongodb-shard2-0.mongodb-shard2-headless-service.mongodb.svc.cluster.local:27017\");" ``` ::: ### reference - https://medium.com/google-cloud/sharded-mongodb-in-kubernetes-statefulsets-on-gke-ba08c7c0c0b0