Dockerネットワークの作成・管理・接続方法
Dockerでコンテナを運用していると、「複数のコンテナ間でうまく通信ができない」「アプリケーションコンテナとデータベースコンテナを連携させたいが、どう設定すればよいかわからない」といった悩みに直面することがあります。Dockerコンテナはデフォルトで独立した隔離環境として動作するため、何も設定しなければ他のコンテナと通信できません。
この記事では、コンテナ間の通信を管理する仕組みである「Dockerネットワーク」について、基本的な概念から具体的なコマンド、docker-compose.ymlでの設定方法までを解説します。Dockerネットワークの仕組みを理解すれば、コンテナ同士の連携がスムーズになり、マイクロサービス構成やWebアプリケーションとデータベースを組み合わせた構成など、複数コンテナを連携させるシステムを安全かつ柔軟に構築できるようになります。
Dockerネットワークとは
Dockerネットワークは、コンテナ間の通信を管理するための機能です。Dockerコンテナはデフォルトで独立した隔離環境として動作しますが、Dockerネットワークを利用することで、複数のコンテナが相互に通信できるようになります。
たとえば、Webアプリケーションのコンテナとデータベースのコンテナを別々に起動した場合、そのままでは互いの存在を認識できません。同じDockerネットワークに参加させることで、コンテナ名を使った名前解決ができるようになり、IPアドレスを意識せずに通信できるようになります。
Docker networkのコマンド
Dockerネットワークは、docker networkコマンドで作成・確認・削除ができます。ここでは、実務でよく使う基本コマンドを紹介します。
ネットワークを作成する
新しいDockerネットワークを作成するには、以下のコマンドを実行します。
docker network create ネットワーク名
このコマンドを実行すると、指定した名前のネットワークが作成されます。以降、このネットワークにコンテナを参加させることで、コンテナ同士が通信できるようになります。
ネットワーク一覧を表示する
現在作成されているネットワークの一覧を確認するには、以下のコマンドを使用します。
docker network ls
デフォルトで用意されているbridgeやhost、noneといったネットワークに加え、自分で作成したネットワークも一覧に表示されます。
ネットワークを削除する
不要になったネットワークは、以下のコマンドで削除できます。
docker network rm ネットワーク名
なお、ネットワークにコンテナが接続されたままの状態では削除できません。削除する前に、対象のコンテナを停止するか、ネットワークから切り離しておく必要があります。
ネットワークに所属するコンテナを確認する
どのコンテナがどのネットワークに接続されているかを確認したい場合は、docker network inspectコマンドを使用します。
docker network inspect <network_id>
docker network inspect ネットワーク名
出力結果の"Containers"項目に、そのネットワークに所属するコンテナが列挙されます。複数のコンテナを連携させる構成では、意図したコンテナが正しくネットワークに参加できているかを確認する際に役立ちます。
コンテナが属するネットワークを検索する
逆に、特定のコンテナがどのネットワークに参加しているかを調べたい場合は、docker container inspectコマンドを使用します。
docker container inspect -f '{{.NetworkSettings.Networks}}' <container_id>
docker container inspect -f '{{.NetworkSettings.Networks}}' コンテナ名
コンテナが複数のネットワークに参加している場合、その一覧が表示されます。「コンテナ同士が通信できない」というトラブルが起きた際は、まずこのコマンドで想定通りのネットワークに接続されているかを確認するとよいでしょう。
コマンドラインでの指定
コマンドラインでコンテナを起動する際は、docker runコマンドに--network ネットワーク名オプションを指定することで、特定のネットワークにコンテナを接続できます。このオプションを使用することにより、コンテナは指定したネットワーク内で他のコンテナと通信できるようになります。
docker run --network ネットワーク名 イメージ名
なお、--networkオプションを省略した場合、コンテナはデフォルトのbridgeネットワークに接続されます。複数のコンテナを連携させたい場合は、事前にdocker network createで作成したネットワークを明示的に指定することを推奨します。
docker-compose.ymlでネットワークを指定する
複数のコンテナをまとめて管理する場合は、コマンドを都度実行するよりも、docker-compose.ymlにネットワーク設定を記述しておく方法が効率的です。ここでは、代表的な3つのパターンを紹介します。
docker-compose.ymlで新規ネットワークに参加する
services配下の各サービスで、参加させたいネットワーク名をnetworks:に指定します。あわせて、ファイル下部のnetworks:セクションで、そのネットワークの定義を行います。
services:
myapp:
networks:
- my-network
networks:
my-network:
name: my-network
ここで指定するservices.myapp.networksのネットワーク名と、ファイル下部のnetworks:直下のキー名は一致させる必要があります。名前が食い違っていると、Docker Composeが意図したネットワークを認識できず、起動時にエラーとなるため注意してください。
docker-compose.ymlで既存のネットワークに参加する
すでにdocker network createなどで作成済みのネットワークに参加させたい場合は、networks:でexternal: trueを指定します。
services:
myapp:
networks:
- existing-already-network
networks:
existing-already-network:
name: already-network
external: true
external: trueを指定すると、Docker Composeはそのネットワークを新規作成せず、既存のネットワークとして扱います。複数のdocker-compose.ymlファイルにまたがってコンテナを連携させたい場合や、他のプロジェクトで作成したネットワークを共有したい場合に利用します。
ホストマシンのネットワークを利用する
コンテナをホストマシンと同じネットワーク空間で動作させたい場合は、network_mode: hostを指定します。
services:
myapp:
network_mode: host
この場合、コンテナはホストマシンのネットワークインターフェースをそのまま利用するため、portsオプションによるポートフォワーディングの設定は無効になります。ポートの公開設定をしなくてもホスト側から直接アクセスできる反面、複数のコンテナで同じポート番号を使用できなくなる点には注意が必要です。
同一ネットワーク内のコンテナ通信について
同一のdocker-compose.ymlファイルで作成されたコンテナは、特に指定がない場合、デフォルトで同一のネットワークに自動的に接続されます。そのため、同じdocker-compose.yml内であれば、意識してネットワーク設定を書かなくてもコンテナ同士は通信可能です。
また、同一ネットワーク内のコンテナ同士が通信する際には、ホスト側に公開しているポート番号ではなく、コンテナ内部のポート番号を使用する点に注意してください。たとえば、Webアプリケーションコンテナからデータベースコンテナに接続する場合は、docker-compose.ymlのportsで指定したホスト側のポートではなく、コンテナが内部で待ち受けているポート番号(例: MySQLであれば3306番)を指定します。
まとめ
Dockerネットワークを正しく理解して使いこなすことで、次のような課題を解決できます。
- コンテナ間で通信ができないというトラブルの解消
- 複数コンテナを組み合わせた構成の見通しの良い管理
- 既存ネットワークとの連携やホストネットワークの活用による柔軟な構成変更
コンテナ同士の連携がうまくいかない場合は、まずdocker network lsやdocker network inspectで現在のネットワーク構成を確認し、意図したネットワークにコンテナが接続されているかをチェックすることから始めてみてください。
