Docker Network とは何ぞ？

ずっとDockerを使っていますが、あまりDockerNetworkを意識することが今までなく、役割とかいまいちよくわかっていないので、調査して、自分用のメモを残します。

ドキュメントは[ここ](http://docs.docker.jp/engine/userguide/networking/index.html)を読みました。

## Docker Networkとは
Dockerのネットワークを管理するものです。
Dockerをインストールすると、自動的に３つのネットワークを作成します。
確認するコマンドは

```
$ docker network ls

NETWORK ID          NAME                DRIVER
7fca4eb8c647        bridge              bridge
9f904ee27bf5        none                null
cf03ee007fb4        host                host
```

確かに設定してあります。


## bridgeネットワーク
ホスト側には、docker0 というブリッジができています。これがbridgeネットワークと繋がっています。
名前からして、ブリッジ接続でホストのネットワークと繋がっていると思われます。
確認は下記のコマンド

```
$ ifconfig

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:dc:ab:d1:d4  txqueuelen 0  (イーサネット)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

コンテナに接続するネットワークは --netのオプションで設定できます。
例えば、

```
$ docker run -d --name container1 --net bridge busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"
```

ような感じです。
何も指定しない場合、デフォルトのネットワーク bridgeが選択されます。

デフォルトのネットワークはbridgeですが、他のものはどういうものなのか。

## noneネットワーク
noneを指定するとネットワーク・インターフェースが欠如した状態でコンテナを作れます。

例えば、

```
$ docker run -d --name container2 --net none busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"
```

でコンテナを作る。
確認は下記のコマンド

```
$ docker exec container2 cat /etc/hosts

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

$ docker exec container2 ifconfig

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          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:1 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

```

ループバックインターフェースしかないですね。

ちなみにbridgeネットワークで作った場合は、

```
$ docker exec container1 cat /etc/hosts

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.17.0.2	ba703c0e2904

$ docker exec container1 ifconfig

eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:76 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:11028 (10.7 KiB)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          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:1 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
```

eth0のネットワークインターフェースがありますね。

## hostネットワーク
hostネットワークは名前の通り、ホスト側のネットワーク・スタックにコンテナを接続しており、
コンテナ内のネットワーク設定が、ホスト上と同じに見えます。

```
$ docker run -d --name container3 --net host busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"

$ docker exec container3 cat /etc/hosts

127.0.0.1	localhost
127.0.1.1	--
127.0.2.1	--

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

$ docker exec container3 ifconfig
※ホストでifconfigを使った時と同じ出力

```

これは結構便利ですね。

## ブリッジ・ネットワークの詳細
下記のコマンドで詳細を見ることができます。

```
$ docker network inspect bridge

[
    {
        "Name": "bridge",
        "Id": "e37815cd479e4272ea69f16c54b55fdf41ecb35151c1421a3b4bd2c16a46c34f",
        "Created": "2020-05-17T17:11:01.385296653+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "ba703c0e2904404891295f707c3b323a48ee01631e8082948038478c3fe89990": {
                "Name": "container1",
                "EndpointID": "51244eaedf829aea7887272f28bf7aeb61573b14894d304c7af215c0dbb4c13f",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

```

自動的にサブネットやゲートウェイが作られていて、それを見ることができます。
接続しているコンテナの情報も見れます。

bridgeネットワークのコンテナにpingで接続確認をします。

```
$ docker exec container1 ping -w3 172.17.0.2docker exec container1 ping -w3 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.042 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.045 ms
64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.122 ms

--- 172.17.0.2 ping statistics ---
4 packets transmitted, 3 packets received, 25% packet loss
round-trip min/avg/max = 0.042/0.069/0.122 ms
```

コンテナ→ホストは繋がっていることがわかりますね。


## カスタムネットワークを作る
下記のコマンドでユーザ独自のネットワークを作れます。

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

$docker network inspect new_nw
[
    {
        "Name": "new_nw",
        "Id": "129f288d936696f13caa17580e7c12f94d58e13d135e6eeb1662c1cdb85e0c73",
        "Created": "2020-05-24T18:19:00.890438557+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

```

この新規に作ったネットワークはbridgeのネットワークとは、独立しているので、
このネットワークにつなぐコンテナは、他のコンテナと独立することができます。
逆に、同じネットワークにすれば、他のコンテナと連携ができます。非常に便利ですね。


## オーバレイ・ネットワーク
まず、オーバーレイネットワークという用語を聞いたことなかったので、確認。
「オーバーレイネットワークとはあるネットワークの上に構築された別のネットワークのこと」ということを指す模様
インターネットVPNやP2Pネットワークもオーバーレイネットワークのようで、SDNの一方式として使われるようです。

Dockerを使ったオーバーレイネットワークですが、ドキュメントを見ると、どうやら※VXLANをDockerNetworkで作れるようです。

※VXLANは私自身は情報処理試験で知識としてしかわかってなく、異なるネットワークを、仮想的に同一のネットワークとして通信ができるものくらいの理解です。

ここは[他者様のサイト](https://qiita.com/TsutomuNakamura/items/ed046ee21caca4a2ffd9#overlay-network)を参考
これにより、異なるネットワークのコンテナ同士で、通信ができるようになります。

## カスタム・ネットワーク・プラグイン
必要があれば、自分自身でネットワーク・ドライバ・プラグインを書けます。
書き方は、[ここ](http://docs.docker.jp/engine/extend/plugins.html)と[ここ](https://docs.docker.com/engine/extend/plugin_api/)

作成したネットワークを元に、派生してネットワークを作ります。

```
$ docker network create --driver weave mynet
```
　


## 参考
[おうちで学べるネットワークのきほん](https://www.amazon.co.jp/dp/B00EDF73ZS/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
　わかりやすい

[ブリッジ接続](https://wa3.i-3-i.info/word12032.html)
　このサイトもすき

[Docker_VXLAN](https://qiita.com/TsutomuNakamura/items/ed046ee21caca4a2ffd9#overlay-network)
　図がわかりやすい

[VXLAN詳細](https://www.infraexpert.com/study/virtual3.html)

ネットワークの復習もできて、ちょっと調べて得しました。