comandos - asignar ip a contenedor docker
Usando el host ip en docker-compose (5)
Quiero crear un archivo docker-compose que pueda ejecutarse en diferentes servidores.
Para eso tengo que poder especificar el host-ip o el nombre de host del servidor (donde se ejecutan todos los contenedores) en varios lugares en el docker-compose.yml .
Por ejemplo, para un contenedor de cónsules donde quiero definir cómo pueden encontrar el servidor otros contenedores de cónsules.
consul:
image: progrium/consul
command: -server -advertise 192.168.1.125 -bootstrap
Obviamente no quiero codificar 192.168.1.125.
Podría usar env_file : para especificar el nombre de host o la ip y adoptarlo en cada servidor, así que tengo esa información en un lugar y la uso en docker-compose.yml. Pero esto solo se puede utilizar para especificar variables de entorno y no para el parámetro de publicidad.
¿Hay una mejor solución?
¿Hay una mejor solución?
¡Absolutamente!
No necesita la IP del host para la comunicación entre contenedores.
Si
link
contenedores en su archivo
docker-compose.yaml
, tendrá acceso a una serie de variables de entorno que puede usar para descubrir las direcciones IP de sus servicios.
Considere, por ejemplo, una configuración compuesta por docker con dos contenedores: uno que usa
consul
y otro que ejecuta algún servicio que necesita hablar con el cónsul.
consul:
image: progrium/consul
command: -server -bootstrap
webserver:
image: larsks/mini-httpd
links:
- consul
Primero, al iniciar el
consul
con just
-server -bootstrap
, el
consul
-server -bootstrap
su propia dirección de publicidad, por ejemplo:
consul_1 | ==> Consul agent running!
consul_1 | Node name: ''f39ba7ef38ef''
consul_1 | Datacenter: ''dc1''
consul_1 | Server: true (bootstrap: true)
consul_1 | Client Addr: 0.0.0.0 (HTTP: 8500, HTTPS: -1, DNS: 53, RPC: 8400)
consul_1 | Cluster Addr: 172.17.0.4 (LAN: 8301, WAN: 8302)
consul_1 | Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false
consul_1 | Atlas: <disabled>
En el contenedor del
webserver
, encontramos las siguientes variables de entorno disponibles para pid 1:
CONSUL_PORT=udp://172.17.0.4:53
CONSUL_PORT_8300_TCP_START=tcp://172.17.0.4:8300
CONSUL_PORT_8300_TCP_ADDR=172.17.0.4
CONSUL_PORT_8300_TCP_PROTO=tcp
CONSUL_PORT_8300_TCP_PORT_START=8300
CONSUL_PORT_8300_UDP_END=udp://172.17.0.4:8302
CONSUL_PORT_8300_UDP_PORT_END=8302
CONSUL_PORT_53_UDP=udp://172.17.0.4:53
CONSUL_PORT_53_UDP_ADDR=172.17.0.4
CONSUL_PORT_53_UDP_PORT=53
CONSUL_PORT_53_UDP_PROTO=udp
CONSUL_PORT_8300_TCP=tcp://172.17.0.4:8300
CONSUL_PORT_8300_TCP_PORT=8300
CONSUL_PORT_8301_TCP=tcp://172.17.0.4:8301
CONSUL_PORT_8301_TCP_ADDR=172.17.0.4
CONSUL_PORT_8301_TCP_PORT=8301
CONSUL_PORT_8301_TCP_PROTO=tcp
CONSUL_PORT_8301_UDP=udp://172.17.0.4:8301
CONSUL_PORT_8301_UDP_ADDR=172.17.0.4
CONSUL_PORT_8301_UDP_PORT=8301
CONSUL_PORT_8301_UDP_PROTO=udp
CONSUL_PORT_8302_TCP=tcp://172.17.0.4:8302
CONSUL_PORT_8302_TCP_ADDR=172.17.0.4
CONSUL_PORT_8302_TCP_PORT=8302
CONSUL_PORT_8302_TCP_PROTO=tcp
CONSUL_PORT_8302_UDP=udp://172.17.0.4:8302
CONSUL_PORT_8302_UDP_ADDR=172.17.0.4
CONSUL_PORT_8302_UDP_PORT=8302
CONSUL_PORT_8302_UDP_PROTO=udp
CONSUL_PORT_8400_TCP=tcp://172.17.0.4:8400
CONSUL_PORT_8400_TCP_ADDR=172.17.0.4
CONSUL_PORT_8400_TCP_PORT=8400
CONSUL_PORT_8400_TCP_PROTO=tcp
CONSUL_PORT_8500_TCP=tcp://172.17.0.4:8500
CONSUL_PORT_8500_TCP_ADDR=172.17.0.4
CONSUL_PORT_8500_TCP_PORT=8500
CONSUL_PORT_8500_TCP_PROTO=tcp
Hay un conjunto de variables para cada puerto
EXPOSE
d por la imagen del
consul
.
Por ejemplo, en esa segunda imagen, podríamos interactuar con la API REST de cónsul conectándose a:
http://${CONSUL_PORT_8500_TCP_ADDR}:8500/
Con la nueva versión de Docker Compose ( 1.4.0 ) debería poder hacer algo como esto:
docker-compose.yml
consul:
image: progrium/consul
command: -server -advertise HOSTIP -bootstrap
golpetazo
$ sed -e "s/HOSTIP/${HOSTIP}/g" docker-compose.yml | docker-compose --file - up
Esto es gracias a la nueva característica:
Compose ahora puede leer la configuración de YAML desde la entrada estándar, en lugar de desde un archivo, especificando - como el nombre del archivo. Esto facilita la generación dinámica de la configuración:
$ echo ''redis: {"image": "redis"}'' | docker-compose --file - up
Docker crea las variables de entorno, como se sugirió en la solución anterior, cuando los contenedores están vinculados. Pero los env no se actualizan automáticamente si se reinicia el contenedor. Por lo tanto, no se recomienda utilizar variables de entorno en la producción.
Docker, además de crear las variables de entorno, también actualiza las entradas de host en el archivo / etc / hosts. De hecho, la documentación de Docker recomienda utilizar las entradas de host de etc / hosts en lugar de las variables de entorno.
Referencia: https://docs.docker.com/userguide/dockerlinks/
A diferencia de las entradas de host en el archivo / etc / hosts, las direcciones IP almacenadas en las variables de entorno no se actualizan automáticamente si se reinicia el contenedor de origen. Recomendamos utilizar las entradas de host en / etc / hosts para resolver la dirección IP de los contenedores vinculados.
He usado la IP de red interna de Docker que parece ser estática: 172.17.0.1
docker-compose permite usar variables de entorno del entorno que ejecuta el comando compose.
Consulte la documentación en https://docs.docker.com/compose/compose-file/#variable-substitution
Suponiendo que puede crear un script de envoltura, como sugirió @balver, puede establecer una variable de entorno llamada
EXTERNAL_IP
que incluirá el valor de
$(docker-machine ip)
.
Ejemplo:
#!/bin/sh
export EXTERNAL_IP=$(docker-machine ip)
exec docker-compose $@
y
# docker-compose.yml
version: "2"
services:
consul:
image: consul
environment:
- "EXTERNAL_IP=${EXTERNAL_IP}"
command: agent -server -advertise ${EXTERNAL_IP} -bootstrap
Desafortunadamente, si está utilizando una asignación de puerto aleatoria, no hay forma de agregar
EXTERNAL_PORT
, por lo que los puertos deben estar vinculados estáticamente.
PD: Algo muy similar está habilitado de forma predeterminada en HashiCorp Nomad, también incluye puertos asignados. Doc: https://www.nomadproject.io/docs/jobspec/interpreted.html#interpreted_env_vars