180 lines
6.1 KiB
Markdown
180 lines
6.1 KiB
Markdown
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" })'
|
||
|
||
|