前回は、Dockerfileの作成方法を確認しました。以前紹介したdocker psコマンドなどを利用すると実行中のコンテナのIPアドレスを確認することが出来ました。今回は、ネットワークについて確認していきましょう。

デフォルトのネットワークを確認する

前回までは、Docker内部のネットワークについて意識せずに利用していました。現状のネットワークの確認をします。

$ docker network ls               
NETWORK ID          NAME                DRIVER              SCOPE
17e644550ecf        bridge              bridge              local
6645e0984e9c        host                host                local
f3227d80ccb2        none                null                local

デフォルトのネットワークは、3つのネットワークが 実装されています。コンテナを実行するネットワークを指定したいときは、--netで指定します。ネットワークの詳細情報を見るためにdocker network inspectコマンドを利用します。下記例は、bridgeネットワークの情報を表示した例です。

$ docker network  inspect bridge
[
    {
        "Name": "bridge",
        "Id": "17e644550ecf26ba0e810933d4a8146ae66d80e609e610311b1e624f90fdc2c1",
        "Created": "2020-07-20T13:39:21.153490615Z",
        "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": {},
        "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": {}
    }
]

ブリッジ名は、docker0、サブネットなどの情報も取得できています。
今度は、適当なコンテナを起動して確認してみます。

$ docker run -dit --name alpine1 alpine ash
$ docker run -dit --name alpine2 alpine ash    

bridgeネットワークを調べてみます。

$ docker network  inspect bridge
[
    {
        "Name": "bridge",
        "Id": "988f0af2f9ab7961aa8de1e811850cdc79bbd5621dbe5e9b5a406134204ef8b8",
        "Created": "2020-08-04T22:03:36.034883405Z",
        "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": {
            "17176ea43139bee5d79c272516378127abd40148406813660af02127e60ea8f6": {
                "Name": "alpine2",
                "EndpointID": "32f693dd2826d2ebf3f66bf0bf22c93741da381236f94106781c961efccafd54",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "ce93f1dccb68fae643b9640d61ce61ce8e83f6484a0252d3cdb58b98140ea255": {
                "Name": "alpine1",
                "EndpointID": "9fb26ce03a3e454dd2f87d217e22870ca934cc91694f3117b4800606275a7207",
                "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ネットワークのContainersにalpine1、alpine2が存在していることがわかります。このことから、ネットワークを指定せずに起動した場合には、bridgeネットワークで動作することが分かります。

alpine1に接続します。

$ docker attach alpine1 
/ #

networkインターフェースを確認します。

/ # ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN qlen 1000
    link/tunnel6 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ #

eth0に172.17.0.2の同じアドレスがあることが確認できます。

インターネットへ接続できるか確認します。

/ # ping -c 2 google.com
PING google.com (172.217.175.14): 56 data bytes
64 bytes from 172.217.175.14: seq=0 ttl=37 time=35.369 ms
64 bytes from 172.217.175.14: seq=1 ttl=37 time=48.506 ms

--- google.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 35.369/41.937/48.506 ms
/ #

応答がかえってきているので接続できていることがわかります。

次にコンテナに通信ができるか確認します。alpine2のipアドレス172.17.0.3への接続を確認します。

/ # ping -c 2 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.115 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.089 ms

--- 172.17.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.089/0.102/0.115 ms
/ #

bridgeネットワークに属する2つのコンテナの疎通確認ができました。

ついでにコンテナ名でも通信できるか確認します。

/ # ping -c 2 alpine2
ping: bad address 'alpine2'
/ #

こんな形でアドレスの解決ができていないことがわかります。

今回は、入門編ということなので省略しますが、bridgeネットワークをもう少し突っ込んで理解するためには、veth、Linuxのネットワーク名前空間等の知識が必要になってきます。また、Docker DesktopだとLinuxに依存している部分が見えづらいので、別途VirtualBox + Vagrant等を利用したLinux環境上にDockerエンジンをインストールした環境を構築する必要があります。このあたりについては、また別の記事でまとめる予定ですので、楽しみにしていて下さい。

bridgeネットワークについて図で表すとこんな感じになっています。

まとめ

今回は、簡単ではありますがデフォルトのネットワークの確認とコンテナ追加時の挙動、コンテナ間通信を見てきました。次回は、独自のネットワークを作成してみようと思います。