Docker部署MongoDB集群(一主一从一仲裁)

 在一个MongoDB复制集集群中,各个服务器有以下几种状态:

  • master 主节点,一个复制集有且仅有一台服务器处于Primary状态,只有主节点才对外提供读写服务。如果主节点挂掉,复制集将投票选出一个备节点成为新的主节点。
  • slave 备用节点,复制集允许有多台Secondary,每个备用节点的数据与主节点的数据是完全同步的。Recovering 恢复中,当复制集中某台服务器挂掉或者掉线后数据无法同步,重新恢复服务后从其他成员复制数据,这时就处于恢复过程,数据同步后,该节点又回到备用状态。
  • Arbiter 仲裁节点,该类节点可以不用单独存在,如果配置为仲裁节点,就主要负责在复本集中监控其他节点状态,投票选出主节点。该节点将不会用于存放数据。如果没有仲裁节点,那么投票工作将由所有节点共同进行。

准备工作:

  • centos7系统及已安装的docker
  • mongodb4.0
  • 三台机器  :

主节点:192.168.3.80  ------master(node1)

从节点:192.168.3.81  ------slave(node2)

仲裁节点:192.168.3.103  ------arbiter(node3)

架构图:

参考链接:

https://www.jianshu.com/p/7bfda4943034

步骤:

1.将下面给出的IP地址配置到所有的服务器上面,每一台服务器都要执行如下命令(记得要替换掉IP地址哦):

# export node1=192.168.3.80
# export node2=192.168.3.81
# export node3=192.168.3.103

2.在master服务器上面执行如下的命令,然后把密钥文件复制到其余两个服务器的同样的位置。

# mkdir -p /home/core/mongo-files  
# cd /home/core/mongo-files
# openssl rand -base64 741 > mongodb-keyfile
# chmod 600 mongodb-keyfile
# sudo chown 999 mongodb-keyfile

这个密钥文件的所有者被设置成id为“999”的用户了,因为在MongoDB的Docker容器中,这个用户需要有操作密钥文件的权限

3.传输密钥并添加权限

在master节点上操作,把秘钥文件mongo-files,复制到slave的/home/core/mongo-files下,命令如下:

scp -r mongodb-keyfile root@192.168.3.81:/home/core/mongo-files

 

  然后切换到slave节点里,给秘钥增加权限

chmod 600 mongodb-keyfile
sudo chown 999 mongodb-keyfile

scp -r mongodb-keyfile root@192.168.3.103:/home/core/mongo-files
把秘钥文件mongo-files,复制到arbiter的/home/core/mongo-files下,命令如下:

 在master节点操作:mongodb-keyfile root@192.168.3.103:/home/core/mongo-files

  然后切换到arbiter节点里,给秘钥增加权限

chmod 600 mongodb-keyfile
sudo chown 999 mongodb-keyfile

4.启动master(即第一台Docker服务器)的MongoDB容器。它会启动一个没有身份验证机制的容器,所以我们要设置一个用户。

root@master:/# docker run --name mongo \
-v /home/core/mongo-files/data:/data/db \
-v /home/core/mongo-files:/opt/keyfile \
--hostname="node1.example.com" \
-p 27017:27017 \
-d mongo:4.0 --smallfiles

 :没mongo:4.0镜像时,执行上面命令时会自动下载mongo:4.0

现在创建一个admin用户。我们可以连接到刚刚启动的mongoDB容器,并进入一个交互式的shell环境

root@master:/# docker exec -it mongo /bin/bash

这时候,我们就进到MongoDB的Docker容器里面了,然后我们要打开一个mongo shell环境:

root@master:/# mongo

上面的命令可以打开mongo shell环境。执行后你会看到这样的输出:

  切换到admin用户:

> use admin
switched to db admin

创建一个新的site admin 用户

> db.createUser( {
user: "siteUserAdmin",
 pwd: "password",
 roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]});

创建成功的话你会看到如下的成功信息:

 创建一个root用户:

> db.createUser( { user: "siteRootAdmin",
pwd: "password",
roles: [
              {
                    role: "root",
                    db: "admin" 

    } 
]});

你会看到如下的成功信息:

 我们已经创建好了我们以后要使用的几个用户,现在我们会退出交互式shell环境(mongo和Docker容器的环境)。我们输入两次exit退出去

5.停止并删除第一个MongoDB实例:

root@master:/# docker stop mongo (停止容器)

root@master:/# docker rm mongo (删除容器)

6.这次使用密钥文件启动第一台MongoDB实例(还是在master上面操作的)

docker run \
--name mongo \
-v /home/core/mongo-files/data:/data/db \
-v /home/core/mongo-files:/opt/keyfile \
--hostname="node1.example.com" \
--add-host node1.example.com:${node1} \
--add-host node2.example.com:${node2} \
--add-host node3.example.com:${node3} \
-p 27017:27017 -d mongo:4.0 \
--smallfiles \
--keyFile /opt/keyfile/mongodb-keyfile \
--replSet "rs0"

注意:

  • --keyFile的路径是/opt/keyfile/mongodb-keyfile,这是正确的。这是密钥文件在Docker内部的地址,我们用-v选项将密钥文件映射到容器内部的那个路径上(即:/opt/keyfile/mongodb-keyfile)。
  • --add-host把这些信息添加到Docker容器的/etc/hosts文件中,所以我们可以使用域名而不是IP地址了。在实际的生产环境中这些信息都是DNS,这些参数都可以忽略。

