Dockerのネットワークを理解する!(1)

最近Dockerをプライベートで使う機会が多いのですが、なんとなくで使っている部分が多く時々困ります。その中でも特にネットワークに関してはもともと理解が浅いのかイマイチ理解できていません。ので、調査してみました。

Dockerのネットワークをについては以下の公式リファレンスに載っています。

docs.docker.com

ネットワークドライバ

Dockerのネットワークを調べると第一に出てくるのがネットワークドライバという言葉です。この言葉はどうやらDockerでネットワークを構成する方法を表しているみたいで、執筆時点では以下の4つのネットワークドライバがあります。

  • bridge ... デフォルトのドライバ
  • host ... ホストネットワークを直接使用するドライバ
  • overlay ... Docker Swarm サービスが相互に接続できるドライバ
  • macvlan ... コンテナにMACアドレスを割り当てるドライバ
  • none ... ネットワークを無効にするドライバ

少し古いですが、上記の bridge、overlay、macvlanについて解説している公式ブログ記事がありました。参考として以下に乗せておきます。

www.docker.com

今回は一番よく使われていると勝手に思っている bridge ネットワークドライバについて調べてみます。

そもそもブリッジとは?

まずは基本から行きます!そもそもブリッジとはそもそも何なのでしょうか?

安心・安全の「マスタリング TCP/IP 入門」で調べてみました。

マスタリングTCP/IP 入門編 第5版

マスタリングTCP/IP 入門編 第5版

ブリッジとはOSI参照モデルデータリンク層でネットワークを接続する機械のことになります。

f:id:bau1537:20200111143629j:plain

ただ、Dockerでいうブリッジとは上記の図のような異なるネットワークを接続させるのではなく、下の図のように複数のホストを接続させる目的で使用されるブリッジのことかと思います。このような機械はスイッチと言われます。

f:id:bau1537:20200111144259j:plain

Docker の bridge とは?

公式サイトでは以下のページに詳しく書いてあります。

docs.docker.com

以下の文章で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ネットワークとは、ソフトウェアによって構築されたブリッジのことで同じブリッジに接続されているコンテナ間を通信可能にするものということになります。なので異なるブリッジに接続されているコンテナは通信することができないということになりますね。

イメージとしては以下のようなものかと思います。スイッチのようなものが仮想的に作成され、そこに複数のコンテナがホストとして接続されているような感じかと。

f:id:bau1537:20200111150059j:plain

実際にやってみる

では実際にコンテナを立ち上げて本当にそのように動くかを確認してみます。

Dockerはネットワークを指定しないで立ち上げたコンテナにはデフォルトで用意されているbridgeネットワークにコンテナを接続させる仕組みになっています。そのため、何もしていない状態でもbridgeネットワークはデフォルトで存在します。下の NAMEbridge になっているものがそれです。

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