我尝试使用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副本如何在不同服务器甚至不同数据中心之间相互通信(主服务器和辅助服务器可以更改)?
答案 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 repo或docker 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名称_