ずっとDockerを使っていますが、あまりDockerNetworkを意識することが今までなく、役割とかいまいちよくわかっていないので、調査して、自分用のメモを残します。
ドキュメントはここを読みました。
Docker Networkとは
Dockerのネットワークを管理するものです。
Dockerをインストールすると、自動的に3つのネットワークを作成します。
確認するコマンドは
$ 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は私自身は情報処理試験で知識としてしかわかってなく、異なるネットワークを、仮想的に同一のネットワークとして通信ができるものくらいの理解です。
ここは他者様のサイトを参考
これにより、異なるネットワークのコンテナ同士で、通信ができるようになります。
カスタム・ネットワーク・プラグイン
必要があれば、自分自身でネットワーク・ドライバ・プラグインを書けます。
書き方は、こことここ
作成したネットワークを元に、派生してネットワークを作ります。
$ docker network create --driver weave mynet
参考
おうちで学べるネットワークのきほん
わかりやすい
ブリッジ接続
このサイトもすき
Docker_VXLAN
図がわかりやすい
ネットワークの復習もできて、ちょっと調べて得しました。