いろいろ書いていく

やってみたなど

Docker network tutorial (bridge編)

Docker公式ドキュメントのbridge network tutorialをやってみた.
docs.docker.com

環境

Docker 18.09.1 on Ubuntu 18.04 (Oracle VirtualBox VM on macOS)
 インストール方法はこちら↓
koimedenshi.hatenablog.com

  • default bridge network

デフォルトブリッジはその名の通りデフォルトで用意されているネットワーク.
ネットワークを指定せずにコンテナを立ち上げると, ここに接続される.
ここでは2台のalpineコンテナをデフォルトブリッジに接続する.

初期状態の確認

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f0e09069add5        bridge              bridge              local
6dc567989d6f        host                host                local
dd596238709d        none                null                local

2台のalpineコンテナの立ち上げ

$ docker run -dit --name alpine1 alpine ash

$ docker run -dit --name alpine2 alpine ash

起動したコンテナの確認

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
4081fada5d19        alpine              "ash"               2 minutes ago       Up 2 minutes                            alpine2
f9926cee8b76        alpine              "ash"               2 minutes ago       Up 2 minutes                            alpine1

ブリッジネットワークの接続状況をinspectで確認

$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "f0e09069add5f694454f4b91aa92b249834c51f990436233d3d1302cd14f1bcc",
        "Created": "2019-01-22T09:55:52.056584987+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": {
            "4081fada5d19e08d10b7a903261c12f66d42d962b639851256525babc933c7f7": {
                "Name": "alpine2",
                "EndpointID": "f94f5c25a244f5f921e066f00950cc9926675d131c84cfdbfec86319e398ce78",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "f9926cee8b761f44da6f8646132c6e6d2a1b4ece6c7d46e49b8f6e98d577efee": {
                "Name": "alpine1",
                "EndpointID": "784c9240218a496ce26d6301354ec0051fbd5f9ef657ded18736e079bf89ed6f",
                "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": {}
    }
]

alpine1コンテナ, alpine2コンテナはbridgeネットワークに接続され, デフォルトゲートウェイ172.17.0.1/16を介してDocker hostと通信する.

f:id:koimedenshi:20190124122754p:plain
default-bridge

実際にコンテナの中から確認する.
attachコマンドでalpine1に接続する.

$ docker attach alpine1

/ #

ipコマンドでインターフェースの確認

/ # 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
13: eth0@if14: <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

loopbackとeth0(172.17.0.2/16)が立ち上がっている.

外向けにpingを打ってみる

/ # ping -c 2 google.com
PING google.com (216.58.197.142): 56 data bytes
64 bytes from 216.58.197.142: seq=0 ttl=61 time=9.415 ms
64 bytes from 216.58.197.142: seq=1 ttl=61 time=10.116 ms

--- google.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 9.415/9.765/10.116 ms

alpine2のIPアドレスpingを打ってみる

/ # 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.117 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.099 ms

--- 172.17.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.099/0.108/0.117 ms

'alpine2'にpingを打つと失敗する

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

デフォルトブリッジではコンテナ名指定で疎通しないことがわかる.
alpine1のシェルを抜けてから(CTRL+p + qの順に押す),使用したコンテナを削除する

$ docker container stop alpine1 alpine2
$ docker container rm alpine1 alpine2

デフォルトブリッジのチュートリアル終わり.

  • user-defined bridge networks

次にユーザ定義ネットワークのチュートリアルを行う.
まずalpine-netという名前のネットワークを作成

$ docker network create --driver bridge alpine-net
3fe4ed300746ac93ff0eb283f239d3482aeedc88a9aa0e2eb1354a6ca79527ac

ネットワークが追加されたことを確認

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
3fe4ed300746        alpine-net          bridge              local
b005254ef24e        bridge              bridge              local
6dc567989d6f        host                host                local
dd596238709d        none                null                local

inspectコマンドでalpine-netの接続状況を確認. この段階では何もつながっていない

$ docker network inspect alpine-net 
[
    {
        "Name": "alpine-net",
        "Id": "3fe4ed300746ac93ff0eb283f239d3482aeedc88a9aa0e2eb1354a6ca79527ac",
        "Created": "2019-01-24T11:04:19.021413436+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": {}
    }
]

ネットワークアドレスは172.19.0.0/16となっている.
自動生成されるアドレス帯は環境によって異なる.

以下のコマンドで4台のコンテナを起動する.

$ docker run -dit --name alpine1 --network alpine-net alpine ash
26673686e6ff88c401c6e5b9dd007d1519ac603f86d1251195392a846f398ac5
$ docker run -dit --name alpine2 --network alpine-net alpine ash
6d36c4792f2b5c16b4a381a930d51b7456ab216efcc7af4363f9204c3a27a16a
$ docker run -dit --name alpine3 alpine ash
7747f25eb4e7729b83741be135f9fdc13c84695519abd77544f1f01fbe400d17
$ docker run -dit --name alpine4 --network alpine-net alpine ash
f39f29ac4f23bd0bb41bf39e80961d542a23f3cb79f91b93bbc00bee690a2e1b
$ docker network connect bridge alpine4
$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
f39f29ac4f23        alpine              "ash"               31 seconds ago       Up 29 seconds                           alpine4
7747f25eb4e7        alpine              "ash"               49 seconds ago       Up 48 seconds                           alpine3
6d36c4792f2b        alpine              "ash"               About a minute ago   Up About a minute                       alpine2
26673686e6ff        alpine              "ash"               About a minute ago   Up About a minute                       alpine1

ざっくり言うと以下のようなネットワーク構成になっている

f:id:koimedenshi:20190124115430p:plain
user-defined

inspectコマンドでalpine-netを確認すると,コンテナが3台追加されている

$ docker network inspect alpine-net 
[
    {
        "Name": "alpine-net",
        "Id": "3fe4ed300746ac93ff0eb283f239d3482aeedc88a9aa0e2eb1354a6ca79527ac",
        "Created": "2019-01-24T11:04:19.021413436+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": {
            "26673686e6ff88c401c6e5b9dd007d1519ac603f86d1251195392a846f398ac5": {
                "Name": "alpine1",
                "EndpointID": "10d86d5b8ac9a132fa018c1ef2af71fa605ebcc48db24c1176628f36fc8cee08",
                "MacAddress": "02:42:ac:13:00:02",
                "IPv4Address": "172.19.0.2/16",
                "IPv6Address": ""
            },
            "6d36c4792f2b5c16b4a381a930d51b7456ab216efcc7af4363f9204c3a27a16a": {
                "Name": "alpine2",
                "EndpointID": "ceb49779dff5690117bc9ab18995bf443a8f77d2c956a2152179561676ca0a3c",
                "MacAddress": "02:42:ac:13:00:03",
                "IPv4Address": "172.19.0.3/16",
                "IPv6Address": ""
            },
            "f39f29ac4f23bd0bb41bf39e80961d542a23f3cb79f91b93bbc00bee690a2e1b": {
                "Name": "alpine4",
                "EndpointID": "49f46643172030e0de68dd093aca27a45d6c8ddf606cdc8a7c1eee8228b8f360",
                "MacAddress": "02:42:ac:13:00:04",
                "IPv4Address": "172.19.0.4/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

alpine1の中からpingを打ってみると,今度はコンテナ名でも通じることがわかる.

$ docker container attach alpine1

/ # ping -c 2 alpine2

--- alpine2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.095/0.097/0.099 ms


/ # ping -c 2 alpine4
PING alpine4 (172.19.0.4): 56 data bytes
64 bytes from 172.19.0.4: seq=0 ttl=64 time=0.255 ms
64 bytes from 172.19.0.4: seq=1 ttl=64 time=0.156 ms

--- alpine4 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.156/0.205/0.255 ms


/ # ping -c 2 alpine1
PING alpine1 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.073 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.122 ms

--- alpine1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.073/0.097/0.122 ms

この機能はautomatic service discoveryという.

一方alpine3はネットワークが異なるため,名前解決できないし,IPアドレスでも到達できない.

/ # ping -c 2 alpine3
ping: bad address 'alpine3'
/ # ping -c 2 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes

--- 172.17.0.2 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

CTRL+p+qでalpine1を抜けて,今度はalpine4からpingを打ってみる.

$ docker container attach alpine4
/ # ping -c 2 alpine1
PING alpine1 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.067 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.086 ms

--- alpine1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.067/0.076/0.086 ms


/ # ping -c 2 alpine2
PING alpine2 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.090 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.097 ms

--- alpine2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.090/0.093/0.097 ms


/ # ping -c 2 alpine3
ping: bad address 'alpine3'
/ # ping -c 2 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.115 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.155 ms

--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.115/0.135/0.155 ms


/ # ping -c 2 alpine4
PING alpine4 (172.19.0.4): 56 data bytes
64 bytes from 172.19.0.4: seq=0 ttl=64 time=0.035 ms
64 bytes from 172.19.0.4: seq=1 ttl=64 time=0.105 ms

--- alpine4 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.035/0.070/0.105 ms

デフォルトブリッジとユーザ定義ブリッジの両方に接続しているので,すべてのコンテナに到達できる.
ただしalpine3はデフォルトブリッジのため,名前解決はできない.

ブリッジネットワークに接続しているので,全てのコンテナがグローバルアドレスへ到達可能.

/ # ping -c 2 google.com
PING google.com (172.217.25.238): 56 data bytes
64 bytes from 172.217.25.238: seq=0 ttl=61 time=10.855 ms
64 bytes from 172.217.25.238: seq=1 ttl=61 time=9.578 ms

--- google.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 9.578/10.216/10.855 ms

 終わったら作成したコンテナとネットワークを削除

$ docker container stop alpine1 alpine2 alpine3 alpine4

$ docker container rm alpine1 alpine2 alpine3 alpine4

$ docker network rm alpine-net

まとめ

ブリッジネットワークのチュートリアルを実施した.
商用環境ではdefault bridge networkは非推奨とのこと.
逆に開発環境でコンテナ1台お手軽に試すとかならdefaultでも十分そう.

以上