はじめに
Dockerコンテナはポータブルで分離された環境を提供しますが、実際のアプリケーションではコンテナ同士、ホスト、そして外部サービスとの通信が不可欠です。Dockerのネットワーキングモデルを理解することは、信頼性が高く、セキュアで、パフォーマンスの良いコンテナ化アプリケーションを構築するための基本です。
Dockerは複数の組み込みネットワークドライバー(bridge、host、overlay、macvlan、ipvlan、none)を提供しており、それぞれ異なるユースケースに適しています。本ガイドでは各ドライバーの詳細に加え、DNS解決、ポートマッピング、セキュリティ分離、Docker Composeのネットワーキングパターンまでを解説します。
Dockerネットワークドライバーの基礎
各コンテナはホストに接続された仮想ネットワークインターフェース(vethペア)を持ちます。Dockerはネットワーク名前空間を使用して、各コンテナに独立したネットワークスタック(IPアドレス、ルーティングテーブル、ポート)を提供します。
docker networkコマンドがネットワーク管理の中心です:
# 全ネットワークを一覧表示
docker network ls
# ユーザー定義ブリッジネットワークを作成
docker network create my-network
# ネットワークの詳細を確認
docker network inspect my-network
# 実行中のコンテナをネットワークに接続
docker network connect my-network my-container
Dockerの組み込みネットワークドライバーの比較:
| ドライバー | スコープ | ユースケース | DNS解決 |
|---|---|---|---|
| Bridge | 単一ホスト | スタンドアロンコンテナのデフォルト | ユーザー定義のみ |
| Host | 単一ホスト | 低レイテンシ、分離不要 | なし(ホストDNS) |
| Overlay | マルチホスト | Swarmサービス、クロスホスト通信 | 対応 |
| Macvlan | 単一ホスト | MACアドレスが必要なレガシーアプリ | 対応 |
| Ipvlan | 単一ホスト | 高性能、大規模サブネット | 対応 |
| None | 単一ホスト | 最大の分離 | なし |
ブリッジネットワークの実践
ブリッジネットワークはDockerのデフォルトドライバーです。Docker起動時にホスト上に仮想ブリッジdocker0が作成され、コンテナにはデフォルトで172.17.0.0/16サブネットのIPが割り当てられます。
デフォルトブリッジには制限があります:自動DNS解決がなく、すべてのコンテナが無差別に接続されます。ユーザー定義ブリッジはこれらの問題を解決します:
docker network create my-app-net
docker run -d --name web --net my-app-net nginx
docker run -d --name api --net my-app-net node:18
同一ユーザー定義ブリッジ上のコンテナはコンテナ名で相互解決できます:
# apiコンテナからwebのIPに名前解決
ping web
ポート公開はiptables DNATルールを介してホストポートをコンテナポートにマッピングします:
# ホストポート8080をコンテナポート80にマッピング
docker run -p 8080:80 nginx
ホストネットワークとオーバーレイネットワーク
ホストネットワーク
--network hostを指定すると、コンテナはホストのネットワークスタックを直接共有します。NAT変換も仮想インターフェースもなく、最小限のレイテンシが実現します。パフォーマンスベンチマークやホストインターフェースの監視が必要なアプリケーションに適していますが、ネットワーク分離はありません。
# docker-compose.yml
services:
benchmark:
image: tool:latest
network_mode: "host"
オーバーレイネットワーク
オーバーレイネットワークは複数のDockerホスト間の通信を可能にします。Swarmモードでは、オーバーレイネットワークを作成すると自動的に全ノードに配布されます:
docker network create -d overlay --attachable my-overlay
内部ではVXLANカプセル化を使用してコンテナパケットをラップし、物理ネットワーク境界を越えられるようにします。--opt encryptedフラグでIPsec暗号化も可能です。パフォーマンスオーバーヘッドはパケットあたり約50バイト、スループットは5〜10%低下します。
DNS解決とサービスディスカバリ
Dockerは各コンテナ内で127.0.0.11に組み込みDNSサーバーを実行し、ユーザー定義ブリッジおよびオーバーレイネットワーク上のコンテナ名をIPアドレスに解決します。デフォルトブリッジではDNS解決が提供されないため、ユーザー定義ブリッジを使用する必要があります。
Swarmモードでは、複数レプリカを持つサービスに対してDNSラウンドロビン解決が行われます:
# 3つのレプリカを持つサービスを作成
docker service create --name api --replicas 3 --network my-overlay my-api:latest
# 他のコンテナは"api"をDNSラウンドロビンで3つのレプリカのいずれかに解決
カスタムDNS設定もコンテナごとに適用できます:
docker run --dns 8.8.8.8 --dns-search example.com nginx
ポートマッピングとセキュリティ分離
ポートマッピングはホストポートをコンテナポートに変換します。-pフラグはhostPort:containerPort/protocolの形式をとります:
# 複数ポート、特定インターフェースへのバインド
docker run -p 127.0.0.1:8080:80 -p 443:443 nginx
ネットワーク分離のための仕組み:
- 内部ネットワーク(
--internal)— コンテナがインターネットにアクセス不可。 - ネットワークなし(
--network none)— ループバックのみ、最大の分離。 - 分離されたブリッジ— 信頼レベルに基づいて異なるユーザー定義ブリッジにコンテナを配置。
DockerにはKubernetesのような組み込みネットワークポリシーはありません。細かい制御にはiptables、firewalld、またはCalicoやCiliumなどのサードパーティプラグインを使用します。
Docker Composeのネットワーキングパターン
Docker Composeはプロジェクトごとにユーザー定義ブリッジネットワーク(<プロジェクト>_default)を作成します。Composeファイルで複数のカスタムネットワークを定義し、関心の分離を実現できます:
services:
web:
image: nginx
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
redis:
image: redis
networks:
- backend
networks:
frontend:
backend:
このパターンは公開Web層を内部データ層から分離します。webサービスのみが両方のネットワークに接続され、dbとredisは内部のbackendネットワークからのみアクセス可能です。
既存のネットワーク(共有監視ネットワークなど)に接続するには、外部ネットワークを使用します:
networks:
monitoring:
external: true
サービスをスケールする際、各レプリカは同じネットワーク上の別コンテナとして動作します。depends_onとhealthcheckおよびconditionを組み合わせてサービスの準備完了を確認し、起動順序だけに依存しないようにします。
まとめ
Dockerのネットワーキングモデルは、柔軟でセキュアかつ高性能なコンテナ通信オプションを提供します。シングルホストのマルチコンテナアプリケーションにはユーザー定義ブリッジネットワークから始めましょう。自動DNS解決と優れた分離を提供します。マルチホスト環境では、Docker Swarmとオーバーレイネットワークを使用します。
ネットワークトポロジーを設計する際のポイント:
- ハードコードされたIPアドレスよりもDNSベースのサービスディスカバリを優先する。
- 信頼レベルに基づいて異なるブリッジネットワークで層を分離する。
- ホストネットワーキングはレイテンシやインターフェースアクセスが重要な場合のみ選択する。
- Composeのネットワーク定義を活用してインフラを宣言的かつ再現可能にする。
ネットワークの問題はdocker network inspect、コンテナ内でのip addrやtcpdump、そしてクロスホスト接続のファイアウォールルール確認でデバッグできます。これらの基礎を押さえれば、強力で管理しやすいコンテナネットワークを構築できます。
