cómo vincular contenedores docker entre sí con docker-compose
Tengo que configurar un conjunto de réplicas de mongo con docker-compose. Para el conjunto de réplicas los contenedores tienen que conocerse.
Lo intenté en 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
...
Recibo un mensaje circular de importación. Pero si elimino el back-link a dbreplicasetpart1 no puedo hacer ping de dbreplicasetpart2 a dbreplicasetpart1. ¿Cuál es la solución?
4 answers
Actualizado para Docker 1.10
Docker 1.10 permite la definición de redes dentro del archivo de composición. Aquí está el código actualizado
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
Respuesta anterior para Docker 1.9
A partir de Docker 1.9, la solución para esto es crear una red personalizada y pasarla al comando docker-compose up
.
Crear una red
docker network create --driver bridge my-net
-
Haga referencia a esa red como una variable de entorno (
${NETWORK}
)en docker-compose.archivos yml. Eg:
```
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"
```
Tenga en cuenta que replica1
en http://replica1:27018
se resolverá a la dirección ip del servicio replica1 (contenedor). No es necesario codificar direcciones ip; una entrada para replica1 se agrega automáticamente al /etc/host del contenedor replica2. Lo mismo ocurre con el contenedor replica1. Docker añadirá una entrada para replica2 en su archivo/etc / host.
- Llame a docker-compose, pasándole la red que creó
NETWORK=my-net docker-compose up -d -f docker-compose.yml
He creado un red de puentes por encima del cual solo funciona dentro de un nodo (host). Bien por Dev. Si necesita obtener dos nodos para comunicarse entre sí, debe crear un red de superposición. Sin embargo, el mismo principio. Pase el nombre de red al comando docker-compose up.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-19 10:07:06
Debes usar el patrón embajador:
Https://docs.docker.com/engine/admin/ambassador_pattern_linking /
Básicamente se crea un componente intermedio que une ambos. Puede ver un ejemplo que usamos con el servicio Eureka discovery de Spring Cloud:
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"
Para simplificar, solo copié los enlaces
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-03 15:44:36
Decidimos usar la solución con el embajador. De hecho, es la solución más cómoda. La configuración que funciona para nosotros:
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"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-13 08:33:14
Esto es lo que debería funcionar en Docker 1.7.1 (en caso de que se haya quedado con 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
script:
#!/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\"}"
Aquí hay una explicación:
- Configuramos nuestro propio servidor DNS en un contenedor
- Configuramos nuestros contenedores para usar ese servidor
- Configuramos ese servidor DNS usando peticiones HTTP especiales
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-14 02:52:36