7.连接到副本集上并且安装配置好它。这还是在node1上面进行的。我们要开启另外一个新的交互式shell环境进入mongo容器,同时开启一个mongo shell环境:

root@master:/# docker exec -it mongo /bin/bash    
root@master:/# mongo
MongoDB shell version: v4.0.13
>

切换到admin用户下:

> use admin
switched to db admin

因为我们已经设置了一个密码,所以这次我们不得不做身份验证。我们把密码设置为:password。

> db.auth("siteRootAdmin", "password");
1

现在我们可以开启副本集:

> rs.initiate()

8.验证已经初始化的副本集的配置:

>rs0:PRIMARY> rs.conf()

 9.在其余的两个节点启动MongoDB

在slave上面执行命令:

# docker run \
--name mongo \
-v /home/core/mongo-files/data:/data/db \
-v /home/core/mongo-files:/opt/keyfile \
--hostname="node2.example.com" \
--add-host node1.example.com:${node1} \
--add-host node2.example.com:${node2} \
--add-host node3.example.com:${node3} \
-p 27017:27017 -d mongo:4.0 \
--smallfiles \
--keyFile /opt/keyfile/mongodb-keyfile \--replSet "rs0"

在arbiter上面执行命令:

# docker run \
--name mongo \
-v /home/core/mongo-files/data:/data/db \
-v /home/core/mongo-files:/opt/keyfile \
--hostname="node3.example.com" \
--add-host node1.example.com:${node1} \
--add-host node2.example.com:${node2} \
--add-host node3.example.com:${node3} \
-p 27017:27017 -d mongo:4.0 \
--smallfiles \
--keyFile /opt/keyfile/mongodb-keyfile \
--replSet "rs0"

10.将那两个节点加到副本集上

回到master节点,如果你在这里按了几次回车键(enter)的话,你会看到下面的提示:“rs0:PRIMARY”。这是因为这个节点是副本集“rs0”的主节点。

首先将节点加入复制集:

rs0:PRIMARY> rs.add("node2.example.com")

  rs0:PRIMARY> rs.addArb("node3.example.com")

 

修改节点的优先级:

db.auth("siteRootAdmin", "password");    --首先授权认证

  将主节点的优先级设置为10

PRIMARY>rscfg.members[0].priority = 10
将从节点的优先级设置为2
PRIMARY>rscfg.members[1].priority = 2
PRIMARY> rs.reconfig(rscfg)

查看设置的优先级:

rs0:PRIMARY> rs.conf()

验证其它节点是否正确的加到这个副本集当中:

rs0:PRIMARY> rs.status()

结果如下说明节点添加成功

 从库开启读操作(此时可以测试主库插入,从库查看,同步正常):

rs.slaveOk();
show dbs

local    0.000GB

mydb   0.000GB

可能会花几分钟的时间来将master上面的数据同步到其余的两个节点上面。你可以通过查看日志来观察每一个MongoDB的Docker容器里面发生了什么。在任意一个服务器上面执行下面的命令就可以了:

root@master*:/# docker logs -ft mongo

  查看各节点的状态

rs.status()
查看各节点的配置及优先级
rs.conf()

查看整体状态:
rs.status()

查看主从节点的切换
停掉主节点
docker stop master_mongo

查看从节点变化
docker stop slave_mongo
可以看到从节点已经变成了primary

当主节点再次启动
它又再次变为primary

查看主从数据库同步:
插入数据库:
rs0:PRIMARY> use admin
rs0:PRIMARY> db.auth('rootAdmin','Admin168+);
rs0:PRIMARY> use Test01
rs0:PRIMARY> db.createUser( {
... ... user: "Test01",
... ... pwd: "password",
... ... roles: [ { role: "dbOwner", db: "Test01" } ]});
rs0:PRIMARY> db.Test01.insert([ { "title" : "fczlm", "year" : 2019, "imdb_rating" : 8.1 },{ "title" : "AAA", "year" : 2020, "imdb_rating" : 7.6 } ]);

查看数据库
rs0:PRIMARY> show dbs

验证 主从节点切换

优点:当主库挂掉,从库会被选为主库!当原先挂掉的主库再次启动,由于优先级的设置,挂掉的主库还是会变为主库

  192.168.3.81变为主节点

  再次启动主节点(192.168.3.80)查看其变化

测试 数据库同步

连接mongo数据库操作(其它两台操作同下)

输入IP地址及端口号

输入之前创建的root用户名和密码

user: "siteUserAdmin"

pwd: "password"

  在主节点上创建数据库

创建思路:

  

  在从节点中认证并查看

  在Robo  3T上查验证

  结论

现在你拥有了一个MongoDB集群。你可以自由的在任何时刻添加节点到这个集群上。你甚至可以关闭其中的一个节点,包括主节点,然后观察一个另外一个节点重新变成了主节点。由于这些数据都被写在了你的本机文件系统当中了,所以重启任何一个节点都不是什么大问题。

  

 

posted @ 2020-01-20 16:22  ly-uping  阅读(1684)  评论(0编辑  收藏  举报