はじめに

Dockerコンテナはそれぞれ独立した仮想環境として動作しますが、Webサーバー、アプリケーション、データベースなど複数のコンテナが連携して動作するには通信手段が必要です。

この通信を実現するのが「Dockerネットワーク」です。特に、Dockerがデフォルトで作成する「bridge(ブリッジ)ネットワーク」は基本となるネットワークであり、コンテナ間通信の初学習には最適です。

本記事では、Dockerネットワークの全体像から、ポートのマッピング、デフォルトネットワークの挙動、独自ネットワークの作成、名前解決やIP設定までを詳しく解説します。

ポートの関連付け

まず、Dockerネットワークの説明の前提として、ホストとコンテナ間の通信方法であるポートマッピングについて理解しておきましょう。

たとえば、以下のコマンドで2つのNGINXコンテナを起動します。

$ docker container run -p 3000:80 -d --rm --name web1 nginx
$ docker container run -p 3001:80 -d --rm --name web2 nginx

NGINXは内部でポート80を使用しますが、-p オプションを使ってホスト側のポートと結びつけることで、ブラウザからアクセス可能になります。

  • http://localhost:3000web1の80番ポート
  • http://localhost:3001web2の80番ポート

ポートの割り当て状況は docker port コマンドで確認できます。

$ docker port web1
80/tcp -> 0.0.0.0:3000

デフォルトネットワークとコンテナ間通信

Dockerではデフォルトで以下のネットワークが作成されます。

$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
84ee3eb8011a   bridge    bridge    local
2608c71b8b1b   host      host      local
08401ea912ba   none      null      local

この中で bridge は、コンテナ間通信を可能にする仮想ネットワークです。特にネットワークを指定しなければ、すべてのコンテナはこのbridgeネットワークに自動的に参加します。

コンテナのネットワーク設定を確認

以下のようにUbuntuコンテナを2つ起動します。

$ docker container run -itd --name u1 ubuntu bash
$ docker container run -itd --name u2 ubuntu bash

それぞれのネットワーク設定を docker container inspect で確認します。

$ docker container inspect --format '{{json .NetworkSettings.Networks}}' u1

出力例:

1
2
3
4
5
6
7
{
  "bridge": {
    "Gateway": "172.17.0.1",
    "IPAddress": "172.17.0.2",
    ...
  }
}
$ docker container inspect --format '{{json .NetworkSettings.Networks}}' u2
1
2
3
4
5
6
7
{
  "bridge": {
    "Gateway": "172.17.0.1",
    "IPAddress": "172.17.0.3",
    ...
  }
}

両者とも同じbridgeネットワーク上にあり、異なるIPアドレスが自動的に割り当てられていることが分かります。

コンテナ間通信の確認

互いに通信できることを確認するために ping コマンドを実行します。ただし、Ubuntuイメージには ping がインストールされていないため、事前に以下を実行します。

$ docker exec u1 apt update && docker exec u1 apt install -y iputils-ping
$ docker exec u2 apt update && docker exec u2 apt install -y iputils-ping

通信確認:

$ docker exec u1 ping -c 2 172.17.0.3
$ docker exec u2 ping -c 2 172.17.0.2

成功すると、以下のような出力が得られます。

PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.061 ms

このように、同一ネットワーク上のコンテナはIPアドレスを使って通信が可能です。

独自ネットワークの作成と接続管理

デフォルトの bridge ネットワークでは、すべてのコンテナが同じネットワークに接続されるため、意図しないコンテナ間の通信が可能になってしまうリスクがあります。
そのため、プロジェクトごとに専用のネットワークを作成し、通信を制御することが推奨されます。

ネットワークの作成

$ docker network create my-network

確認:

$ docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
...            my-network   bridge    local

作成したネットワークに接続する

以下のように、--network オプションでネットワークを指定してコンテナを起動できます。

$ docker container run -itd --name u3 --network my-network ubuntu bash

ネットワーク設定の確認:

$ docker container inspect --format '{{json .NetworkSettings.Networks}}' u3

出力例:

1
2
3
4
5
6
7
{
  "my-network": {
    "Gateway": "172.19.0.1",
    "IPAddress": "172.19.0.2",
    ...
  }
}

同様に u4 コンテナを作成し、u3 と通信できるか確認します。

$ docker container run -itd --name u4 --network my-network ubuntu bash
$ docker exec u3 ping -c 2 172.19.0.3
$ docker exec u4 ping -c 2 172.19.0.2

通信が成功すれば、ネットワークが正しく構成されていることが分かります。

他ネットワークとの分離を確認する

