メモ：Dockerのネットワーク（ブリッジネットワーク）


# 概要
* Dockerのネットワークまわりについて調べる
* Dockerのブリッジネットワークでどのように通信が行われるのか調べる
* リンク機能については触れない

# Dockerコンテナ・ネットワーク

まず、Dockerをインストールすると、デフォルトで３つのネットワークが作成され（ここでいう「ネットワーク」は、Docker内部の概念）、`docker run`したときのデフォルトは、docker0というブリッジネットワークが使われる。

```
# デフォルトで作成される３つのネットワーク
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
d4d0e07e3979        bridge              bridge              local
ba38d64470bd        host                host                local
d1f35877f0fd        none                null                local
```

```
# ネットワークの詳細を確認
$ docker network inspect bridge
…出力は省略
```


docker0はifconfigで確認ができる。

```
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:82ff:feeb:c7b5  prefixlen 64  scopeid 0x20<link>
        ether 02:42:82:eb:c7:b5  txqueuelen 0  (イーサネット)
        RX packets 7519  bytes 409824 (409.8 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 16155  bytes 18364515 (18.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

同じブリッジネットワークに属するコンテナ同士はそれぞれ通信可能なため、セキュリティ的に問題がある場合は新しくネットワークを作成し、所属するネットワークを分ける。

このブリッジはbrctlコマンドでも確認が可能であり、Linuxの標準機能で実現されていることがわかる。

```
$ brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.024282ebc7b5	no	
```

起動したコンテナがこのネットワークに属していることを確認するには、`docker network inspect bridge`もしくは`brctl show`を実行する。

# コンテナ起動時に作成されるリソース、設定
## 構成
コンテナを起動すると下記のようなネットワーク構成が作られる。コンテナと外部の通信はvethによって実現され、仮想ブリッジから外へはiptablesの力を借りる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/115524/7df60793-a95b-fc14-484d-bfae036bb166.png)

引用元：https://www.kaitoy.xyz/2015/07/25/how-to-capture-packets-on-a-local-network-with-pcap4j-container/

## veth
Linuxが提供する機能。コンテナごとに仮想NICのペアを作成し、一つはコンテナ内部に入れ（LinuxのNetwork namespaceを使う）、もう一つは仮想ブリッジと接続する。

コンテナ内部の仮想NICはeth0として作成され、ブリッジと同じサブネットのIPアドレスが自動的に割り振られる。仮想ブリッジと接続される仮想NICは、ホストOSからifconfigにより確認できる。

```
veth6f26945: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::fc41:30ff:fe01:3c56  prefixlen 64  scopeid 0x20<link>
        ether fe:41:30:01:3c:56  txqueuelen 0  (イーサネット)
        RX packets 6  bytes 516 (516.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 31  bytes 3191 (3.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

## iptables
外部ネットワークとコンテナとの通信は、iptablesによりIPマスカレードにより実現する。

dockerにより追加された設定を確認する。`iptables-save`で見てもいいが、ここでは`iptables -L`で見ている。

### natテーブル
「MASQUERADE」の行がポイント。

```
# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0     
```

### filterテーブル
特に面白い設定はないが、filterテーブルにも設定は入る。

```
# iptables -t filter -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-ISOLATION  all  --  0.0.0.0/0            0.0.0.0/0           
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (1 references)
target     prot opt source               destination         

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0  
```

### ブリッジネットワーク追加時
次のようにブリッジネットワークを追加可能。

```
$ docker network create --driver bridge my_bridge_nw
```

このときiptablesの設定も追加される。


# 参考

* Docker コンテナ・ネットワークの理解
  * http://docs.docker.jp/engine/userguide/networking/dockernetworks.html
* Dockerを支える技術
  * https://www.slideshare.net/enakai/docker-34668707
* LXCで学ぶコンテナ入門 －軽量仮想化環境を実現する技術、第6回　Linuxカーネルのコンテナ機能［5］ ─ネットワーク

  * http://gihyo.jp/admin/serial/01/linux_containers/0006