在不同的物理服务器上使用 Docker 部署 mongodb 副本集服务器



我正在尝试使用 docker 部署一个 mongodb 副本集。我设法通过执行以下命令在同一台服务器上执行此操作:

docker run -d --expose 27017 --name mongodbmycompany1 dockerfile/mongodb mongod --replSet rsmycompa
docker run -d --expose  27017 --name mongodbmycompany2 dockerfile/mongodb mongod --replSet rsacommeassure
docker run -d --expose 27017 --name mongodbmycompany3 dockerfile/mongodb mongod --replSet rsacommeassure
MONGODB1=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' mongodbmycompany1)
MONGODB2=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' mongodbmycompany2)
MONGODB3=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' mongodbmycompany3)
echo $MONGODB1
echo $MONGODB2
echo $MONGODB3
echo "Mongodb Replicaset init"
docker exec mongodbmycompany1 mongo 127.0.0.1:27017/mycompany --eval 'if(!rs.conf()) {     rs.initiate(); cfg = rs.conf(); cfg.members[0].host = "'$MONGODB1':27017"; rs.reconfig(cfg); rs.add("'$MONGODB2':27017"); rs.add("'$MONGODB3':27017"); } rs.status();'

它按预期工作。我的副本集已初始化,我的 mongodb 结果集配置包含由其内部 IP 地址标识的 3 台服务器。这并不完美,因为我更喜欢使用服务器名称,但我没有设法做到。Docker 只使用映像启动时使用 --link 参数传递的服务器名称填充每个/etc/hosts 文件。如果我在其他服务器运行时添加新服务器。这些服务器不会 ping 新服务器。

现在我还有一个问题。在生产中,在同一物理服务器上运行大量Mongodb docker映像是可能的,但这并不安全:- 如果我的物理服务器出现故障,我将丢失所有Mongodb副本,并且我的服务已关闭- 如果我的物理服务器使用内部存储,我所有的 docker 映像都使用相同的磁盘...而且我会遇到 IO 问题。

所以我的问题是:如何在多个物理服务器上部署许多mongodb副本?当这些mongodb副本位于不同的服务器甚至不同的数据中心时,它们如何相互通信(主服务器和辅助服务器可以更改)?

让我们假设:

  1. 您有 3 个不同的 docker 主机(服务器),IP 10.1.1.10110.1.1.10210.1.1.103
  2. 想要部署名为 rsacommeassure 的单个副本集
  3. Dockerfile s for mongodb 公开端口 27017
  4. 所有服务器都位于受信任区域中,可以相互通信

首先,让我们在每个服务器上启动mongodb容器(10.1.1.101 ~$用于命令提示符):

10.1.1.101 ~$ docker run -d -p 27017:27017 --name mongodbmycompany1 dockerfile/mongodb mongod --replSet rsacommeassure
10.1.1.102 ~$ docker run -d -p 27017:27017 --name mongodbmycompany2 dockerfile/mongodb mongod --replSet rsacommeassure
10.1.1.103 ~$ docker run -d -p 27017:27017 --name mongodbmycompany3 dockerfile/mongodb mongod --replSet rsacommeassure
-p 27017:27017在主机 IP 上

公开端口 27017,以便可以在服务器的主机 IP 地址上访问 mongo。

然后你需要启动副本集,所以只需对 mongodb 容器运行它(我将在这里选择 server1):

your_laptop ~$ > mongo --host 10.1.1.101 
MongoDB shell version: 2.6.9
connecting to: test
> rs.initiate()
> cfg = rs.conf()
> cfg.members[0].host = "10.1.1.101:27017"
> rs.reconfig(cfg)
> rs.add("10.1.1.102:27017")
> rs.add("10.1.1.103:27017") 
> rs.status();

IP是本地的,但只要服务器可以相互通信(VPN,防火墙,DMZ等),它就可以与全局一起使用。顺便说一句,您应该仔细考虑安全性。

我使用 docker 机器和虚拟盒子作为驱动程序在不同的物理服务器上创建了一个副本集:

$ docker-machine create --driver virtualbox server1
$ docker-machine create --driver virtualbox server2
$ docker-machine create --driver virtualbox server3

在每个终端中打开 3 个不同的终端

$(Terminal1) eval "$(docker-machine env server1)"
$(Terminal2) eval "$(docker-machine env server2)"
$(Terminal3) eval "$(docker-machine env server3)"

在每个航站楼中:

$(Terminal1) docker run -d -p 27017:27017 --name mongoClient1 mongo mongod --replSet r1
$(Terminal2) docker run -d -p 27017:27017 --name mongoClient2 mongo mongod --replSet r1
$(Terminal3) docker run -d -p 27017:27017 --name mongoClient3 mongo mongod --replSet r1

进入 VirtualBox -> 在每个环境(服务器 1、服务器 2、服务器 3)>设置 -> 网络 -> 适配器 1 -> 端口转发。创建新规则协议 TCP,主机端口 - 27017,访客端口 - 27017,将主机 IP 和访客 IP 留空

现在重新启动所有环境,您可以从 VirtualBox 或终端执行此操作,从终端只需运行:

$(Terminal1) docker-machine restart server1
$(Terminal2) docker-machine restart server2
$(Terminal3) docker-machine restart server3

重新启动容器:

$(Terminal1) docker start mongoClient1
$(Terminal2) docker start mongoClient2
$(Terminal3) docker start mongoClient3

现在容器应该正在运行,您可以通过运行来检查它们$ 码头工人 ps 在每个终端

进入第一个容器(或其他)的 Mongo Shell

$(Terminal1) docker exec -it mongoClient1 mongo
// now we are in the Mongo Shell
$(Mongo Shell) rs.initiate()
$(Mongo Shell) cfg = rs.conf()
$(Mongo Shell) cfg.members[0].host = <server1's Ip Address>
// you should get server1's Ip Address by running $ docker-machine ls, mine was 192.168.99.100
$(Mongo Shell) rs.reconfig(cfg)
$(Mongo Shell Primary) rs.add("<server2's Ip Address>:27017")
// now we added a Secondary
$(Mongo Shell Primary) rs.add("<server3's Ip Address>:27017", true)
// now we added an Arbiter
$(Mongo Shell Primary) use planes
// now we create a new database
$(Mongo Shell Primary) db.tranporters.insert({name:'Boeing'})
// create a new collection
$(Mongo Shell Primary) db.tranporters.find()
// we obtain the inserted plane

要连接到辅助数据库,您可以:

$(Terminal2) docker exec -it mongoClient2 mongo planes
// or
$(Mongo Shell Primary) db = connect ("<server2's Ip Address>:27017/planes")

现在我们处于二级的蒙戈外壳中

$(Mongo Shell Secondary) rs.slaveOk()
// to allow readings from the Shell
$(Mongo Shell Secondary)db.tranporters.find()
// should return inserted plane

您可以使用"Weave - The Docker network"轻松解决问题。

Weave 创建了一个覆盖网络,该网络将容器连接到不同的主机上,甚至在不同的云提供商处也是如此。Weave 还提供 DNS 服务,可让您在 Weave 网络中按名称查找容器。

#Here stop already running instances
docker stop m1 m2 m3
#Cleanup of the volumes
docker rm -f m1 m2 m3
# Start MongoDB services optimised for faster startup
docker run  -dP --name m1 mongo mongod --replSet "r1" --noprealloc --smallfiles --nojournal --syncdelay 0 
docker run  -dP --name m2 mongo mongod --replSet "r1" --noprealloc --smallfiles --nojournal --syncdelay 0 
docker run  -dP --name m3 mongo mongod --replSet "r1" --noprealloc --smallfiles --nojournal --syncdelay 0
export M1_ADDRESS=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' m1`
export M2_ADDRESS=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' m2`
export M3_ADDRESS=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' m3`
docker exec m1 mongo --eval "rs.initiate();"
docker exec m1 mongo --eval "cfg = rs.conf(); cfg.members[0].host = '$M1_ADDRESS:27017'; rs.reconfig(cfg);"
docker exec m1 mongo --eval "rs.add('$M2_ADDRESS:27017');rs.add('$M3_ADDRESS:27017')"
# Check if everything is fine.
docker exec m1 mongo --eval "rs.status();"

我编写了一个 docker 映像脚本,该映像为任意数量的容器设置 mongodb replicaSet,并在添加更多容器时自动扩展。 查看 GitHub GitHub 存储库或 Docker 注册表

使用 Docker Compose

设置你的 docker-compose.yml

version: "2"
services:
  <your_service_name>:
     image: rollymaduk/mongo-replica:local
     environment:
       REPLICA_NAME: "<your_replica_name>"
     volumes:
     -  /var/config:/var/config

在命令行中运行

docker-compose up

纵向扩展到更多容器

docker-compose scale <your_service_name>=3

码头工人云
要使用 docker-cloud 部署 mongo-db replicaSet,请设置堆栈文件

stack.yml:不需要共享卷的堆栈文件

<service_name>:
  image: rollymaduk/mongo-replica:cloud
  deployment_strategy: high_availability
  target_num_containers: 3
  environment:
    REPLICA_NAME: <your_replica_name>
    DOCKERCLOUD_AUTH: <your_docker_auth_key>

stack.yml:需要共享卷的堆栈文件

<service_name>:
  image: rollymaduk/mongo-replica:local
  deployment_strategy: high_availability
  target_num_containers: 3
  volumes:
    - /var/config:/var/config
  environment:
    REPLICA_NAME: <your_replica_name>

使用 docker-cloud cli 在命令行中运行(如果云中不存在堆栈文件)

docker-cloud stack create --name <your_stack_name> -f <your_stack_file>
docker-cloud stack start <your_stack_name>

使用 docker-cloud cli 在命令行中运行(如果云中已存在堆栈文件)

docker-cloud stack update -f <your_stack_file> <your_stack_name>
docker-cloud stack redeploy <your_stack_name>

重要事项: 您必须指定共享卷并将其挂载到容器的 config 目录 [默认:/var/config ] 下面的示例挂载主机 目录/var/config 到容器的配置卷。
您可以使用任何 docker 推荐的共享卷的方式在 容器,即挂载主机目录或数据卷容器),只是 您可以为配置卷 (/var/config) 指定正确的路径。

_to更改默认配置目录,请使用环境变量 --CONFIG_DIR设置容器。确保更新主机卷 反映您的新 --CONFIG_DIR name_ 的路径

最新更新