Dock Stay
ネットワークを使い分ける - bridge / host / overlay の使い方・オプション・サンプル

ネットワークを使い分ける - bridge / host / overlay

Docker のネットワークドライバは bridge・host・overlay などに分かれ、用途が違う。user-defined bridge では DNS 解決が働き、`--network host` は Linux と Docker Desktop で挙動が大きく異なる。

概念図

bridge / host / overlay diagram

構文

bash
docker network create [--driver bridge|overlay] <name>
docker run --network <name|host> <image>

実例

user-defined bridge でサービス名 DNS 解決を使う

bash
docker network create appnet
docker run -d --name db --network appnet postgres:16
docker run -d --name api --network appnet myorg/api
# api コンテナから "db" でアクセスできる / api can reach "db" by name

compose で frontend / backend をネットワーク分離する

bash
services:
  web:
    image: nginx
    networks:
      - frontend
  api:
    image: myorg/api
    networks:
      - frontend
      - backend
  db:
    image: postgres:16
    networks:
      - backend
networks:
  frontend:
  backend:

ドライバの違い(bridge / host / overlay / none)

ドライバ 範囲 主な用途 備考
bridge 単一ホスト 既定。コンテナ間通信 + NAT 外向き user-defined bridge は DNS 付き
host 単一ホスト ホストのネットスタック直接利用 Linux 限定。Desktop は VM 越しで別挙動
overlay 複数ホスト Swarm などで L2 仮想ネット張る Swarm / KV ストア前提
none なし 外部通信を完全遮断 ネットワーク不要なジョブ向け

開発で意識するのはほぼ bridge と host の 2 つ。

Compose でネットワークを明示しない場合、プロジェクトごとに専用の user-defined bridge が自動で作られる。

user-defined bridge で DNS 解決

Docker の既定 bridge(bridge という名前そのもの)には歴史的経緯で DNS 機能が付いておらず、--link を使う必要がある。

対して docker network create や Compose で作られる user-defined bridge は内蔵 DNS が動き、同じネットワーク上のコンテナは「サービス名」や「コンテナ名」で相互に名前解決できる。

これにより api コンテナから db:5432 のような接続文字列がそのまま動作する。

複数のサービス群を論理的に分離したいときは、frontendbackend のように複数の user-defined bridge を作ってサービスを所属させると、API だけが両方に属してプロキシ役になる構成を安全に組める。

DB を含む backend ネットワークを外から到達不能にすることで、攻撃面を減らせる。

`--network host` が OS ごとに挙動違う

Linux で --network host を指定すると、コンテナはホストと同じネットワークスタックを使う。

NAT を通らずポートが直接公開されるためベンチマーク用途では便利だが、ポート衝突やセキュリティ境界の消失というデメリットもある。

一方、Docker Desktop(macOS / Windows)は裏側で軽量 VM を動かしているため、host を指定してもホスト OS と同じ IP を共有するわけではなく、VM 内のネットワークをホストにする挙動になる。

結果として macOS で「Linux と同じだろう」と思って --network host を書くと、ホスト OS から localhost:8080 でアクセスできない、という事故が起こる。

Docker Desktop 側でも新しめのバージョンでは experimental な host ネットワーキング対応が入っているが、依然として Linux と同等ではないことを前提にすべき。

bash
# Linux: ホストの :8080 にそのまま bind される
# Linux: binds directly to host :8080
docker run --rm --network host nginx

# Docker Desktop: VM 内の host であり macOS 本体ではない
# Docker Desktop: host of the VM, not the macOS itself

関連トピック