Me gustaría configurar los contenedores Docker para que se vean y se sientan como un sistema real asignándoles direcciones IP estáticas en mi red.
Actualmente tengo una configuración de puente de red (br0) en el host. Lo he DOCKER_OPTS="-b=br0"
configurado en el /etc/default/docker
archivo. Puedo asignar direcciones estáticas a cada uno de los contenedores a través de sus /etc/network/interface
archivos.
El problema es que Docker seguirá asignando direcciones IP por sí solo. (¿Cómo puedo detener esto?) Aún más preocupante es que ahora utilizará el esquema IP de la red puenteada. Lo que causará problemas de red, ya que puede asignar direcciones que ya están en uso en la red.
Problemas:
Red bloqueada/pausada.
La dirección de respuesta al hacer ping al contenedor puede cambiar.
Error messages such as this are seen in the logs of the host:
kernel: [31912.876161] br0: port 3(vethb228701) entered disabled state
kernel: [31913.441517] device veth122d9f8 left promiscuous mode
kernel: [22491.609856] audit: type=1400 audit(1434148604.621:124): apparmor="DENIED" operation="getattr" info="Failed name lookup - disconnected path" error=-13 profile="/usr/sbin/ntpd" name="var/lib/docker/aufs/diff/eb00895db3d297979df741cd560ccbea2ab4d572264bd703fc6cbc7ea2acb5c4/usr/lib" pid=30955 comm="ntpd" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
Docker también asigna al contenedor una dirección en la misma subred que mi red. Al principio pensé que se trataba simplemente de agregar una línea al /etc/hosts
archivo del contenedor. Lo cual hace, pero incluso después de eliminarlo se siguen viendo problemas.
Ejemplo:
root@myhostname:/# cat /etc/hosts
X.X.192.3 myhostname.mydomain.com myhostname
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
root@myhostname:/# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:09:1a:c0:03
inet addr:X.X.X.X Bcast:X.X.X.X Mask:255.255.252.0
inet6 addr: fe80::42:9ff:fe1a:c003/64 Scope:Link
UP BROADCAST RUNNING MTU:1500 Metric:1
RX packets:231 errors:0 dropped:26 overruns:0 frame:0
TX packets:46 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:23719 (23.7 KB) TX bytes:3960 (3.9 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Si no se asigna ningún nombre de host a través de la línea de comando (-h) para iniciar el contenedor, utilizará el nombre de host asignado aleatoriamente.
Ambiente:
Host:
OS: Ubuntu 14.04.2
Arch: PPC64LE
Kernel: 3.16.0-30
docker version
:
Client version: 1.4.1-dev
Client API version: 1.17
Go version (client): gccgo (GCC) 5.0.0 20150118 (experimental)
Git commit (client): 7294f26
OS/Arch (client): linux/ppc64le
Server version: 1.4.1-dev
Server API version: 1.17
Go version (server): gccgo (GCC) 5.0.0 20150118 (experimental)
Git commit (server): 7294f26
Hardware:
IBM Power 8, 8247-22L
CPUs: 192
Memory: 512GB
Contenedores:
OS: Ubuntu 14.04.2
Arch: PPC64LE
Kernel: 3.16.0-30
Red:
brctl show
bridge name bridge id STP enabled interfaces
br0 8000.6cae8b6aaf64 no eth0
br0 Link encap:Ethernet HWaddr 6c:ae:8b:6a:af:64
inet addr:X.X.X.X Bcast: X.X.X.X Mask:255.255.252.0
inet6 addr: fe80::6eae:8bff:fe6a:af64/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6750867 errors:0 dropped:80 overruns:0 frame:0
TX packets:1586308 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1049658934 (1.0 GB) TX bytes:6936734104 (6.9 GB)
eth0 Link encap:Ethernet HWaddr 6c:ae:8b:6a:af:64
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:7155242 errors:0 dropped:7598 overruns:0 frame:0
TX packets:6347549 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1212526214 (1.2 GB) TX bytes:7339350703 (7.3 GB)
Interrupt:249
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:238 errors:0 dropped:0 overruns:0 frame:0
TX packets:238 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:22564 (22.5 KB) TX bytes:22564 (22.5 KB)
Respuesta1
También intenté solucionar este problema hace algún tiempo. No pude encontrar una manera de alterar el comportamiento de Docker con respecto a sus asignaciones de IP sin deshabilitar toda la funcionalidad de red ( --net=none
). Así que asigné una subred no utilizada hasta el momento a la interfaz del puente de Docker y dejé que Docker hiciera la tarea. También escribí un demonio que escucha ciertos eventos de la API de Docker y luego envía actualizaciones dinámicas a nuestro servidor DNS, por lo que no tengo que preocuparme por las IP y puedo abordar los contenedores por nombre.
Aquí está el repositorio de github para el demonio DNS. https://github.com/cschritt/docker-dns-daemon Pronto impulsaré mis últimos cambios y algunas refactorizaciones.
Respuesta2
Lamentablemente, parece que no hay forma de evitar que Docker asigne direcciones IP a contenedores en modo puente. Como solución alternativa, agrego pre-up ip addr flush dev eth0
para /etc/network/interface
descartar la dirección IP de Docker comodescrito aquí. A continuación se muestra un ejemplo de cómo se puede hacer:
auto eth0
iface eth0 inet static
pre-up ip addr flush dev eth0
address 192.168.0.249
netmask 255.255.255.0
gateway 192.168.0.1
La advertencia de este enfoque es con múltiples contenedores cuando Docker inyecta sus propias direcciones IP incorrectas/anuladas en /etc/hosts
los archivos de los contenedores. La única forma que encontré para solucionar este problema es instalar inotify-tools
el paquete y ejecutar el siguiente script para volver /etc/hosts
a su estado predefinido tan pronto como Docker lo cambie:
#!/bin/sh
while /usr/bin/inotifywait -e close /etc/hosts; do
cp -v /etc/hosts.orig /etc/hosts
done
El script anterior requiere que agregue /etc/hosts.orig
un archivo válido al contenedor.
Respuesta3
Comenzando con Docker 1.10, que se lanzará en los próximos días, puede especificar una dirección IP estática explícitamente al iniciar su contenedor, con las opciones --ip=
y --ip6=
, para especificar direcciones IPv4 e IPv6 respectivamente. Estos se pueden usar con docker run
y docker network connect
persistir mientras exista el contenedor.