如何停用 Docker 的自動 IP 位址分配?

如何停用 Docker 的自動 IP 位址分配?

我想透過在我的網路上指派靜態 IP 位址來將 Docker 容器配置為看起來和感覺起來像一個真實的系統。

目前我在主機上有一個網橋設定(br0)。我已經DOCKER_OPTS="-b=br0"在文件中配置了 /etc/default/docker。我可以透過/etc/network/interface文件為每個容器分配靜態位址。

問題是 Docker 將繼續自行分配 IP 位址。 (如何阻止這個?)更麻煩的是它現在將使用橋接網路的 IP 方案。這將導致網路問題,因為它可以/將分配網路上已使用的位址。

問題:
網路掛起/暫停
ping 容器時的回應位址可能會變更。

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 也為容器指派一個與我的網路位於同一子網路上的位址。起初我以為這只是在/etc/hosts容器的文件中添加一行。它確實如此,但即使刪除它後仍然會出現問題。

例子:

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)

如果沒有透過命令列(-h)分配主機名稱來啟動容器,它將使用隨機分配的主機名

環境:

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

硬體:

IBM Power 8, 8247-22L
CPUs: 192
Memory: 512GB

容器:

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

網路:

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)

答案1

前段時間我也嘗試解決這個問題。我找不到一種方法來改變 docker 關於其 IP 分配的行為,而不禁用整個網路功能 ( --net=none)。因此,我將一個迄今為止未使用的子網分配給docker網橋接口,並讓docker來完成分配。我還編寫了一個守護進程,用於偵聽某些 docker API 事件,然後將動態更新推送到我們的 DNS 伺服器,因此我不必關心 IP,並且可以按名稱尋址容器。

這是 DNS 守護程式的 github 儲存庫。 https://github.com/cschritt/docker-dns-daemon 我將很快推出我的最新更改和一些重構。

答案2

不幸的是,似乎沒有辦法阻止 Docker 在橋接模式下為容器分配 IP 位址。作為解決方法,我新增了pre-up ip addr flush dev eth0以下內容/etc/network/interface以將 Docker 的 IP 位址忽略為此處描述。以下是如何完成此操作的範例:

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

這種方法的警告是當 Docker 將其自己的不正確/覆蓋的 IP 位址注入到容器的/etc/hosts檔案中時,使用多個容器。我發現解決此問題的唯一方法是安裝inotify-tools軟體包並運行以下腳本,以便/etc/hosts在 Docker 更改後立即恢復到其預定義狀態:

#!/bin/sh

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

上面的腳本要求您將有效/etc/hosts.orig文件新增到容器中。

答案3

從 Docker 1.10 開始,預計在未來幾天內發布,您可以在啟動容器時明確指定靜態 IP 位址,使用--ip=--ip6=選項分別指定 IPv4 和 IPv6 位址。它們可以與docker runand一起使用,docker network connect並且只要容器存在就持續存在。

相關內容