¿Cómo puedo desactivar la asignación automática de dirección IP de Docker?

¿Cómo puedo desactivar la asignación automática de dirección IP de Docker?

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/dockerarchivo. Puedo asignar direcciones estáticas a cada uno de los contenedores a través de sus /etc/network/interfacearchivos.

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/hostsarchivo 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 eth0para /etc/network/interfacedescartar 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/hostslos archivos de los contenedores. La única forma que encontré para solucionar este problema es instalar inotify-toolsel paquete y ejecutar el siguiente script para volver /etc/hostsa 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.origun 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 runy docker network connectpersistir mientras exista el contenedor.

información relacionada