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

时间:2014-11-28 11:21:40

标签: mongodb docker

我尝试使用docker部署mongodb replicaset。 我设法通过执行以下操作在同一台服务器上执行此操作:

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();'

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

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

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

4 个答案:

答案 0 :(得分:2)

我使用docker-machine和virtual box作为驱动程序在不同的物理服务器上创建了副本集:

$ 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 - >在每个环境(server1,server2,server3)上 - >设置 - >网络 - >适配器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

现在容器应该正在运行,您可以通过运行来检查它们 每个终端的$ docker 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中

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

答案 1 :(得分:1)

您可以使用“Weave - the Docker network”轻松解决问题。

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

答案 2 :(得分:0)

#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();"

答案 3 :(得分:-2)

我编写了一个docker-image脚本,为任意数量的容器设置mongodb replicaSet,并在添加更多容器时自动进行缩放。查看github github repodocker registry

使用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
要使用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目录[default:/ var / config]下面的示例安装主机   目录/ var / config到容器的配置卷   您可以使用docker推荐的任何共享卷之间的方式   只是,容器,如安装主机目录或数据卷容器)   您为配置卷(/ var / config)指定了正确的路径。

     

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