前回は、生成時に作成されていたデフォルトのネットワークについて確認しました。今回は、独自のネットワークを生成する方法について確認しましょう。

ネットワークを生成する

下記コマンドは、ネットワークmy-networkを生成するコマンドです。簡単ですね。

$ docker network create my-network
d8c0f19a36cc2ce1774fcd6a7a93ca23ced6b282a8fb355f399c731b2c7ce5eb

デフォルトで生成されているbridgeと今回作成したmy-networkについて、少し調べてみましょう。

こちらは、デフォルトで生成されているbridgeネットワークの様子です。

$  docker network inspect bridge 
[
    {
        "Name": "bridge",
        "Id": "6cd916ece8c4f69a7ff5f7056794cadea6a3ff4f5045c15449dd7f2ba9d82e39",
        "Created": "2020-09-01T01:57:15.511771326Z",
        "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": {}
    }
]

こちらはmy-networkネットワークの様子です。

$ docker network inspect my-network 
[
    {
        "Name": "my-network",
        "Id": "d8c0f19a36cc2ce1774fcd6a7a93ca23ced6b282a8fb355f399c731b2c7ce5eb",
        "Created": "2020-09-08T01:25:39.1570301Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.20.0.0/16",
                    "Gateway": "172.20.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

両者をくらべてみると下記のようにサブネットが別になっているのがポイントです。

bridgemy-network
Driverbridgebridge
Subnet172.17.0.0/16172.20.0.0/16

コンテナ起動時にネットワークを指定して起動する

コンテナ起動時にネットワークを指定して起動するには、--networkにネットワーク名を指定します。

# ネットワークを指定していない場合は、デフォルトのbirdgeネットワークに接続される。
$ docker run -it -d --name centos7-bridge centos:centos7 

# my-network上で起動する。
$ docker run -it -d --name centos7-my-network --network my-network centos:centos7 

上記のコマンドを実行すると下記のようにそれぞれのnetwork上にコンテナ(=”Containers”)が認識されます。

$ docker network inspect bridge 
[
  ・・・
        "Containers": {
            "0c6d4afac2f1ee6f094a62f303aae5c16138d4a6f93c63287afbd35bdf5b55b5": {
                "Name": "centos7-bridge",
                "EndpointID": "29d4e931733d5d307ebe14561cdf578ad6405246e4755b64873be89ce893f99c",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
   ・・・
]
$ docker network inspect my-network 
 [
   ・・・ 
        "Containers": {
            "91f8e4c8e71fc4c3ca68b8e1d0d0824a4d4af507169cfcb3b75655781d1dafd1": {
                "Name": "centos7-my-network",
                "EndpointID": "69dad37667e248ee804c45f5881347d09224e44e2c065253f58507c4275d6126",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            }
        },
   ・・・
]  

コンテナに割り振られたIPアドレスは、下記のコマンドで確認できます。

$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos7-bridge
172.17.0.2

$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos7-my-network
172.20.0.2

後からネットワークに接続する


$ docker run -it -d --name centos7-2 centos:centos7
# すでに起動してcentos7-2というコンテナをmy-networkネットワークに接続する
$  docker network connect my-network centos7-2  

このとき、bridgemy-networkを確認してみると下記のようになっています。

$ docker network inspect bridge 
[
    ・・・
    "Containers": {
            "0c6d4afac2f1ee6f094a62f303aae5c16138d4a6f93c63287afbd35bdf5b55b5": {
                "Name": "centos7-bridge",
                "EndpointID": "8d3f2c43b4a7e0a8bb97e18c86b44e45a683e8cd5635b8cdb1867693c1bfc801",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "78b7bab53bdcfe7bd128399817cfcaa5269c6472b9562a413604de1dacbee1a7": {
                "Name": "centos7-2",
                "EndpointID": "c934522a3def340e34f8c737a37d9b1b07dfa5b7fa273f83cf13b33ed3d8aac7",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
    ・・・
]

$  docker network inspect my-network 
[
    ・・・
        "Containers": {
            "78b7bab53bdcfe7bd128399817cfcaa5269c6472b9562a413604de1dacbee1a7": {
                "Name": "centos7-2",
                "EndpointID": "10832886fe1606b2a00b1e2d003a87ad89a6361e03f15675bd708f15aa5ef63f",
                "MacAddress": "02:42:ac:14:00:03",
                "IPv4Address": "172.20.0.3/16",
                "IPv6Address": ""
            },
            "91f8e4c8e71fc4c3ca68b8e1d0d0824a4d4af507169cfcb3b75655781d1dafd1": {
                "Name": "centos7-my-network",
                "EndpointID": "69dad37667e248ee804c45f5881347d09224e44e2c065253f58507c4275d6126",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            }
        },

    ・・・
]

現状は、2つのネットワークに所属しています。こちらのネットワークに関しては、コンテナを止めて、再度起動した場合にも維持されます。

$ docker stop centos7-2
# 再度起動
$ docker start centos7-2 

この状態で上記と同様にそれぞれのネットワークを確認してみるとそれぞれのネットワークに所属していることがわかります。

ネットワークから切断する

network disconnectを利用します。下記は、my-networkから切断する方法です。

$ docker network disconnect my-network centos7-2 

my-networkを確認します。

$ docker network inspect my-network  
[
    ・・・
        "Containers": {
            "91f8e4c8e71fc4c3ca68b8e1d0d0824a4d4af507169cfcb3b75655781d1dafd1": {
                "Name": "centos7-my-network",
                "EndpointID": "69dad37667e248ee804c45f5881347d09224e44e2c065253f58507c4275d6126",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            }
        }, 
    ・・・
]

my-networkからcentos7-2コンテナが消えていることが確認できます。

外部向けにポートを公開する

ここでは、nginxのイメージを利用しようと思います。下記コマンドでmy-network上でnginxを起動します。

$ docker run --name test-nginx1 --network my-network -p 8080:80 -d nginx

上記コマンドで利用して-pが外部にポートを公開する方法です。もう少し詳しく記載すると外部(=dockerエンジンの外側、dockerコマンドを利用している環境、ここではホストと呼ぶ)は、ネットワーク空間が別になっているので、そのままアクセスすることができません。nginxのコンテナ自身は、well-knowポートである80ポートを開けているので、それをホスト側で利用できるようにホスト上のポート8080でコンテナの80ポートと”同一視する”という設定です。

外部から利用する際には、「-p 外部ポート番号:コンテナ内のポート番号」で指定します。明示的に外部ポートを指定することで外部から利用できるようになります。指定が無い場合には外部からの利用ができないので注意が必要です。

おわりに

Dockerのネットワークは、コマンド一つでできかなり楽な印象があります。次回は、永続ボリュームについて紹介しようと思います。