(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Docker】docker0のbridgeを用いてコンテナ間通信を行う

スポンサーリンク

はじめに

Dockerインストール時に自動的に作成されるbridgeですが、オプションを指定せずにコンテナを作成するとそのコンテナはbridgeに接続した構成となります。

本記事ではDockerのネットワーク理解の第一歩として,同一ホストで作成した二つのコンテナ間で通信を行う流れを解説します。

f:id:mtiit:20190506215009p:plain

コマンド実行環境
ホスト環境 Red Hat Enterprise Linux Server 7.6

brigde接続

事前確認

Dockerがインストール済みの場合、ネットワークインターフェースを確認すると「docker0」というイーサネットブリッジ(Ethernet bridge)が作成されているはずです。

# ip addr
1: lo: ...
2: eth0: ...
3: docker0: ...
    link/ether ...
    inet 172.17.0.1/16 scope global docker0
...

172.17.0.0がサブネットで172.17.0.1のIPアドレスが与えられているdocker0が確認できました。

次にdocker network lsコマンドにてネットワークの一覧を表示します。

# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
efb3af624e0f        bridge              bridge              local
bf1109e77fce        host                host                local
03bb47ddbb2b        none                null                local

この bridge,host,nullは予め存在しているネットワークであり、引数なしでコンテナを作成するとそのコンテナはbridge接続となります。

ブリッジ接続とは?

f:id:mtiit:20190506220826p:plain
( https://www.youtube.com/watch?v=2vcLgcH_hDI&t=2074s より画像を抜粋 )

コンテナを作成する際に同じブリッジに接続すれば同じIP体系でアドレスが割り振られることにより、互いに通信を行うことが可能です。

ブリッジ情報の確認

bridgeの情報をdocker network inspect コマンドにて確認してみます。

# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "efb3af624e0fc25cab358f728f26210633809359c7fe11d45c0b82e72c6d4fa0",
        "Created": "XXX",
        "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,
        "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": {}
    }
]

先ほど確認したIPアドレスがGatewayとして割り当てられていることが確認できます。

まずはコンテナを一つ起動します。

# docker run -it ubuntu
root@06196a0265ca:/# 

bridgeに関して再確認します。

# docker network inspect bridge
...
"Containers": {
            "06196a0265ca91779aad80b19865b16847a5fd57c6f88c76f81bf56ebff15a66": {
                "Name": "sad_bardeen",
                "EndpointID": "cef36c8aee6479ee90a4c5bd403f903ba2cf3d59c1c392e5444e6032185c6d8b",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        }
...

コンテナに関する情報が追加され、IPアドレスは172.17.0.2が割り当てられていることが確認できます。

2台目のコンテナを起動します。

# docker run -it ubuntu
root@2db3bcb4fe93:/# 

再度確認を行うと

# docker network inspect bridge
...
"Containers": {
            "06196a0265ca91779aad80b19865b16847a5fd57c6f88c76f81bf56ebff15a66": {
                "Name": "sad_bardeen",
                "EndpointID": "cef36c8aee6479ee90a4c5bd403f903ba2cf3d59c1c392e5444e6032185c6d8b",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "2db3bcb4fe93451c75597c22351e524445fc267c4c05e646e69122f7ac152a16": {
                "Name": "musing_austin",
                "EndpointID": "687602e76d73954dec6fc9ff43bdaecde0730b75c2cfa3703d8dd2def51d2e4b",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
        },
...

2台目のコンテナに172.17.0.3が割り当てられています。

疎通確認

コンテナ間の通信はncコマンドにて行います。

尚、イメージによってはncコマンドが入っていないのでインストールしてください。

# apt-get update
# apt-get install netcat
...
Do you want to continue? [Y/n] y
...

1台目のコンテナにて以下コマンドにてポート8888にてリッスン状態で待機します。

root@06196a0265ca:/# nc -lp 8888

2台目のコンテナにて1台目のコンテナに向けて test hoge Ctrl+C(切断)を送ります。

root@2db3bcb4fe93:/# nc 172.17.0.2 8888
test
hoge
^C

確かに1台目の画面を確認すると以下のように受信が行えています。

test
hoge
root@84bf47c87827:/#

ちなみに待ち構えていないポートへ送信を行うと以下のように疎通はできないことも合わせて確認できます。

root@2db3bcb4fe93:/#  nc 172.17.0.2 8880
(UNKNOWN) [172.170.0.2] 8880 (?) : Connection refused

終わりに

Dockerではネットワークを指定せずにdocker runを行うとdocker0に該当するbridgeで接続されます。
一般的にはdocker network create -d bridge BRIDGENAMEにてブリッジを作成し、docker run -it --net=BRIDGENAMEで指定したブリッジに接続しますが、その前の入門としてデフォルトのbridgeによる接続確認の手順を紹介しました。

ご参考になれば幸いです。