MongoDB Sharded Cluster — Initialization Guide Raspberry Pi 3-node MicroK8s cluster, MongoDB 8.0 Community Architecture ┌─────────────────────────────────────────────────────┐ │ mongos (x2) │ │ mongo-mongos.mongodb.svc.cluster.local │ └───────────────────┬─────────────────────────────────┘ │ ┌───────────┴───────────┐ │ │ ┌───────▼────────┐ ┌─────────▼──────┐ ┌──────────────────┐ │ Config Server │ │ Shard 0 │ │ Shard 1 │ │ ReplicaSet │ │ ReplicaSet │ │ ReplicaSet │ │ (3 replicas) │ │ (3 replicas) │ │ (3 replicas) │ │ port 27019 │ │ port 27018 │ │ port 27018 │ └────────────────┘ └────────────────┘ └──────────────────┘ Step 0 — Prerequisites ====== On pisvrwsv07 create the data directories: sudo mkdir -p /mnt/mongodb/configsvr0 /mnt/mongodb/configsvr2 /mnt/mongodb/shard0-0 /mnt/mongodb/shard1-0 sudo chown -R 999:999 /mnt/mongodb On pisvrwsv08 create the data directories: sudo mkdir -p /mnt/mongodb/configsvr1 /mnt/mongodb/shard0-1 /mnt/mongodb/shard1-1 sudo chown -R 999:999 /mnt/mongodb step 1 ====== kubectl apply -f namespace.yaml Step 2 ====== Generate the keyfile and create the secret: openssl rand -base64 756 > mongo-keyfile chmod 400 mongo-keyfile kubectl create secret generic mongo-keyfile –from-file=keyfile=./mongo-keyfile -n mongodb You can delete the local file after this, it’s stored in the secret. rm mongo-keyfile Step 3 ====== Apply manifest: kubectl apply -f mongodb.yaml Wait for all pods to be Running before continuing: kubectl get pods -n mongodb -w All 9 pods (3 configsvr + 3 shard0 + 3 shard1) must be Running. Step 4 ====== Initialize the Config Server replica set kubectl exec -n mongodb mongo-configsvr-0 -- mongosh --port 27019 --eval ' rs.initiate({ _id: "configReplSet", configsvr: true, members: [ { _id: 0, host: "mongo-configsvr-0.mongo-configsvr.mongodb.svc.cluster.local:27019" }, { _id: 1, host: "mongo-configsvr-1.mongo-configsvr.mongodb.svc.cluster.local:27019" }, { _id: 2, host: "mongo-configsvr-2.mongo-configsvr.mongodb.svc.cluster.local:27019" } ] })' Step 5 ====== initialize shard0: kubectl exec -n mongodb mongo-shard0-0 -- mongosh --port 27018 --eval ' rs.initiate({ _id: "shard0ReplSet", members: [ { _id: 0, host: "mongo-shard0-0.mongo-shard0.mongodb.svc.cluster.local:27018" }, { _id: 1, host: "mongo-shard0-1.mongo-shard0.mongodb.svc.cluster.local:27018" }, { _id: 2, host: "mongo-shard0-arbiter-0.mongo-shard0-arbiter.mongodb.svc.cluster.local:27018", arbiterOnly: true } ] })' Step 6 ====== initialize shard1: kubectl exec -n mongodb mongo-shard1-0 -- mongosh --port 27018 --eval ' rs.initiate({ _id: "shard1ReplSet", members: [ { _id: 0, host: "mongo-shard1-0.mongo-shard1.mongodb.svc.cluster.local:27018" }, { _id: 1, host: "mongo-shard1-1.mongo-shard1.mongodb.svc.cluster.local:27018" }, { _id: 2, host: "mongo-shard1-arbiter-0.mongo-shard1-arbiter.mongodb.svc.cluster.local:27018", arbiterOnly: true } ] })' Step 7 ====== Create admin user: kubectl exec -n mongodb \ $(kubectl get pod -n mongodb -l app=mongo-mongos -o jsonpath='{.items[0].metadata.name}') -- \ mongosh --eval ' db.getSiblingDB("admin").createUser({ user: "admin", pwd: "changeme", roles: [{ role: "root", db: "admin" }] })' check statusses: Status configsvr: kubectl exec -n mongodb mongo-configsvr-0 -- mongosh --port 27019 -u admin -p changeme --authenticationDatabase admin --eval 'rs.status().members.forEach(m => print(m.name, m.stateStr))' Status shards without auth: kubectl exec -n mongodb mongo-shard0-0 -- mongosh --port 27018 --eval 'rs.status().members.forEach(m => print(m.name, m.stateStr))' status shards with auth: kubectl exec -n mongodb mongo-shard0-0 -- mongosh --port 27018 -u admin -p changeme --authenticationDatabase admin --eval 'rs.status().members.forEach(m => print(m.name, m.stateStr))' step 8 ====== MongoDB 5+ requires explicit default write concern when arbiters are involved. Fix it by setting the cluster-wide write concern first: kubectl exec -n mongodb \ $(kubectl get pod -n mongodb -l app=mongo-mongos -o jsonpath='{.items[0].metadata.name}') -- \ mongosh -u admin -p Mongodb01@ --authenticationDatabase admin --eval ' db.adminCommand({ setDefaultRWConcern: 1, defaultWriteConcern: { w: 1 }, defaultReadConcern: { level: "local" } })' step 9 ====== Add shards kubectl exec -n mongodb \ $(kubectl get pod -n mongodb -l app=mongo-mongos -o jsonpath='{.items[0].metadata.name}') -- \ mongosh -u admin -p changeme --authenticationDatabase admin --eval ' sh.addShard("shard0ReplSet/mongo-shard0-0.mongo-shard0.mongodb.svc.cluster.local:27018,mongo-shard0-1.mongo-shard0.mongodb.svc.cluster.local:27018") sh.addShard("shard1ReplSet/mongo-shard1-0.mongo-shard1.mongodb.svc.cluster.local:27018,mongo-shard1-1.mongo-shard1.mongodb.svc.cluster.local:27018") sh.status()' step 10 ------- connection string for applications: mongodb://admin:Mongodb01@mongo-mongos.mongodb.svc.cluster.local:27017/mydb?authSource=admin mongoose: mongoose.connect('mongodb://admin:Mongodb01@mongo-mongos.mongodb.svc.cluster.local:27017/mydb?authSource=admin') step 11 ======= If you want to enable sharding on a specific database and collection: kubectl exec -n mongodb \ $(kubectl get pod -n mongodb -l app=mongo-mongos -o jsonpath='{.items[0].metadata.name}') -- \ mongosh -u admin -p Mongodb01@ --authenticationDatabase admin --eval ' sh.enableSharding("mydb") sh.shardCollection("mydb.mycollection", { _id: "hashed" })'