contenedor comandos asignar docker docker-compose

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