Dockerネットワークモード詳解 — bridge/host/none/overlayの使い分け

コンテナ

Dockerでコンテナを起動したとき、「どうやって外とつながっているのか」「複数コンテナを会話させるにはどうすればいいか」で詰まった経験はありませんか。Dockerのネットワークモードを正しく理解すれば、この疑問は一気に解決します。

結論から言うと、本番環境では「カスタムbridgeネットワーク」を使うのが正解です。デフォルトのbridgeでコンテナ名が解決できず詰まる、というのはよくある落とし穴です。本記事では Docker 20.10.12 / Ubuntu 24.04.4 LTS 環境で実際にコマンドを動かして、各ネットワークモードの挙動を確認した結果を載せます。

この記事のポイント

  • Dockerには bridge/host/none/overlay の4種類のネットワークドライバーがある
  • デフォルトbridgeはDNSなし。コンテナ名でpingすると bad address エラーになる(実測で確認)
  • カスタムbridgeを使うと組み込みDNS(127.0.0.11)が有効になり、コンテナ名で通信できる
  • none モードはloインターフェースのみ。外部pingは Network is unreachable で失敗する
  • overlay は Docker Swarm 専用。単一ホストの開発には不要
  • Docker Compose はデフォルトでプロジェクト名のカスタムbridgeを作成するため、サービス名で通信できる

目次

  1. デフォルトネットワーク3種類を確認する
  2. bridge モード — デフォルトだが落とし穴あり
  3. カスタムbridge — 本番で使うべき設定
  4. host モード — Linuxで有効な高速通信
  5. none モード — 完全に隔離したいとき
  6. overlay モード — Swarmクラスタ向け
  7. 使い分けガイド
  8. よくあるエラーと解決策
  9. まとめ

動作確認済み環境

Docker version 20.10.12(build e91ed57)/ Ubuntu 24.04.4 LTS(Docker公式イメージ、カーネル 5.10.76-linuxkit)で検証しています。Ubuntu 22.04 LTS でも同じ結果を確認済みです。

デフォルトネットワーク3種類を確認する

Docker をインストールすると、コマンドを何も打たなくても3つのネットワークが自動で作られます。docker network ls で確認できます。




ubuntu@linuxlab: ~
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
b22808ae3a2b bridge bridge local
18c65bddc3c8 host host local
14078de0e6fb none null local
docker network ls 実測結果とnoneモード遮断確認
docker network ls 実測結果とnoneモード遮断確認

実際に Docker 20.10.12 で実行した結果です。bridge(bridgeドライバー)、host(hostドライバー)、none(nullドライバー)の3つが存在しています。

docker network ls 実測 + デフォルトbridgeのサブネット確認
docker network ls 実測 + デフォルトbridgeのサブネット確認

bridgeネットワークのサブネットは 172.17.0.0/16、ゲートウェイは 172.17.0.1 でした。docker run でネットワークを指定しなかった場合、コンテナはすべてこのbridgeに接続されます。

bridge モード — デフォルトだが落とし穴あり

①bridge モードの仕組み

bridgeモードは Docker のデフォルトです。ホストに docker0 という仮想ブリッジが作られ、コンテナはその下の仮想ネットワーク(172.17.0.0/16)に接続されます。外部へは NAT(ネットワークアドレス変換)を使って通信します。

コンテナを1つ起動して、IPアドレスを確認してみます。




ubuntu@linuxlab: ~
$ docker run –rm ubuntu:24.04 hostname -I
172.17.0.13

172.17.0.13 というアドレスが割り当てられました。bridgeネットワークのサブネット(172.17.0.0/16)内のIPです。外部への通信はホストのIPアドレスを使ってNATされます。

②デフォルトbridgeの落とし穴 — DNS名前解決ができない

ここが最大の注意点です。デフォルトのbridgeネットワークでは、コンテナ名でのDNS名前解決が使えません。

実際に2つのコンテナを起動して確認しました。




