Dockerのネットワークをbridgeで外と繋げる

Dockerの1.10ではネットワークの機能にも大きな改善があったようで、Dockerコンテナのネットワークを`bridge`で外と繋げることが簡単にできるようになっています。

参考に、下記のような構成を例にしてやり方を説明します。

| Host     | IP Address    |
|----------|---------------|
| MacBook  | 192.168.33.1  |
| host1(VirtualBox)  | 192.168.33.10  |
| container1  | 192.168.33.11  |
| container2  | 192.168.33.12  |
| container3  | 192.168.33.13  |

## `Vagrantfile`を準備する

VirtualBox上にテスト用のVM(`host1`)を作ろうと思うのですが、`bridge`が使えるようにするにはネットワークアダプターの選択肢をデフォルトから変更する必要があります。

`Vagrantfile`は下記のようになります。

```rb

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.hostname = "host1"
  config.vm.network "private_network", ip: "192.168.33.10"

  config.vm.provider "virtualbox" do |v|
    v.memory = "2048"
    # ネットワークアダプタに変更を加える
    v.customize ['modifyvm', :id, '--nictype1', 'Am79C973']
    v.customize ['modifyvm', :id, '--nicpromisc1', 'allow-all']
    v.customize ['modifyvm', :id, '--nictype2', 'Am79C973']
    v.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all']
  end

  # bridge-utilsをインストールする
  config.vm.provision "shell", inline: <<-SHELL
    apt-get update
    apt-get -y install bridge-utils
  SHELL
end
```

## Dockerマシンを作る

```bash
# VMを立ち上げます
$ vagrant up

# VMをDockerマシンにします
$ docker-machine create \
      --driver "generic" \
      --generic-ip-address 192.168.33.10 \
      --generic-ssh-user vagrant \
      --generic-ssh-key .vagrant/machines/default/virtualbox/private_key \
      --generic-ssh-port 22 \
      host1
```

## ブリッジ`docker1`とネットワーク`shared_nw`を作る

```bash
# VMにログインします
$ vagrant ssh

# eth1のIPアドレスを削除します
$ sudo ip addr del 192.168.33.10/24 dev eth1

# "shared_nw"と"docker1"を作ってサブネットとゲートウェイを
# 設定します
$ sudo docker network create \
    --driver bridge \
    --subnet=192.168.33.0/24 \
    --gateway=192.168.33.10 \
    --opt "com.docker.network.bridge.name"="docker1" \
    shared_nw

# docker1をeth1に接続します
$ sudo brctl addif docker1 eth1
```

> **Note:** 本当はhost1にログインする際に`docker-machine ssh host1`を使いたいところですが、`eth1`から192.168.33.10を一旦削除するので、接続が切れてしまわないように`eth0`経由でログインする`vagrant ssh`を使っています。

## コンテナを作る

VMからログアウトしてMacBookに戻ります。それからDockerマシンの環境を設定して、`shared_nw`上に固定IPでコンテナを作ります。

```bash
$ eval $(docker-machine env host1) 
$ docker run --name container1 --net shared_nw --ip 192.168.33.11 -dt ubuntu
$ docker run --name container2 --net shared_nw --ip 192.168.33.12 -dt ubuntu
$ docker run --name container3 --net shared_nw --ip 192.168.33.13 -dt ubuntu
```

設定がうまく行っていれば、MacBookからコンテナへ直接`ping`が通ります。

```bash
$ ping -c 3 192.168.33.11
$ ping -c 3 192.168.33.12
$ ping -c 3 192.168.33.13
```

固定IPが設定できるという点も嬉しいですね。

## 後片付け

テストが終わって要らなくなったDockerマシンは下記の手順で削除することができます。

```bash
$ docker rm -f $(docker ps -aq) 
$ docker-machine rm host1 
$ vagrant destroy 
```

## 参考になったリンク

* [Docker - Network Configuration](https://docs.docker.com/v1.5/articles/networking/)
* [Docker - network create](https://docs.docker.com/engine/reference/commandline/network_create/)
* [Odd Bits - Four ways to connect a docker container to a local network](http://blog.oddbit.com/2014/08/11/four-ways-to-connect-a-docker/)
* [Github - jpetazzo/pipework](https://github.com/jpetazzo/pipework)
* [Stack Overflow - Assign static IP to Docker container](http://stackoverflow.com/questions/27937185/assign-static-ip-to-docker-container)