6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

福岡若手Sier_bcAdvent Calendar 2019

Day 13

Docker のネットワークについて

Last updated at Posted at 2019-12-12

この記事は、福岡若手Sier_bc Advent Calendar 2019 の 13 日目の投稿です。

はじめに

Docker を勉強していて、どうも難しく感じてしまうのがコンテナのネットワークについて。
自分の備忘録もかねて徒然なるままに綴ります。

確認用の環境構築

確認用の環境は、Virtual Box で仮想マシンを作成し、その中に Docker の環境を作ります。
以前の自分の投稿で

ただ、個人的に Virtual Box で仮想マシン作って〜、Nginx インストールして〜
ってのはめんどくさいので Docker でやってしまいます。(ごめんね)

と書いていましたが今回はわざわざ Virtual Box 上に Docker の環境を作ります。
ただ、ここはさすが Docker さん。
簡単に環境を構築できるコマンドが用意されています。
それが、 docker-machine コマンド。
( 「Docker 版の Vagrant 的なやつ」 と言うとイメージがしやすい?? )

やり方は簡単で、Virtual Box と docker-machine コマンドをインストール して以下のコマンドを実行。

docker-machine create nw-vm

これで、Virtual Box 上に Docker の環境が入ったnw-vmという名前のインスタンスが立ち上がります。
image.png
インスタンスの中に入るには、

$ docker-machine ssh nw-vm

   ( '>')
  /) TC (\   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-\)           www.tinycorelinux.net

docker@nw-vm:~$

で中に入れます。

デフォルトのネットワーク

インスタンスの中に入ったら、デフォルトの Docker ネットワークを確認します。

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
4a85b1978bc9        bridge              bridge              local
f06510f48928        host                host                local
6aa5429b7a4f        none                null                local

Docker をインストールすると必ずこれらのネットワークが作成されます。

bridge network

コンテナを起動する際に特にネットワークを指定しないと bridge が選択されます。
その詳細を確認します。
( ちなみに、docker で何かの詳細を確認する時はだいたい、docker ~ inspect ~ です。)

$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "4a85b1978bc9dfb5f5304686227fd6e4f34d7f0ef4cb567f7fb091211a9feb13",
        "Created": "2019-12-12T14:17:10.468964848Z",
        "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": {}
    }
]

注目すべきは以下です。

"Config": [
    {
        "Subnet": "172.17.0.0/16",
        "Gateway": "172.17.0.1"
    }
]

コンテナは、172.17.0.0/16 のネットワークに所属します。
そして、ゲートウェイの 172.17.0.1docker0 インターフェースに接続されています。
インスタンスのネットワークインターフェースを確認します。

$ ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:7C:77:4F:5F
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

inet addr:172.17.0.1 で、確かに docker0 インターフェースが 172.17.0.1 の IP アドレスが割り当てられていることが確認できました。

コンテナを起動してみる

$ docker run -itd --rm --name=nginx nginx

で起動し、詳細を確認

$ docker inspect nginx
~~~ 省略 ~~~
"Networks": {
    "bridge": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": null,
        "NetworkID": "4a85b1978bc9dfb5f5304686227fd6e4f34d7f0ef4cb567f7fb091211a9feb13",
        "EndpointID": "a3414897f695a122751cc0e33de651b988a91c3b69b493ad4ad66efab29b41d2",
        "Gateway": "172.17.0.1",
        "IPAddress": "172.17.0.2",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "02:42:ac:11:00:02",
        "DriverOpts": null
    }
}
~~~ 省略 ~~~

めちゃめちゃ表示される中から下の方の Networks でコンテナのネットワーク状態を確認できます。
このコンテナには、172.17.0.2 の IP アドレスが割り当てられています。

ネットワークの作成

$ docker network create my-bridge 

でユーザ定義のブリッジネットワークを作成することができます。
コンテナをネットワークに接続するためには、

// 起動中のコンテナの場合
docker network connect <ネットワーク名> <コンテナ名>

// 最初からネットワークに接続して起動する場合
docker run --network <ネットワーク名> ~~~

作成した、my-bridge とデフォルトの bridge の違いは、コンテナ名で名前解決ができるかどうかです。
ユーザ定義のネットワークであれば、コンテナ名で名前解決ができるため、
同じネットワークに所属するコンテナ同士であれば、コンテナ名で通信することができます。

host network

コンテナがこのネットワークに所属した状態で起動すると、コンテナはホストマシンのネットワークインターフェースと共有された状態になります。
例えば、Nginx のサーバを起動した場合、外部からコンテナの 80 番ポートにアクセスするためには -p オプションでポートフォワードを設定する必要があります。
しかし、host ネットワークであれば Nginx を起動したらホストマシンの 80 番ポートがそのままコンテナの 80 番ポートに流れて行きます。

docker-machine コマンドで起動したインスタンスの IP アドレスは、

$ docker-machine ip nw-vm
192.168.99.115

で確認することができます。
この状態で、host ネットワークに所属した Nginx コンテナを起動します。

$ docker run -itd --name=nginx2 --rm --network=host nginx

これで、ブラウザから先ほど確認した http://192.168.99.115 にアクセスすると Nginx デフォルトページが表示されるはずです。
image.png

none network

コンテナがこのネットワークに所属した状態で起動すると、このコンテナは ループバックインターフェースしか持たない 状態になります。

さいごに

立ち上げたインスタンスの停止は以下のコマンドでできます。

$ docker-machine stop nw-vm

次はマルチホスト上でのコンテナ間通信について書こうと思います。

ちなみに

docker-machine コマンドは有能なやつで、AWS の EC2 上に Docker ホストを構築できちゃったりもします。
詳しくは自分で調べてください。()

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?