ubuntu@linuxlab: ~ — デフォルトbridgeでの名前解決テスト(実測)
$ docker run -d –name dnm_def1 busybox sleep 300
6a43a7128bee4b5cfe2c52668bc7d6148fd8c171…
$ docker run -d –name dnm_def2 busybox sleep 300
423884ad4c8211bc8169694ceae7bc4b34232…
$ docker exec dnm_def1 ping -c 2 dnm_def2
ping: bad address ‘dnm_def2’

ping: bad address 'dnm_def2' というエラーになりました。コンテナ名で解決できていません。IPで直接指定すれば通信は可能ですが、コンテナのIPは起動のたびに変わるため実用的ではありません。

注意

--link フラグを使えばコンテナ名で通信できる」という古い情報が Web 上に残っています。しかし --linkdeprecated(非推奨) であり、Docker の将来バージョンで削除される予定です。現在はカスタムbridgeネットワークを使うのが正解です。

カスタムbridge — 本番で使うべき設定

①カスタムbridgeネットワークの作り方

カスタムbridgeを使うと、Docker 組み込みDNS(127.0.0.11)が自動設定され、コンテナ名で相互通信が可能になります。実際に作って確認します。




ubuntu@linuxlab: ~ — カスタムbridgeネットワーク作成(実測)
$ docker network create –driver bridge \
–subnet 172.30.0.0/16 \
–ip-range 172.30.5.0/24 \
–gateway 172.30.0.1 \
dnm_mynet
23a928876c01a1f1ad9c8e67f91bf877bcfac2f36c0a07231a34a2097851f4e5

ネットワークが作成されました。主要オプションの意味は以下の通りです。

オプション 値(今回の例) 意味
--driver bridge bridge ドライバーを明示(省略可、デフォルトがbridge)
--subnet 172.30.0.0/16 ネットワーク全体のIPアドレス範囲
--ip-range 172.30.5.0/24 コンテナに自動割り当てするIP範囲
--gateway 172.30.0.1 外部へのゲートウェイIPアドレス

②コンテナ間通信(コンテナ名で ping)

2つのコンテナを同じカスタムbridgeに接続して、コンテナ名でpingが通るか確認します。

カスタムbridgeでコンテナ名pingが通ることを実測で確認
カスタムbridgeでコンテナ名pingが通ることを実測で確認

実測結果です。ping dnm_app2(コンテナ名指定)で 172.30.5.20 に解決され、4パケット全て受信(0% packet loss)、往復遅延は平均 0.125 ms でした。

docker network inspect dnm_mynet でネットワーク構成を確認します。




ubuntu@linuxlab: ~
$ docker network inspect dnm_mynet
[
{
“Name”: “dnm_mynet”,
“Driver”: “bridge”,
“IPAM”: {“Config”: [{“Subnet”: “172.30.0.0/16”,
“IPRange”: “172.30.5.0/24”,
“Gateway”: “172.30.0.1”}]},
“Containers”: {
“dnm_app1”: {“IPv4Address”: “172.30.5.10/16”},
“dnm_app2”: {“IPv4Address”: “172.30.5.20/16”}
}
}
]

指定した通り dnm_app1 が 172.30.5.10、dnm_app2 が 172.30.5.20 にそれぞれ固定IPで配置されていることが分かります。

③デフォルトbridge vs カスタムbridge の決定的な違い

デフォルトbridge(名前解決失敗)vs カスタムbridge(名前解決成功)実測比較
デフォルトbridge(名前解決失敗)vs カスタムbridge(名前解決成功)実測比較

上の実測比較が全てを示しています。

  • デフォルトbridgeping dnm_def2bad address 'dnm_def2'(DNS なし)
  • カスタムbridgeping dnm_app2172.30.5.20 に解決、0% packet loss

Docker Compose を使うと、プロジェクト名(ディレクトリ名)を使ったカスタムbridgeが自動作成されます。だからこそ docker-compose.yml でサービス名を使って通信できるのです。

Dockerネットワークモード全体比較表(実測)
Dockerネットワークモード全体比較表(実測)

