ネットワーク上で静的 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
コンテナのファイルに 1 行追加するだけだと思っていました。確かに追加されますが、削除した後でも問題は依然として見られます。
例:
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
私も以前、この問題を解決しようとしました。ネットワーク機能全体を無効にせずに、IP 割り当てに関する docker の動作を変更する方法を見つけることができませんでした ( --net=none
)。そこで、これまで使用されていないサブネットを docker ブリッジ インターフェイスに割り当て、docker に割り当てを行わせました。また、特定の docker API イベントをリッスンして、動的更新を DNS サーバーにプッシュするデーモンも作成したので、IP を気にする必要はなく、名前でコンテナーをアドレス指定できます。
DNS デーモンの github リポジトリはこちらです。 https://github.com/cschritt/docker-dns-daemon 最新の変更とリファクタリングをすぐにプッシュします。
答え2
残念ながら、DockerがブリッジモードのコンテナにIPアドレスを割り当てるのを防ぐ方法はないようです。回避策として、DockerのIPアドレスを無視するためにpre-up ip addr flush dev eth0
以下を追加します。/etc/network/interface
ここで説明以下にその実行例を示します。
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=
オプションを使用して、それぞれ IPv4 アドレスと IPv6 アドレスを明示的に静的 IP アドレスとして指定できます。これらはおよび--ip6=
とともに使用でき、コンテナーが存在する限り存続します。docker run
docker network connect