モチベーション

Dockerのインターフェースに固定ipを振りたい

背景

現状,Dockerでコンテナを起動するとそれぞれのコンテナにeth0が追加される.その際に振られるipはDockerが勝手に割り振ってしまうためにコンテナに固定ipでアクセスしたいときは不便である.自分でbtctlをつかってブリッジや仮想インターフェースを作っても良いが,Pipeworkというツールを使うと簡単にDockerに固定をipを振れるようなので使ってみる.

環境

  • OS:Ubuntu 14.04

Pipeworkのインストール

Dockerがインストールされ,コンテナが既にあるubuntuマシンにて以下を実行

$ sudo -s
$ git clone https://github.com/jpetazzo/pipework.git
$ apt-get install -y bridge-utils
$ apt-get install -y arping

コンテナにNICを追加する

コンテナIDを調べ,NICを追加したいコンテナを起動し,NICを追加する.

$ docker ps -a
$ docker start 9bc312779a79  
$ ./pipework  br1 9bc312779a79  192.168.10.5/24 (コンテナに振りたいip)

この時br1という名前のブリッジが自動的に生成されるが,br1のipは自分で振る必要がある.

$ ip addr add 192.168.10.254/24 dev br1
$ ip addr show br1
22: br1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 3e:1c:29:d7:b7:04 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.254/24 scope global br1
       valid_lft forever preferred_lft forever
    inet6 fe80::e828:a5ff:fe57:2f79/64 scope link
       valid_lft forever preferred_lft forever

これでホストから192.168.10.5に対してpingが通るようになった.

Docker + Pipeworkの挙動メモ

これまでに生成されたインタフェースを見ると,

$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 06:09:72:64:53:b4 brd ff:ff:ff:ff:ff:ff
    inet 172.31.15.159/20 brd 172.31.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::409:72ff:fe64:53b4/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link
       valid_lft forever preferred_lft forever
22: br1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 3e:1c:29:d7:b7:04 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.254/24 scope global br1
       valid_lft forever preferred_lft forever
    inet6 fe80::e828:a5ff:fe57:2f79/64 scope link
       valid_lft forever preferred_lft forever
30: vethc78d: <BROADCAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast master docker0 state UP group default qlen 1000
    link/ether 02:53:af:6d:e5:91 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::53:afff:fe6d:e591/64 scope link
       valid_lft forever preferred_lft forever
32: veth1pl7845: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br1 state UP group default qlen 1000
    link/ether fa:22:e8:ae:a9:15 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::f822:e8ff:feae:a915/64 scope link
       valid_lft forever preferred_lft forever

vethXXXというのがDockerが自動で作成したブリッジdocker0に紐付いている仮想NICで, veth1plXXXというのがPipeworkが作成したブリッジに紐付いている仮想NIC(これがコンテナ内に生成されたNIC eth1と対になっているNIC)

$ brctl show
bridge name     bridge id               STP enabled     interfaces
br1             8000.3e1c29d7b704       no              veth1pl7845
                                                     
docker0         8000.56847afe9799       no              vethc78d

コンテナ内に入ってアドレスを調べるとちゃんと,Pipeworkで指定したアドレスがeth1に振られている.

$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 9001 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
39: eth0: <BROADCAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 4a:f7:d8:18:24:c4 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.14/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::48f7:d8ff:fe18:24c4/64 scope link
       valid_lft forever preferred_lft forever
41: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether ee:3c:8b:39:3f:c1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.5/24 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::ec3c:8bff:fe39:3fc1/64 scope link
       valid_lft forever preferred_lft forever

そして,コンテナを停止すると自動的に仮想NICは削除される.

$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 06:09:72:64:53:b4 brd ff:ff:ff:ff:ff:ff
    inet 172.31.15.159/20 brd 172.31.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::409:72ff:fe64:53b4/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 9001 qdisc noqueue state DOWN group defaul

$ brctl show
bridge name     bridge id               STP enabled     interfaces
br1             8000.000000000000       no
docker0         8000.56847afe9799       no

Dockerでサーバを運用する際にうっかりコンテナを停止してしまった時はNICが消えるので注意.このへんの処理は自動化しといたほうがいいかな.

参考