Dockerコンテナネットワーク

Dockerコンテナのネットワーク設定

コンテナのネットワークについては、3つのオプションbridge,host,noneが用意されています。

$ docker network ls

NETWORK ID          NAME                DRIVER              SCOPE
17e324f45964        bridge              bridge              local
6ed54d316334        host                host                local
7092879f2cc8        none                null                local

bridgeモード

コンテナ稼働時にはデフォルトでbridgeモードが選択されます。bridgeモードではコンテナ専用のネットワークが割り当てられ、ホストマシンのネットワークとは隔離されます。“docker network inspect bridge”“ifconfig” コマンドで割り当てられたIPアドレスなどの確認ができます。

$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "c0c58b4d39d158XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "Created": "2019-07-29T16:45:03.528703512+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": {},
        "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": {}
    }
]

$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:53ff:fe85:7593  prefixlen 64  scopeid 0x20<link>
        ether 02:42:53:85:75:93  txqueuelen 0  (イーサネット)
        RX packets 1  bytes 28 (28.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 229  bytes 38983 (38.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ユーザ定義のbridgeネットワークを作成することも出来ます。コンテナイメージ毎にbridgeネットワークを定義して、コンテナ稼働時にこのネットワークを指定する使用方法が推奨されているようです。

例)以下alpine-netという名称のbridgeネットワークを定義します。

$ docker network create --driver bridge alpine-net

Dockerネットワークリストにより、bridgeモードにalpine-netが追加されていることが確認できます。

$ docker network ls

NETWORK ID          NAME                DRIVER              SCOPE
e9261a8c9a19        alpine-net          bridge              local
17e324f45964        bridge              bridge              local
6ed54d316334        host                host                local
7092879f2cc8        none                null                local
$ docker network inspect alpine-net

[
    {
        "Name": "alpine-net",
        "Id": "e9261a8c9a19eabf2bf1488bf5f208b99b1608f330cff585c273d39481c9b0ec",
        "Created": "2017-09-25T21:38:12.620046142Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

alpineコンテナイメージをネットワーク指定して以下4種類のコンテナを稼働します。

$ docker run -dit --name alpine1 --network alpine-net alpine ash

$ docker run -dit --name alpine2 --network alpine-net alpine ash

$ docker run -dit --name alpine3 alpine ash

$ docker run -dit --name alpine4 --network alpine-net alpine ash

$ docker network connect bridge alpine4

各コンテナに割り当てられるIPアドレス、異なるbridgeネットワーク間通信については、上記リンク先ドキュメントを参照願います。

hostモード

ホストマシンのネットワーク環境をコンテナに適用します。

例)nginxウェブサーバをホストマシンネットワークで稼働させます。(–rmオプション:コンテナ停止時にコンテナを削除。–dオプション:バックグラウンド動作)

$ docker run --rm -d --network host --name my_nginx nginx

コンテナからホストネットワーク上のMySQLサーバへのアクセス

host=localhostを指定するとコンテナ内でのunix socket経由の接続となるためアクセスは拒否されます。MySQLの設定でbind-address=127.0.0.1になっていることを確認の上、host=127.0.0.1を指定します。

host mode

To access MySQL running on the docker host from containers in host mode , you can keep bind-address = 127.0.0.1 in your MySQL configuration and all you need to do is to connect to 127.0.0.1 from your containers:

[vagrant@docker:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

note: Do use mysql -h 127.0.0.1 and not mysql -h localhost ; otherwise the MySQL client would try to connect using a unix socket.

同一ネットワーク内で、あるコンテナからコンテナ稼働のMySQLサーバへアクセスする場合
MySQLコンテナ名をホスト名として指定します。

コンテナがデフォルトのBridgeネットワークを使用した場合、ホストマシン外部への転送(フォワーディング)は拒否されています。ホストマシン外部への転送(フォワーディング)を有効にするため、以下対応が必要です。

Enable forwarding from Docker containers to the outside world

By default, traffic from containers connected to the default bridge network is not forwarded to the outside world. To enable forwarding, you need to change two settings. These are not Docker commands and they affect the Docker host’s kernel.

  1. Configure the Linux kernel to allow IP forwarding.
$ sysctl net.ipv4.conf.all.forwarding=1
  1. Change the policy for the iptables FORWARD policy from DROP to ACCEPT .
$ sudo iptables -P FORWARD ACCEPT

These settings do not persist across a reboot, so you may need to add them to a start-up script.

再起動した場合にも設定が反映されるように起動スクリプトに上記2つのコマンドを追加する必要が有ります。

Docker-Composeで指定した各サービスへIPアドレスを付与する場合

$ docker network create --help

Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which to copy the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment

docker-composeファイル内で各サービスにIPアドレスを付与する場合、gatewayアドレスとサブネットを指定します。
EX)

$ docker network create --gateway 172.16.0.1 --subnet 172.16.0.0/24 nginx-proxy

Docker Compose Ver.2でのネットワークの書式

以下の書式でDocker Compose Ver.2では上記警告が表示されるため修正。

修正前

networks:
  default:
    external: true
    name: my-pre-existing-network
networks:
  default:
    external:
      name: ddev_default

修正後

networks:
  default:
    name: ddev_default
    external: true