MongoDB副本集搭建-docker
注:在进行副本集搭建前,请先将服务部署docker环境并正常运行。
#通过--platform指定下载镜像的系统架构 在这我用的是mongo:4.0.28版本 arm64系统架构的mongo镜像
docker pull --platform=linux/arm64 mongo:4.0.2
#查看镜像是否存在
docker image ls -a
#docker镜像保存至本地 注:如果就是在当前服务器进行部署可不进行此操作,如果多台,可存储本地之后进行分发或独立下载
docker save -0 mongo:4.0.28.tar mongo:4.0.28
设计三个节点分别如下
名称 | 数据存储位置 | 优先级 | docker映射端口 | mongo启动端口 |
---|---|---|---|---|
mongo1 | /data/mongo/data | 3 | 27017 | 27017 |
mongo2 | /data/mongo/data | 1 | 27017 | 27017 |
mongo3 | /data/mongo/data | 1 | 27017 | 27017 |
容器启动
#mongo1
docker run --restart=always --name mongo -v /data/mongo/data:/data/db --network host -d mongo:4.0.28 mongod --replSet "rs0" --port 27017 --bind_ip 0.0.0.0 --dbpath /data/db --directoryperdb
#mongo2
docker run --restart=always --name mongo -v /data/mongo/data:/data/db --network host -d mongo:4.0.28 mongod --replSet "rs0" --port 27017 --bind_ip 0.0.0.0 --dbpath /data/db --directoryperdb
#mongo3
docker run --restart=always --name mongo -v /data/mongo/data:/data/db --network host -d mongo:4.0.28 mongod --replSet "rs0" --port 27017 --bind_ip 0.0.0.0 --dbpath /data/db --directoryperdb
#注:--directoryperdb 选项是用于指定mongo每个数据库的数据文件都存储在单独的目录下
3个均启动完成,随便进入到一个容器里,如mongo,并连接到数据库
#进入容器
docker exec -it mongoDB /bin/bash
#进入mongo终端
mongo
传入配置并初始化:
config={_id:"rs0",members:[{_id:0,host:"ip1:27017", priority:3},{_id:1,host:"ip2:27017", priority:1},{_id:2,host:"ip3:27017", priority:1}]}
rs.initiate(config);
或
rs.initiate({
_id:"rs0",
members:[
{_id:0,host:'192.168.1.2:27017',priority:3},
{_id:1,host:'192.168.1.3:27017',priority:1},
{_id:2,host:'192.168.1.4:27017',priority:1}
]
})
节点在经过短暂的同步后,登陆mongo的控制台会显示成rso:PRIMARY,备份节点会显示成rso:SECONDARY,此时副本集就安装好了。
验证
进入primary服务器,随便创建一个测试数据库和测试表数据:
rso:PRIMARY> use test
switched to db test
rso:PRIMARY> db.testCollection.insert({"key":"value"})
WriteResult({ "nInserted" : 1 })
rso:PRIMARY> db.testCollection.find()
{ "_id" : ObjectId("5c20a3d7c5d174307dc3d516"), "key" : "value" }
然后进入secondary服务器查一下数据,会出现如下结果:
rso:SECONDARY> use test
switched to db test
rso:SECONDARY> db.testCollection.find()
Error: error: {
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk"
}
这是因为secondary服务器在写多读少的应用使用Replica Sets来实现读写分离。通过在连接时指定或者在主库指定slaveOk,由secondary来分担读的压力,primary只承担写操作,此时为了检测设置为slaveOk,并重新查询一下,会出现如下结果:
rso:SECONDARY> rs.slaveOk()
rso:SECONDARY> db.testCollection.find()
{ "_id" : ObjectId("5c20a3d7c5d174307dc3d516"), "key" : "value" }
可以检测到副本集生效了。这时候主动把primary宕机或者删除,就可以看到主节点转移到mongo2/3了。
4. 开启密码验证
副本集的验证与mongo单机开启验证不同:
mongo单机版本只需要在admin库中的system.user表里加好用户后就默认开启了验证模式。
mongo副本集在admin库中的system.user表里加好用户后,需要显示开启验证模式(启动参数添加:–auth),那么副本集之间的互相反问就需要用到keyFile了。
注:keyFile几个注意点:
- 权限不能太大,不然会报“permissions on xxx are too open”
- 权限不能太小,不然会报“permission denied”
因此我们在创建keyFile的时候首要先把权限赋值好:
#741可以改为任意数
openssl rand -base64 741 > /data/mongo/data/mongo_keyfile
chmod 600 /data/mongo/data/mongo_keyfile
#docker启动需要把赋为999
chown 999/data/mongo/data/mongo_keyfile
#注:
添加用户,需要到主节点上进行添加
docker exec -it mongo bash
mongo
use admin
db.createUser({user: "admin",pwd: "password",roles: [ { role: "root", db: "admin" } ]})
添加好用户后重启副本集,启动带上验证和keyFile(每台执行)
1、
docker stop mongo && docker rm mongo
2、
cat /data/mongo/init.sh
#!/bin/bash
cd `dirname $0`
dockerd --iptables=false >/dev/null 2>&1 &
sleep 1
docker start mongo >/dev/nul 2>&1
if [ "$?" != "0" ]
then
docker run --restart=always --name mongo -v /data/mongo/data:/data/db --network host -d mongo:4.0.28 mongod --replSet "rs0" --port 27017 --bind_ip 0.0.0.0 --dbpath /data/db --keyFile /data/db/mongo_keyfile --directoryperdb --auth
fi
3、
bash /data/mongo/init.sh
重启完成后进行验证,与上一步的验证一致。这样带有权限验证的mongo副本集就创建完毕了。
mongo数据备份 docker
docker -run -it --rm --network host -v /data/mongo/backup:/data/mongo/backup mongo:4.0.28 /usr/bin/mongodump -h "ip地址" -u "用户名" -p "密码" -o /data/mongo/backup/$(date +%Y-%m-%d) --authenticationDatabase admin
mongo数据导入 docker
docker -run -it --rm --network host -v /data/mongo/backup:/data/mongo/backup mongo:4.0.28 /usr/bin/mongorestore -h "ip地址" -u "用户名" -p "密码" --authenticationDatabase=admin /data/mongo/backup/$(date +%Y-%m-%d)