Dockerの内部ネットワークのプライベート・アドレス帯を変更する

タイトルの通り、Dockerコンテナに割り当てられるIPアドレスのアドレス帯を変更します。

# なぜ？

デフォルトでは `172.17.0.0/16` が使われていますが、何らかの理由でこれを変更したい場合があります。
私の場合は、このアドレス帯がDockerホスト自身が所属するネットワークのアドレス帯とかぶってしまったためでした。

# 環境

かなり古い環境を使っています。

- CentOS release 6.6 (Kernel 2.6.32)
- Docker version 1.7.1, build 786b29d/1.7.1

# 参考にした資料

Docker公式ドキュメントにも、変更の方法が記載されています。
[Customize the docker0 bridge](https://docs.docker.com/engine/userguide/networking/default_network/custom-docker0/)
※ 今回はこの手順だけではうまくいかなかったので、追加で行ったことも記載します。

# 手順
## /etc/sysconfig/dockerの変更
CentOS6.X なので、docker daemonの管理には、init/Upstart を使用しています。なので、docker daemon の起動設定を変更するには、`/etc/sysconfig/docker` を編集します。

```:/etc/sysconfig/docker
# /etc/sysconfig/docker
#
# Other arguments to pass to the docker daemon process
# These will be parsed by the sysv initscript and appended
# to the arguments list passed to docker -d

other_args="-H -H unix://var/run/docker.sock --bip=192.168.42.1/24 --fixed-cidr=192.168.42.128/25"
```

`--bip=192.168.42.1/24`が、コンテナが外部と通信する際に使用するBridgeのIPアドレス、`--fixed-cidr=192.168.42.128/25`が、コンテナに割り当てられるIPアドレス帯域を表します。

この状態で、Docker Daemonを起動します。

```
$ service docker start
Starting docker:	                                   [  OK  ]
$ service docker status
docker dead but subsys locked
```

Daemonの起動には成功しましたが、docker自体は立ち上がっていないようです。
ログを確認します。

```
$ tail -f /var/log/docker
time="2016-03-18T15:00:33.250445843+09:00" level=info msg="Listening for HTTP on tcp (0.0.0.0:2375)" 
time="2016-03-18T15:00:33.250788732+09:00" level=info msg="Listening for HTTP on unix (var/run/docker.sock)" 
time="2016-03-18T15:00:33.332532944+09:00" level=info msg="[graphdriver] using prior storage driver \"devicemapper\"" 
time="2016-03-18T15:00:33.348373321+09:00" level=warning msg="Running modprobe bridge nf_nat failed with message: , error: exit status 1" 
time="2016-03-18T15:00:33.426063401+09:00" level=fatal msg="Error starting daemon: Error initializing network controller: Error creating default \"bridge\" network: bridge IPv4 (172.17.42.1) does not match requested configuration 192.168.42.1" 
```

最終行 `Error creating default \"bridge\" network: bridge IPv4 (172.17.42.1) does not match requested configuration 192.168.42.1` より、`--bip=`に指定したアドレスが、既存の Bridge と一致しないためのエラーだとわかります。

## 既存 Bridge の削除
既存Bridge `docker0` の設定を確認します。

```
$ ifconfig docker0
docker0   Link encap:Ethernet  HWaddr 16:3A:1E:2C:59:C1  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::38e0:abff:fe46:b1b5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6366812 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9611054 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1827952253 (1.7 GiB)  TX bytes:36402367735 (33.9 GiB)
$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.172.0.0    *               255.255.0.0   U     0      0        0 docker0
```

`docker0`インターフェースのアドレスが、既定の`172.17.0.1` であることが確認できました。
※ route では、このインタフェースのGatewayを確認しています。以降の操作で route を直接変更することはありません。

Docker Daemon起動時に`docker0`インターフェースがない場合、`--bip=`に指定した値でインタフェースが再作成されます。
このため、既存の`docker0`インターフェースを削除しておきます。

```
$ ip link del docker0 
```

再度、Docker Daemon を立ち上げます。

```
$ service docker start
$ service docker status
docker (pid  5645) is running...
```

# 動作確認

コンテナのIPアドレスが変更されているか確認します。
適当なコンテナを起動し、`docker inspect <Container Id>` で、コンテナ情報を確認します。

```:抜粋
    "NetworkSettings": {
        "Bridge": "",
        "EndpointID": "b908c620b6db8c462a759b4d21d5b96b6a6440429f0240627559006b92633aee",
        "Gateway": "192.168.42.1",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "HairpinMode": false,
        "IPAddress": "192.168.42.129",
        "IPPrefixLen": 24,
        "IPv6Gateway": "",
        "LinkLocalIPv6Address": "",
        "LinkLocalIPv6PrefixLen": 0,
        "MacAddress": "02:42:c0:a8:2a:81",
        "NetworkID": "342c88fbf863a43bbcc27b08c90be82761744dfe307d04d6d53b82c27baa2c77",
```

`IPAddress`が `--fixed-cidr=`に指定した範囲内、`Gateway`が `--bip=`に指定したアドレスになっていることを確認できました。

以上で設定は終了です。