概要
勉強がてら docker のネットワーク機能について基本な操作を行ってみました
既存のネットワークの挙動の確認と独自のネットワークを定義してアタッチするところまで行っています
環境
- Mac OS X 10.12.3
- Docker on Mac 17.03.0-ce, build 60ccb22
ネットワークを確認する
まずはデフォルトで用意されているネットワークを確認してみましょう
NETWORK ID NAME DRIVER SCOPE
fb949b0d7786 bridge bridge local
365cbf8a882f host host local
64103726a5d5 none null local
こんな感じで 3 つのネットワークが用意されています
docker run をするときに --net
オプションがありこれを使うことでコンテナが所属するネットワークを指定することができます
特に指定しない場合は bridge が選択されるようです
では、この 3 つのネットワークの挙動を確認していきます
ネットワークを指定してコンテナを作成する
bridge
まずは bridge を指定します
docker run --rm -p 8080:80 --net bridge --name web1 nginx
これで作成した場合バインドしたポートで Mac (ホストマシン (192.168.100.105)) からコンテナへの通信ができ、moby VM からブリッジネットワークを使ってのコンテナへの通信もできます
また、コンテナからホストマシンへの通信もできます
更に NAT でインターネットに接続することもできます
- ホストマシンから
- moby から
- コンテナから
- ping 172.17.0.1
- ping 192.168.100.105
- apt update
注意点として今回 Docker on Mac でやっているのでホストマシンからコンテナへの ping に関しては moby VM にログインしてから試してください
moby へのログインは以下でできます
screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
host
次に host を試します
--net
オプションの部分を host に変更します
docker run --rm -p 8080:80 --net host --name web1 nginx
これで作成した場合、コンテナはホストマシンと同じネットワークインタフェースを使用します
なので、moby VM からコンテナへの通信とコンテナからホストマシンへの通信、NAT でのインターネットに接続はできます
- moby から
- コンテナから
- ping 172.17.0.1
- ping 192.168.100.105
- apt update
null
次に null を試します
--net
オプションの部分を none に変更します
null ドライバで作成しれたネットワークの none を指定しています
docker run --rm -p 8080:80 --net none --name web1 nginx
この場合、どこからもコンテナにアクセスできなくなります
また、コンテナからホストやインターネットへの通信できなくなります
コンテナに exec して確認してみるとわかりますが、通信するための IP アドレスが何も振られていないことがわかると思います
ネットワークを定義する
デフォルトの 3 つのネットワークの挙動はつかめてので次に独自のネットワークを作成してみます
今回は bridge ドライバを使って定義します
- docker network create my_network
で作成できます
確認するとネットワークが増えていることが確認できます
NETWORK ID NAME DRIVER SCOPE
526531de15db bridge bridge local
365cbf8a882f host host local
4aa22f6b0e5c my_network bridge local
64103726a5d5 none null local
詳細を確認するには inspect を使います
- docker network inspect my_network
[
{
"Name": "my_network",
"Id": "4aa22f6b0e5c3759d80bd717410c9aef70e50a853c4076e9bf972f5ba5132f3a",
"Created": "2017-03-16T23:51:03.617896532Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
Subnet や Gateway はデフォルトで設定されました
既存の bridge ネットワークと比較すると Options が空なだけで後は同じ感じでした
定義したネットワークに接続する
では、定義したネットワークをコンテナに接続してみます
初めに説明すると host と none に対しては接続できませんでした
Error response from daemon: Container sharing network namespace with another container or host cannot be connected to any other network
Error response from daemon: Container cannot be connected to multiple networks with one of the networks in private (none) mode
なので、bridge に接続しているコンテナに対して my_network を接続してみます
docker run --rm -p 8080:80 --net bridge --name web1 nginx
- docker network connect my_network web1
という感じです
insepct で my_network の情報を確認すると Containers の項目が増えていることがわかると思います (以下 inspect 結果の一部抜粋)
"Containers": {
"cca88927fa6e267e8e552c8a446b5363a29f60f04b2bf534e4cf3cc43fed4047": {
"Name": "web1",
"EndpointID": "2bda4228d7930af5ca558aae0e32be545f63018ada5718d80b3daa86bd524fc7",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
また、172.18 帯でも通信できることが確認できると思います
念のためもう一つ my_network に接続しているコンテナを作成してみましょう
- docker run –rm -p 8081:80 –net my_network –name web2 nginx
で web2 に exec してリーチャビリティを確認すると 172.18 では web1 にアクセスできるが、172.17 ではアクセスできないことが確認できると思います
- docker exec -it web2 /bin/bash
root@815fc91e6040:/
PING 172.18.0.2 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.143 ms
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.143/0.143/0.143/0.000 ms
root@815fc91e6040:/
PING 172.17.0.2 (172.17.0.2): 56 data bytes
2 packets transmitted, 0 packets received, 100% packet loss
その他のネットワークドライバ
今回は bridge, host, null という 3 種類のドライバを試しましたが、Docker on Mac では別のドライバも用意されています
docker info | grep -A 2 Plugins:
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
ipvlan, macvlan, overlay というのが他にもあるようです
また、ドライバは自分で定義することもできます
この辺りはまた別途検証して紹介できればと思います
最後に
Docker on Mac でネットワーク機能を試してみました
Mac の場合ちょっと特殊な VM が動作しているので少しややこしくなりましたが概念的には他のマシンで試しても同じだと思います
基本は bridge になるかと思います
あとは swarm などを使った場合にホストをまたがってコンテナ同士を通信させるのに overlay を使う感じかなと思います
それ以外のドライバも試してみたいな思っています
参考サイト