[翻訳] Work with network commands

[Work with network commands](https://docs.docker.com/engine/userguide/networking/work-with-networks/)の翻訳です。
(disconnect / remove はさほどではなかったので省略しています)

## Work with network commands
本稿は Docker とやり取りをして network や container を操作する network サブコマンドの例を示します。
コマンドは Docker Engine CLI で利用可能です。

* `docker network create`
* `docker network connect`
* `docker network ls`
* `docker network rm`
* `docker network disconnect`
* `docker network inspect`

やりたいことが明確で無いのであれば、本セクションの例を試す前に [Understanding Docker network](https://docs.docker.com/engine/userguide/networking/dockernetworks/) を読むのがおすすめです。
`bridge` ネットワークに関しての例で、すぐに試すことができます。
`overlay` ネットワークの実験をしてみたいのであれば、 [Getting started with multi-host networks](https://docs.docker.com/engine/userguide/networking/get-started-overlay/) を読んでみてください。

## Create networks

Docker Engine は Engine がインストールされた時に自動的に1つ `bridge` ネットワークを作成します。
このネットワークは 過去 `docker0` として利用してきたネットワークに対応します。
このネットワークに加えて、あなた自身の `bridge` または `overlay` ネットワークを作成位することができます。

`bridge` ネットワークは、稼働している Docker Engine のインスタンスの1つに1つ存在しています。
`overlay` ネットワークは複数のホストに渡り、それぞれの Engine で稼働します。
もし、 `docker network create` を実行し、ネットワーク名を与えれば、あなたのための bridge network を作成することができます。

```
$ docker network create simple-network
de792b8258895cf5dc3b43835e9d61a9803500b991654dacb1f4f0546b1c88f8
$ docker network inspect simple-network
[
    {
        "Name": "simple-network",
        "Id": "de792b8258895cf5dc3b43835e9d61a9803500b991654dacb1f4f0546b1c88f8",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {}
            ]
        },
        "Containers": {},
        "Options": {}
    }
]
```

`bridge` ネットワークではなく、 `overlay` ネットワークは作成前にいくつかの事前条件が必要になります。

* key-value ストアにアクセスできること. Engine は Consul 、 Etcd および ZooKeeper (Distributed store) をサポートしています
* ホストのクラスタが key-value ストアに接続されていること
* 適切に設定された `daemon` Engine が swarm のホストに存在していること

`docker daemon` のオプションは `overlay` ネットワークをサポートしています。

* `--cluster-store`
* `--cluster-store-opt`
* `--cluster-advertise`

特に要件がなければ、 Docker Swarm をインストールして、クラスタを管理するのがおすすめです。
 Swarm は洗練されたディスカバリとサーバ管理を提供しています。

ネットワークを作成するときに、 Engine はオーバラップされていない subnetwork をデフォルトでネットワークに対して作成します。
このデフォルトを上書きし、`--subnet` を利用することで直接にサブネットワー指定することができます。
`bridge` ネットワークの場合は、たった一つのサブネットだけが作成可能です。
`overlay` ネットワークは複数の subnet をサポートしています。

`--subnetwork` オプションに加え、 `--gateway`、 `--ip-range`、 `--aux-address` オプションを指定することができます。

```
$ docker network create -d overlay
  --subnet=192.168.0.0/16 --subnet=192.170.0.0/16
  --gateway=192.168.0.100 --gateway=192.170.0.100
  --ip-range=192.168.1.0/24
  --aux-address a=192.168.1.5 --aux-address b=192.168.1.6
  --aux-address a=192.170.1.5 --aux-address b=192.170.1.6
  my-multihost-network
```

サブネットワークがオーバラップされないことを確認してください。その場合は、ネットワークは作成に失敗し、 Engine はエラーを返します。

## Connect containers

コンテナを動的に1つまたはそれ以上のネットワークに属させることができます。これらのネットワークは同一でも異なっているネットワークドライバでも構いません。
一旦属させてしまえば、コンテナはその他のコンテナ IP アドレスまたは名前を利用してコミュニケーションすることができるようになります。

`overlay` ネットワークまたはマルチホストをサポートするカスタムプラグインであったとしても、同一のマルチホストネットワークに属しているコンテナはたとえ異なるホストで立ち上げられたとしても、コミュニケーションすることができます。

2つのコンテナを作ってみます。

```
$ docker run -itd --name=container1 busybox
18c062ef45ac0c026ee48a83afa39d25635ee5f02b58de4abc8f467bcaa28731

$ docker run -itd --name=container2 busybox
498eaaaf328e1018042c04b2de04036fc04719a6e39a097a4f4866043a2c2152
```

それから、独立した `bridge` ネットワークをテスト用に作ってみます

```
$ docker network create -d bridge isolated_nw
f836c8deb6282ee614eade9d2f42d590e603d0b1efa0d99bd88b88c503e6ba7a
```

`container2` をこのネットワークに所属させ、その後 `inspect` でこのネットワークのコネクションを確認します。

```
$ docker network connect isolated_nw container2
$ docker network inspect isolated_nw
[[
    {
        "Name": "isolated_nw",
        "Id": "f836c8deb6282ee614eade9d2f42d590e603d0b1efa0d99bd88b88c503e6ba7a",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {}
            ]
        },
        "Containers": {
            "498eaaaf328e1018042c04b2de04036fc04719a6e39a097a4f4866043a2c2152": {
                "EndpointID": "0e24479cfaafb029104999b4e120858a07b19b1b6d956ae56811033e45d68ad9",
                "MacAddress": "02:42:ac:15:00:02",
                "IPv4Address": "172.21.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {}
    }
]
```

Engine が自動的に IP アドレスが `container2` に振っていることが確認できるはずです。
もし、ネットワーク作成時に `--subnetwork` を指定しているならば、ネットワークがそのアドレスを使っているはずです。
さて、３つ目のコンテナを立ち上げ、ネットワークに属させてみましょう。 `docker run` の時に `--net` コマンドを使って、起動時に。

```
$ docker run --net=isolated_nw -itd --name=container3 busybox
c282ca437ee7e926a7303a64fc04109740208d2c20e442366139322211a6481c
```

`container3` のネットワークリソースを(`inspect` で)見てみましょう

```
$ docker inspect --format='{{json .NetworkSettings.Networks}}'  container3
{"isolated_nw":{"EndpointID":"e5d077f9712a69c6929fdd890df5e7c1c649771a50df5b422f7e68f0ae61e847","Gateway":"172.21.0.1","IPAddress":"172.21.0.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:15:00:03"}}
```

このコマンドを `container2` に対して繰り返してみてください。 Python がインストールされているのであれば、整形してみることができます(※訳注: jq使えばいいです)

```
$ docker inspect --format='{{json .NetworkSettings.Networks}}'  container2 | python -m json.tool
{
    "bridge": {
        "EndpointID": "281b5ead415cf48a6a84fd1a6504342c76e9091fe09b4fdbcc4a01c30b0d3c5b",
        "Gateway": "172.17.0.1",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "IPAddress": "172.17.0.3",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "MacAddress": "02:42:ac:11:00:03"
    },
    "isolated_nw": {
        "EndpointID": "0e24479cfaafb029104999b4e120858a07b19b1b6d956ae56811033e45d68ad9",
        "Gateway": "172.21.0.1",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "IPAddress": "172.21.0.2",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "MacAddress": "02:42:ac:15:00:02"
    }
}
```

`container2` が2つのネットワークに属していることが見て取れるはずです。起動した時にデフォルトで所属していた `bridge` ネットワークとその後、結びつけた `isolated_nw` です。

![](https://docs.docker.com/engine/userguide/networking/images/working.png)!

`container3` の場合には、`docker run` を通して結びつけた `isolated_nw` だけで、 `bridge` には結び付けられていません。

`docker attach` コマンドを利用して、稼働中の `container2` に接続し、ネットワークスタックを調べてみましょう。

```
$ docker attach container2
```

コンテナのネットワークスタックを見てみると、 Ethernet interface が2つあるはずです。1つはデフォルトのbridgeネッワーク、もう一つは `isolated_nw` ネットワークです。

```
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03  
          inet addr:172.17.0.3  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)

eth1      Link encap:Ethernet  HWaddr 02:42:AC:15:00:02  
          inet addr:172.21.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe15:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)

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)
```

`/etc/hosts` も表示してみます。

```
/ # cat /etc/hosts
172.17.0.3	498eaaaf328e
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
172.21.0.3	container3
172.21.0.3	container3.isolated_nw
```

ユーザが定義した `isolated_nw` 上で、 Docker network の機能により `/etc/hosts` が適切に名前解決ができるように更新されています。
`container2` の中から、 ping `container3` を名前で実行することが可能です。

```
/ # ping -w 4 container3
PING container3 (172.21.0.3): 56 data bytes
64 bytes from 172.21.0.3: seq=0 ttl=64 time=0.070 ms
64 bytes from 172.21.0.3: seq=1 ttl=64 time=0.080 ms
64 bytes from 172.21.0.3: seq=2 ttl=64 time=0.080 ms
64 bytes from 172.21.0.3: seq=3 ttl=64 time=0.097 ms

--- container3 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.070/0.081/0.097 ms
```

デフォルトの bridge ネットワークの場合はこうではありません。 `container2` と `container1` はデフォルトの bridge ネットワークに属しています。 Docker は自動的にサービスディスカバリをこのネットワークに対しては行えません。
このため、 `container1` への ping は `/etc/hosts` ファイルをベースにしてくれると期待して名前で行うと失敗します。

```
/ # ping -w 4 container1
ping: bad address 'container1'
A ping using the container1 IP address does succeed though:

/ # ping -w 4 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.095 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.075 ms
64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.072 ms
64 bytes from 172.17.0.2: seq=3 ttl=64 time=0.101 ms

--- 172.17.0.2 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.072/0.085/0.101 ms
```

もし、 `container1` を `container2` に結びつけたければ、 `docker run --link` コマンドで行い、2つのコンテナが IP と同じように名前で疎通できるようにする必要があります。

`CTRL-p CTRL-q` を利用して、稼働させたまま `container2` から切り離します。

この例では、 `container2` が両方のネットワークに結び付けられており、 `container1` および `container3` とコミュニケートしていました。
しかし、 `container3` と `container1` は同じネットワークには属しておらず、それゆえコミュニケーションができません。
では、 `container3` にアタッチし、 `container1` に IP アドレスで ping してみましょう。

```
$ docker attach container3
/ # ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
^C
--- 172.17.0.2 ping statistics ---
10 packets transmitted, 0 packets received, 100% packet loss
```

コンテナをネットワークに所属させるために、コンテナは稼働していなければなりません。
コンテナを止め、コンテナが所属しているネットワークを調べると、コンテナを発見できないでしょう。
`docker network inspect` コマンドは起動しているコンテナだけを表示するからです。