最近Dockerをプライベートで使う機会が多いのですが、なんとなくで使っている部分が多く時々困ります。その中でも特にネットワークに関してはもともと理解が浅いのかイマイチ理解できていません。ので、調査してみました。
Dockerのネットワークをについては以下の公式リファレンスに載っています。
ネットワークドライバ
Dockerのネットワークを調べると第一に出てくるのがネットワークドライバという言葉です。この言葉はどうやらDockerでネットワークを構成する方法を表しているみたいで、執筆時点では以下の4つのネットワークドライバがあります。
- bridge ... デフォルトのドライバ
- host ... ホストネットワークを直接使用するドライバ
- overlay ... Docker Swarm サービスが相互に接続できるドライバ
- macvlan ... コンテナにMACアドレスを割り当てるドライバ
- none ... ネットワークを無効にするドライバ
少し古いですが、上記の bridge、overlay、macvlanについて解説している公式ブログ記事がありました。参考として以下に乗せておきます。
今回は一番よく使われていると勝手に思っている bridge ネットワークドライバについて調べてみます。
そもそもブリッジとは?
まずは基本から行きます!そもそもブリッジとはそもそも何なのでしょうか?
安心・安全の「マスタリング TCP/IP 入門」で調べてみました。
ブリッジとはOSI参照モデルのデータリンク層でネットワークを接続する機械のことになります。
ただ、Dockerでいうブリッジとは上記の図のような異なるネットワークを接続させるのではなく、下の図のように複数のホストを接続させる目的で使用されるブリッジのことかと思います。このような機械はスイッチと言われます。
Docker の bridge とは?
公式サイトでは以下のページに詳しく書いてあります。
以下の文章でDockerにおけるbridgeネットワークとは何かを説明しているようです。
In terms of Docker, a bridge network uses a software bridge which allows containers connected to the same bridge network to communicate, while providing isolation from containers which are not connected to that bridge network.
Dockerにおけるbridgeネットワークとは、ソフトウェアによって構築されたブリッジのことで同じブリッジに接続されているコンテナ間を通信可能にするものということになります。なので異なるブリッジに接続されているコンテナは通信することができないということになりますね。
イメージとしては以下のようなものかと思います。スイッチのようなものが仮想的に作成され、そこに複数のコンテナがホストとして接続されているような感じかと。
実際にやってみる
では実際にコンテナを立ち上げて本当にそのように動くかを確認してみます。
Dockerはネットワークを指定しないで立ち上げたコンテナにはデフォルトで用意されているbridgeネットワークにコンテナを接続させる仕組みになっています。そのため、何もしていない状態でもbridgeネットワークはデフォルトで存在します。下の NAME
が bridge
になっているものがそれです。
bookstore@ [/Users/bookstore] % > docker network ls NETWORK ID NAME DRIVER SCOPE db5018912e91 bridge bridge local 1553d31b2a95 host host local a1caa97e1265 none null local
inspect
オプションを付けネットワークを指定することで詳細な情報を見ることができます。Containers
になにも表示されていないので、接続されているコンテナは0個になっています。出力内容が多いので一部内容を省略しています。
bookstore@ [/Users/bookstore] % > docker network inspect bridge [ { "Name": "bridge", "Containers": {}, ]
新しくコンテナを起動すると、bridgeネットワークに接続されます。
bookstore@ [/Users/bookstore] % > docker run -it --rm busybox / #
bookstore@ [/Users/bookstore] % > docker network inspect bridge [ { "Name": "bridge", "Containers": { "e68fcea0501f8138177544e50aaae695aed9302c0d0e395c980f9e62daff12f0": { "Name": "unruffled_fermi", "EndpointID": "eff1fbbec8708771300e0850d0f495057517de74e9493c3ee64e9b5e6204e3ca", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, ]
もう一つ起動させます。
bookstore@ [/Users/bookstore] % > docker run -it --rm busybox / #
bookstore@ [/Users/bookstore] % > docker network inspect -v bridge [ { "Name": "bridge", "Containers": { "4a3593c9b0492d0faeeb98c5391b8a0f62ca649e860058bf8195a38654f4e99b": { "Name": "peaceful_ellis", "EndpointID": "e4e82648e4e774775343a21f1a042a96f2a530fea1be84b68b9129618c81cfc6", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "e68fcea0501f8138177544e50aaae695aed9302c0d0e395c980f9e62daff12f0": { "Name": "unruffled_fermi", "EndpointID": "eff1fbbec8708771300e0850d0f495057517de74e9493c3ee64e9b5e6204e3ca", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, ]
これで2つのコンテナがbridgeに接続されました。では、これらのコンテナがネットワークで接続されていることを確認するためping
コマンドで確かめてみたいと思います。
最初に起動させたコンテナから、2つ目に起動したコンテナに対してping
を打つと通信ができていることが確認できます。
/ # ping 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.084 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.152 ms 64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.088 ms 64 bytes from 172.17.0.2: seq=3 ttl=64 time=0.103 ms 64 bytes from 172.17.0.2: seq=4 ttl=64 time=0.089 ms 64 bytes from 172.17.0.2: seq=5 ttl=64 time=0.103 ms ^C --- 172.17.0.2 ping statistics --- 6 packets transmitted, 6 packets received, 0% packet loss
使用させていただいたアイコンについて
Shipping Container icon icon by Icons8