DB/MongoDB
Mongo client
mongocli
mongocli
is a client for connecting to MongoDB versions 5 and above.
kubectl -n mongo run --image=ubuntu:20.04 ubuntu-1 --rm -it -- bash # Install generic tools DEBIAN_FRONTEND=noninteractive apt install -yq dnsutils iproute2 iputils-ping iputils-tracepath net-tools netcat procps curl wget # Install mongocli apt-get install gnupg -yy wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | apt-key add - touch /etc/apt/sources.list.d/mongodb-org-5.0.list echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" > /etc/apt/sources.list.d/mongodb-org-5.0.list apt-get update apt-get install -y mongocli mongocli <...> # Install mongo shell - version 4.x wget https://downloads.mongodb.com/compass/mongodb-mongosh_1.3.1_amd64.deb dpkg -i mongodb-mongosh_1.3.1_amd64.deb mongosh <...>
Connect
MongoDB version 4
MONGODB_USERNAME=root MONGODB_PASSWORD=password1 mongosh mongodb://${MONGODB_USERNAME}:${MONGODB_PASSWORD}@mongodb.mynamespace:27017/mydatabase?replicaSet=rs0 Connecting to: mongodb://<credentials>@mongodb.mynamespace:27017/mydatabase?replicaSet=rs0&appName=mongosh+1.3.1 Using MongoDB: 4.4.6 Using Mongosh: 1.3.1 rs0 [primary] mydatabase> # Connect via kubectl exec kubectl -n mongo exec -it mongodb-0 -- mongo -u $MONGODB_USERNAME -p $MONGODB_PASSWORD --eval "rs.conf()"
MongoDB version 5
mongocli <...>
Operational MongoDb queries
rs.conf() # show current replica set config rs.status() # show current replica set status printjson(db.serverStatus()) # server status rs0 [primary] hollywood> show databases; mydatabase 90.7 MB rs0 [primary] hollywood> show show databases show dbs show collections show tables show profile show users show roles show log show logs # Simple queries db.users.findOne() db.users.find().limit(10) db.users.find({"name.family": "Smith"}).count() ## Indexes on a collection db.user.getIndexes()
Passwords management
All write operation like a password change must be run on a PRIMARY cluster member. Each database in Mongo cluster has its own set of users.
# Login using keyfile mongo -u __system -p "$(tr -d '\011-\015\040' < path-to-keyfile)" --authenticationDatabase local mongo -u __system -p "$(echo "$MONGODB_REPLICA_SET_KEY" | tr -d '\011-\015\040')" --authenticationDatabase local # List databases as each database has it's own users show databases; use admin; show users; # list users db.getUsers(); # list users { "_id" : "admin.root", "userId" : UUID("aaaabbbb-bbbb-bbbb-bbbb-aaaabbbbaaa"), "user" : "root", "db" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ], "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] } # Create a user db.createUser({user:"admin",pwd:"password",roles:[{role:"root",db:"admin"}]}); # Update a password db.changeUserPassword("admin", "password1"); # Verify db.auth("admin", "password1"); db.runCommand({connectionStatus : 1});
Failover PRIMARY
We want to failover the PRIMARY mongodb-0.mongodb-headless.mongo:27017
node to mongodb-1.mongodb-headless.mongo:27017
Note: The failover must be run on the PRIMARY otherwise we get error "errmsg" : "New config is rejected :: caused by :: replSetReconfig should only be run on a writable PRIMARY. Current state SECONDARY;",
.
# Print the RS (replication set) configuration kubectl -n mongo exec -it mongodb-0 -- mongo -u root -p $PASSWORD --eval "rs.conf()"
rs0:PRIMARY> rs.conf() { "_id" : "rs0", "version" : 201111, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "mongodb-0.mongodb-headless.mongo:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 0.5, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "mongodb-arbiter-0.mongodb-arbiter-headless.mongo:27017", "arbiterOnly" : true, "buildIndexes" : true, "hidden" : false, "priority" : 0, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "mongodb-1.mongodb-headless.mongo:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 0.5, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 3, "host" : "mongodb-2.mongodb-headless.mongo:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 0.5, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "catchUpTakeoverDelayMillis" : 30000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("111111111122222222223333") } }
Update RS configuration by changing votes or priories. The below commands update mongodb-1
priority from 0.5 to 1. The newly triggered election process does not impact the service.
# Execute into any of cluster nodes kubectl -n mongo exec -it mongodb-0 -- mongo -u root -p $PASSWORD --eval "rs.conf()" rs0:PRIMARY> cfg = rs.conf(); rs0:PRIMARY> cfg.members[2].priority = 1; # mongodb-1.mongodb-headless.mongo:27017 rs0:PRIMARY> cfg.members[2].votes = 1; rs0:PRIMARY> rs.reconfig(cfg); # save the configuration rs0:PRIMARY> rs.status(); # verify, the reconfiguration take around 8-12 seconds