Como posso desabilitar a atribuição automática de endereço IP do Docker?

Como posso desabilitar a atribuição automática de endereço IP do Docker?

Gostaria de configurar os contêineres do Docker para parecerem um sistema real, atribuindo-lhes endereços IP estáticos em minha rede.

Atualmente tenho uma configuração de ponte de rede (br0) no host. Eu DOCKER_OPTS="-b=br0"configurei no /etc/default/dockerarquivo. Consigo atribuir endereços estáticos a cada um dos contêineres por meio de seus /etc/network/interfacearquivos.

O problema é que o Docker continuará atribuindo endereços IP por conta própria. (Como faço para parar isso?) Ainda mais preocupante é que agora ele usará o esquema IP da rede em ponte. O que causará problemas de rede, pois pode atribuir endereços que já estão em uso na rede.

Problemas:
Suspensão/pausa da rede
O endereço de resposta durante o ping do contêiner pode mudar.

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

O Docker também atribui ao contêiner um endereço na mesma sub-rede da minha rede. No começo pensei que fosse simplesmente adicionar uma linha ao /etc/hostsarquivo do contêiner. O que acontece, mas mesmo depois de removê-lo, os problemas ainda são vistos.

Exemplo:

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)

Se nenhum nome de host for atribuído por meio da linha de comando (-h) para iniciar o contêiner, ele usará o nome de host atribuído 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

Containers:

OS: Ubuntu 14.04.2 
Arch: PPC64LE
Kernel: 3.16.0-30

Rede:

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)

Responder1

Eu também tentei resolver esse problema há algum tempo. Não consegui encontrar uma maneira de alterar o comportamento do docker em relação às atribuições de IP sem desabilitar toda a funcionalidade de rede ( --net=none). Portanto, atribuí uma sub-rede até então não utilizada à interface do docker bridge e deixei o docker fazer a atribuição. Também escrevi um daemon que escuta determinados eventos da API do docker e, em seguida, envia atualizações dinâmicas para nosso servidor DNS, para que não precise me preocupar com os IPs e possa endereçar os contêineres pelo nome.

Aqui está o repositório do github para o daemon DNS. https://github.com/cschritt/docker-dns-daemon Em breve, enviarei minhas últimas alterações e algumas refatorações.

Responder2

Infelizmente, parece que não há como impedir que o Docker atribua endereços IP a contêineres no modo bridge. Como solução alternativa, adicionei pre-up ip addr flush dev eth0para /etc/network/interfacedescartar o endereço IP do Docker comodescrito aqui. Aqui está um exemplo de como isso pode ser feito:

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

A ressalva dessa abordagem ocorre com vários contêineres, quando o Docker injeta seus próprios endereços IP incorretos/substituídos nos /etc/hostsarquivos dos contêineres. A única maneira que encontrei de corrigir isso é instalar inotify-toolso pacote e executar o seguinte script para reverter /etc/hostsao seu estado predefinido assim que o Docker o alterar:

#!/bin/sh

while /usr/bin/inotifywait -e close /etc/hosts; do
  cp -v /etc/hosts.orig /etc/hosts
done

O script acima requer que você adicione /etc/hosts.origum arquivo válido ao contêiner.

Responder3

Começando com Docker 1.10, previsto para ser lançado nos próximos dias, você pode especificar explicitamente um endereço IP estático ao iniciar seu contêiner, com as opções --ip=e --ip6=, para especificar endereços IPv4 e IPv6, respectivamente. Eles podem ser usados docker run​​e docker network connectpersistirem enquanto o contêiner existir.

informação relacionada