我必须使用docker-compose设置mongo副本集。对于副本集,容器必须彼此了解。
我试过docker-compose.yml
dbreplicasetpart1:
image: mongo:2.6.8
expose:
- '27018'
links:
- replicasetpart2
- replicasetpart3
cap_add:
- NET_ADMIN
dbreplicasetpart2:
image: mongo:2.6.8
links:
- replicasetpart1
- replicasetpart3
expose:
- '27019'
cap_add:
- NET_ADMIN
...
我收到循环导入消息。但是,如果我删除dbreplicasetpart1的反向链接,我无法从dbreplicasetpart2 ping到dbreplicasetpart1。 解决方案是什么?
答案 0 :(得分:41)
针对Docker 1.10进行了更新
Docker 1.10允许在撰写文件中定义网络。 这是更新后的代码
version: "2"
services:
replica1:
image: mongo:2.6.8
container_name: replica1
networks:
- my-net
ports:
- "27018"
environment:
REPLICA2_URL: "http://replica2:27019"
replica2:
image: mongo:2.6.8
container_name: replica2
networks:
- my-net
ports:
- "27019"
environment:
REPLICA1_URL: "http://replica1:27018"
networks:
my-net:
driver: bridge
Docker 1.9的上一个答案
从Docker 1.9开始,解决方案是创建一个自定义网络并将其传递给docker-compose up
命令。
创建网络
docker network create --driver bridge my-net
在docker-compose.yml文件中将网络引用为环境变量(${NETWORK}
)。例如:
```
replica1:
image: mongo:2.6.8
container_name: replica1
net: ${NETWORK}
ports:
- "27018"
environment:
REPLICA2_URL: "http://replica2:27019"
replica2:
image: mongo:2.6.8
container_name: replica2
net: ${NETWORK}
ports:
- "27019"
environment:
REPLICA1_URL: "http://replica1:27018"
```
请注意replica1
中的http://replica1:27018
将解析为replica1服务(容器)的IP地址。无需硬编码IP地址; replica1的条目自动添加到replica2容器的/ etc / host中。 replica1容器也是如此。 Docker将在/ etc / host文件中为replica2添加一个条目。
NETWORK=my-net docker-compose up -d -f docker-compose.yml
我已经创建了一个 bridge network ,只能在一个节点(主机)中运行。对开发者有好处。如果您需要让两个节点相互通信,则需要创建 overlay network 。同样的原则。您将网络名称传递给docker-compose up命令。
答案 1 :(得分:14)
你应该使用大使模式:
https://docs.docker.com/engine/admin/ambassador_pattern_linking/
基本上,您创建了一个将两者连接在一起的中间组件。您可以看到我们在Spring Cloud的Eureka发现服务中使用的示例:
ambassador:
image: cpuguy83/docker-grand-ambassador
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
command: "-name eureka_1 -name eureka2_1 "
eureka:
links:
- "ambassador:eureka2"
eureka2:
links:
- "ambassador:eureka"
为简单起见,我只复制了链接
答案 2 :(得分:0)
我们想出与大使一起使用该解决方案。这确实是更舒适的解决方案。 适用于我们的配置:
amba1:
image: cpuguy83/docker-grand-ambassador
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
command: "-name cucumber_dbreplicasetpart1_1"
amba2:
image: cpuguy83/docker-grand-ambassador
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
command: "-name cucumber_dbreplicasetpart2_1"
amba3:
image: cpuguy83/docker-grand-ambassador
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
command: "-name cucumber_dbreplicasetpart3_1"
dbreplicasetpart1:
image: 'mongo:2.6.8'
hostname: dbreplicasetpart1
command: >
bash -c
'
mongod --fork --logpath mongo.log --smallfiles --replSet rs1
echo "
printjson(
rs.initiate(
{
_id : \"rs1\",
members : [
{_id : 0, host : \"dbreplicasetpart1:27017\"},
{_id : 1, host : \"dbreplicasetpart2:27017\"},
{_id : 2, host : \"dbreplicasetpart3:27017\"},
]
}
)
);
" | mongo;
tail -f mongo.log
'
links:
- "amba2:dbreplicasetpart2"
- "amba3:dbreplicasetpart3"
dbreplicasetpart2:
image: 'mongo:2.6.8'
hostname: dbreplicasetpart2
command: >
bash -c
'
mongod --fork --logpath mongo.log --smallfiles --replSet rs1
echo "
printjson(
rs.initiate(
{
_id : \"rs1\",
members : [
{_id : 0, host : \"dbreplicasetpart1:27017\"},
{_id : 1, host : \"dbreplicasetpart2:27017\"},
{_id : 2, host : \"dbreplicasetpart3:27017\"},
]
}
)
);
" | mongo;
tail -f mongo.log
'
links:
- "amba1:dbreplicasetpart1"
- "amba3:dbreplicasetpart3"
dbreplicasetpart3:
image: 'mongo:2.6.8'
hostname: dbreplicasetpart3
command: >
bash -c
'
mongod --fork --logpath mongo.log --smallfiles --replSet rs1
echo "
printjson(
rs.initiate(
{
_id : \"rs1\",
members : [
{_id : 0, host : \"dbreplicasetpart1:27017\"},
{_id : 1, host : \"dbreplicasetpart2:27017\"},
{_id : 2, host : \"dbreplicasetpart3:27017\"},
]
}
)
);
" | mongo;
tail -f mongo.log
'
links:
- "amba1:dbreplicasetpart1"
- "amba2:dbreplicasetpart2"
答案 3 :(得分:0)
不更新docker-compose.yml
文件
docker network connect docker-compose-network-you-want-to-connect conatianer-name-from-another-docker-compose
更多here
答案 4 :(得分:-1)
以下是Docker 1.7.1中仍然可以使用的内容(如果你坚持使用CentOS 6):
etcd:
image: elcolio/etcd:latest
skydns:
image: outrider/skydns
links:
- etcd
environment:
ETCD_MACHINES: "http://etcd:4001"
SKYDNS_DOMAIN: "docker"
SKYDNS_PATH_PREFIX: my
SKYDNS_NDOTS: 0
SKYDNS_VERBOSE: "true"
SKYDNS_ADDR: 0.0.0.0:53
expose:
- 53
my-service:
image: alpine
command: sh -c "dns_add my-service && ping my-service"
links:
- etcd
- skydns
dns_add
脚本:
#!/usr/bin/env sh
# This script configures resov.conf to use
# "skydns" name server with "docker" domain
# and adds a service name specified in the first argument
SERVICE_NAME=$1
waitforit () {
HOST=$1
PORT=$2
TIME_OUT=${3:-30};
END=$(($(date "+%s+$TIME_OUT")))
while [ $(date "+%s") -lt $END ]
do nc -z -w1 $HOST $PORT && break
done
return $END
}
# Use skydns to resolve names
echo "nameserver `resolveip -s skydns`" > /etc/resolv.conf
echo "search docker" >> /etc/resolv.conf
# Put yourself to DNS
ETCD_HOST=etcd
ETCD_PORT=4001
waitforit $ETCD_HOST $ETCD_PORT
HOST_IP=`resolveip -s $HOSTNAME`
apk update && apk add curl
curl -XPUT http://$ETCD_HOST:$ETCD_PORT/v2/keys/my/docker/$SERVICE_NAME -d value="{\"host\":\"$HOST_IP\"}"
以下是解释: