はじめに
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:3000
→web1
の80番ポートhttp://localhost:3001
→web2
の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
出力例:
|
|
$ docker container inspect --format '{{json .NetworkSettings.Networks}}' u2
|
|
両者とも同じ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
出力例:
|
|
同様に 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
通信が成功すれば、ネットワークが正しく構成されていることが分かります。
他ネットワークとの分離を確認する
デフォルトの u1
や u2
コンテナは、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
を使います。
|
|
設定確認:
$ docker container inspect --format '{{json .NetworkSettings.Networks}}' u5
bridge
ネットワークが消えて my-network
のみになっていれば、切り替え完了です。
名前解決とエイリアス
独自ネットワーク上では、IPアドレスではなくコンテナ名での通信が可能になります。
たとえば、以下のように通信できます:
|
|
出力:
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
出力例(省略版):
|
|
ネットワークの削除
ネットワークを削除するには以下のコマンドを使用します。
ただし、接続中のコンテナがあるネットワークは削除できません。
$ 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
出力:
|
|
IPアドレスの競合や枯渇が起きないよう注意して設定しましょう。
ネットワークの種類
Dockerでは bridge
以外にもいくつかのネットワークドライバーが用意されています。
ネットワーク種別 | ドライバー | 用途・特徴 |
---|---|---|
bridge | bridge | 同一ホスト内のコンテナ間通信(デフォルト) |
host | host | コンテナがホストのネットワークを直接使用(Linux限定) |
overlay | overlay | 複数ホスト間の通信(Swarmなど) |
macvlan | macvlan | 固有のMACアドレスを持ち、外部ネットワークに直接接続 |
none | null | ネットワーク接続なし |
通常の開発用途では bridge
と host
、必要に応じて macvlan
や overlay
を使い分ける形になります。
まとめ
本記事では、Dockerにおけるネットワークの基本として以下の点を解説しました:
bridge
ネットワークはデフォルトで使用され、コンテナ間通信が可能- ポートマッピングを用いればホストとの通信も可能
- 独自ネットワークを作成し、通信範囲を制限することが推奨される
- 名前解決やIPアドレスの手動設定も可能であり、柔軟な運用ができる
docker network inspect
,connect
,disconnect
などのコマンドを活用すれば細かい管理が可能
Dockerネットワークを正しく理解し、プロジェクトに応じた適切な設計と運用ができるようになれば、より安全で管理しやすいコンテナ環境を構築できます。