host モード — Linuxで有効な高速通信

①hostモードの特徴

hostモードでは、コンテナがホストのネットワーク名前空間を直接共有します。コンテナに独自のIPアドレスは割り当てられず、ホストのIPアドレスとポートをそのまま使います。




ubuntu@linuxlab: ~
$ docker run –rm –network host ubuntu:24.04 ip addr show
# ホストのネットワークインターフェースがそのまま見える(Linux環境)
# eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> …
# inet 192.0.2.10/24 … ← ホストのIPがそのまま

macOS・Windows では hostモードが使えない

Docker Desktop(macOS/Windows)では、Docker は Linux VM 上で動いているため、hostモードを指定してもホスト(Mac/Windows)のネットワークに直接アクセスはできません。--network host を指定してもbridgeモードと同様の動作になります。hostモードが有効に機能するのは Linux 上で Docker を直接動かしている場合のみです。VPS(Ubuntu Server)で Docker を使う場合は有効です。

②hostモードが役に立つ場面

hostモードが有効なのは、以下のような状況です。

  • ネットワーク性能が最優先(NATオーバーヘッドをゼロにしたい)
  • 大量のポートを公開する必要があるサービス(例:ゲームサーバー、メディア配信)
  • ホストのネットワークインターフェースを直接操作するネットワーク監視ツール

Linux VPS 上で Nginx を hostモードで動かすと、-p 80:80 という --publish 指定が不要になり、ポートマッピングのオーバーヘッドなしに直接80番ポートをバインドできます。

none モード — 完全に隔離したいとき

①noneモードで何が起きるか

--network none を指定したコンテナは、ネットワークから完全に切り離されます。実際に確認しました。




ubuntu@linuxlab: ~ — none モード実測
$ docker run –rm –network none busybox sh -c “ip addr show”
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
# eth0 がない → ネットワークインターフェースはloだけ
$ docker run –rm –network none busybox ping -c 1 8.8.8.8
ping: sendto: Network is unreachable

実測で確認できた通り、noneモードのコンテナには lo(ループバック、127.0.0.1/8)だけが存在し、ルーティングテーブルは空です。外部への ping は Network is unreachable で失敗します。

②noneモードの使い所

完全なネットワーク遮断が有効なケースはいくつかあります。

  • セキュリティ隔離:外部との通信が一切不要な処理(暗号化、オフラインデータ変換など)
  • バッチ処理:ファイルの変換・圧縮・分析など、ネットワークを使わないジョブ
  • テスト環境:外部APIに誤ってアクセスしないよう隔離したい単体テスト

overlay モード — Swarmクラスタ向け

overlayモードは Docker Swarm(複数のDockerホストをクラスタとして束ねる機能)専用です。異なるホスト上のコンテナが、まるで同じネットワーク上にいるかのように通信できます。




ubuntu@linuxlab: ~ — overlay ネットワーク(Swarm必須)
# Swarm を初期化してからでないと overlay は作れない
$ docker swarm init
Swarm initialized: current node (xxxx) is now a manager.
$ docker network create –driver overlay my_overlay
abcdef123456789…
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
b22808ae3a2b bridge bridge local
abcdef123456 my_overlay overlay swarm

Swarm なしでは overlay は作れない

docker network create --driver overlay xxx を Swarm 未初期化の環境で実行すると Error response from daemon: This node is not a swarm manager というエラーになります。単一ホスト環境での複数コンテナ連携にはカスタムbridgeを使いましょう。

Kubernetes を使う場合は Flannel や Calico などのCNIプラグインが同様の役割を担うため、overlay ドライバーを直接意識することは少ないです。

使い分けガイド

どのモードを選べばよいか、用途別にまとめます。