デフォルトの u1u2 コンテナは、my-network とは異なるネットワークに属しています。よって、u3 から u1 への通信は失敗します。

$ docker exec u3 ping -w 3 172.17.0.2

出力例:

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

docker network connect / disconnect

起動済みのコンテナにネットワークを追加するには connect を、切断するには disconnect を使います。

1
2
3
$ docker container run -itd --name u5 ubuntu bash
$ docker network connect my-network u5
$ docker network disconnect bridge u5

設定確認:

$ docker container inspect --format '{{json .NetworkSettings.Networks}}' u5

bridge ネットワークが消えて my-network のみになっていれば、切り替え完了です。

名前解決とエイリアス

独自ネットワーク上では、IPアドレスではなくコンテナ名での通信が可能になります。

たとえば、以下のように通信できます:

1
$ docker exec u4 ping -c 2 u3

出力:

PING u3 (172.19.0.2) 56(84) bytes of data.
64 bytes from u3.my-network (172.19.0.2): icmp_seq=1 ttl=64 time=0.055 ms

これは docker network が自動的に簡易DNSサーバーのように機能しているためです。

エイリアス(別名)を設定する

--network-alias または --alias を使えば、コンテナ名とは別に通信で使用できる名前(エイリアス)を追加できます。

$ docker container run -itd --name u21 --network my-network --network-alias test ubuntu bash
$ docker exec u3 ping -c 2 test

または既存コンテナに対して:

$ docker container run -itd --name u22 ubuntu bash
$ docker network connect --alias test2 my-network u22
$ docker exec u3 ping -c 2 test2

エイリアスも名前解決され、通信が可能です。

ネットワークの管理と詳細設定

Dockerではネットワークに関する情報や操作を行うための各種コマンドが用意されています。

ネットワークの詳細表示

ネットワークの状態を詳しく確認したい場合は、docker network inspect を使用します。

$ docker network inspect my-network

出力例(省略版):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
  "Name": "my-network",
  "Driver": "bridge",
  "Containers": {
    "xxxxx": {
      "Name": "u3",
      "IPv4Address": "172.19.0.2/16"
    },
    ...
  },
  "IPAM": {
    "Config": [
      {
        "Subnet": "172.19.0.0/16",
        "Gateway": "172.19.0.1"
      }
    ]
  }
}

ネットワークの削除

ネットワークを削除するには以下のコマンドを使用します。
ただし、接続中のコンテナがあるネットワークは削除できません。

$ docker network rm my-network

未使用のネットワークをまとめて削除したい場合は prune が便利です。

$ docker network prune

IPアドレスの手動設定

docker network create では --subnet--gateway--ip-range を指定して、IP関連の設定が可能です。

$ docker network create \
  --subnet=172.20.1.0/24 \
  --gateway=172.20.1.254 \
  --ip-range=172.20.1.1/30 \
  test-network

この場合、--ip-range により割り当て可能なIPが 172.20.1.1〜3 に制限されます。

コンテナ起動時に IP を明示的に指定することも可能です:

$ docker run -itd --name u9 --network test-network --ip 172.20.1.10 ubuntu bash

設定確認:

$ docker container inspect --format '{{json .NetworkSettings.Networks}}' u9

出力:

1
2
3
4
{
  "IPAddress": "172.20.1.10",
  "Gateway": "172.20.1.254"
}

IPアドレスの競合や枯渇が起きないよう注意して設定しましょう。

ネットワークの種類

Dockerでは bridge 以外にもいくつかのネットワークドライバーが用意されています。

ネットワーク種別 ドライバー 用途・特徴
bridge bridge 同一ホスト内のコンテナ間通信(デフォルト)
host host コンテナがホストのネットワークを直接使用(Linux限定)
overlay overlay 複数ホスト間の通信(Swarmなど)
macvlan macvlan 固有のMACアドレスを持ち、外部ネットワークに直接接続
none null ネットワーク接続なし

通常の開発用途では bridgehost、必要に応じて macvlanoverlay を使い分ける形になります。

まとめ

本記事では、Dockerにおけるネットワークの基本として以下の点を解説しました:

  • bridgeネットワークはデフォルトで使用され、コンテナ間通信が可能
  • ポートマッピングを用いればホストとの通信も可能
  • 独自ネットワークを作成し、通信範囲を制限することが推奨される
  • 名前解決やIPアドレスの手動設定も可能であり、柔軟な運用ができる
  • docker network inspect, connect, disconnect などのコマンドを活用すれば細かい管理が可能

Dockerネットワークを正しく理解し、プロジェクトに応じた適切な設計と運用ができるようになれば、より安全で管理しやすいコンテナ環境を構築できます。