使いたい場面 推奨モード 理由
docker run で1つだけ起動、コンテナ間通信なし bridge(デフォルト) 何も指定しなくていい。外部通信はNATで問題なし
複数コンテナをサービス名で通信させたい カスタムbridge DNS自動設定。Docker Composeもこれを使う
Docker Compose を使う カスタムbridge(自動) Composeがプロジェクト名のネットワークを自動作成
NATを避けて最大限のネットワーク性能が欲しい(Linux VPS) host NATなしでホスト直接バインド。Linux専用
ネットワーク不要な処理を安全に隔離したい none lo のみ、完全遮断。漏洩リスクゼロ
複数ホスト(Docker Swarm)でコンテナをまたぐ overlay Swarmの仮想ネットワーク。マルチホスト専用
著者アイコン
著者アイコン

正直、最初は「デフォルトのbridgeだけ覚えれば十分でしょ」と思っていました。でも Docker Compose を使い始めてから、カスタムbridgeの重要性がやっと分かりました。--link を使っていた時代の古い記事に惑わされないよう注意してください。

よくあるエラーと解決策

エラー1: ping: bad address 'コンテナ名'

デフォルトbridgeネットワーク上でコンテナ名を使って通信しようとしたときに出るエラーです。

解決策:カスタムbridgeネットワークを作って、両コンテナを同じネットワークに接続してください。




ubuntu@linuxlab: ~
$ docker network create mynet
$ docker run -d –name app1 –network mynet nginx
$ docker run -d –name app2 –network mynet alpine sleep 300
$ docker exec app2 ping -c 2 app1
# 通る!

エラー2: failed to allocate gateway: Address already in use

指定したゲートウェイIPがすでに他のネットワークで使われているときのエラーです。

解決策docker network lsdocker network inspect で既存ネットワークのサブネットを確認し、重複しないサブネットを指定してください。




ubuntu@linuxlab: ~
# 既存ネットワークのサブネット一覧を確認
$ docker network ls –format “{{.Name}}” | \
xargs -I{} docker network inspect {} –format “{{.Name}}: {{range .IPAM.Config}}{{.Subnet}}{{end}}”
bridge: 172.17.0.0/16
my_other_net: 172.18.0.0/16
# → 172.19.0.0/16 など空いているサブネットを使う
$ docker network create –subnet 172.19.0.0/16 newnet

エラー3: This node is not a swarm manager

Swarm なしで overlay ネットワークを作ろうとしたときのエラーです。

解決策:単一ホストなら overlay は不要です。カスタムbridgeを使いましょう。どうしても overlay が必要なら docker swarm init で Swarm を初期化してから再度実行します。

エラー4: Bind for 0.0.0.0:80 failed: port is already allocated

hostモードで起動しようとしたコンテナが使うポートが、ホスト上の別プロセスまたは別コンテナに使われているときのエラーです。

解決策sudo lsof -i :80 または ss -tlnp | grep :80 で該当プロセスを確認し、必要なら停止します。

まとめ

Dockerのネットワークモードをまとめます。

  • デフォルトの bridge は NAT で外部通信できるが、コンテナ名によるDNS解決はできない
  • 複数コンテナを連携させるには、カスタムbridgeを作るのが正解(Docker Compose も内部でこれを使っている)
  • カスタムbridgeでは Docker 組み込みDNS(127.0.0.11)が有効になり、コンテナ名で通信できる。実測で 0.125 ms の往復遅延、0% packet loss を確認
  • none モードはネットワーク完全遮断。ip addr show で lo のみ確認、外部 ping は Network is unreachable
  • host モードはLinux専用。Docker Desktop(macOS/Windows)では効果なし
  • overlay は Docker Swarm 専用。単一ホストでは不要

次のステップとして、Docker Compose を使ってカスタムbridgeネットワークを自動管理する方法を学ぶと、複数サービスの構成管理がさらに楽になります。

本格的にサーバーを運用したくなったら、VPS を借りて Ubuntu + Docker の環境を作るのがおすすめです。Vultr は東京リージョンがあり、月額数百円から始められます。

関連記事: Ubuntu に Docker をインストールする方法 / Docker Compose 入門

コメント

タイトルとURLをコピーしました