Dockerネットワークモード完全解説:bridge/host/none/containerの性能比較と使い分け

深夜2時。ターミナルに表示された緑色の “Container started” を見つめながら、私は頭を抱えていました。サービスは起動しているのに、curlはずっとタイムアウト。docker logs を3回見直してもエラーなし。ポートマッピング -p 8080:80 も設定済み。ファイアウォールも切った。
問題はどこに?
後でわかったのですが、原因はネットワークモードの選択ミスでした。私はずっと docker run -p だけで万事解決だと思っていて、Dockerの裏側で bridge、host、none、container という4つのモードが動いていることを知りませんでした。もっと恥ずかしいことに、2年もDockerを使っていながら、docker0 ブリッジが何なのかすら説明できなかったのです。
もしあなたも「コンテナは起動しているのに繋がらない」経験があったり、Dockerネットワークの設定に自信がなかったりするなら、この記事はあなたのためのものです。Linuxの複雑なネットワーク名前空間の理論は抜きにして、実戦で本当に必要な知識だけをわかりやすく解説します。
Dockerネットワークの「土台」:docker0ブリッジ
docker0とは何か?
Dockerをインストールすると、システムに docker0 という仮想ネットワークインターフェース(NIC)が自動的に作成されます。これはマンションの「共有ルーター」のようなものです。全てのコンテナ(住人)は、外部と通信するためにここを通ります。
ターミナルで確認してみましょう:
ip addr show docker0こんな出力が出るはずです:
docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0この 172.17.0.1 がdocker0のIPアドレスです。Dockerは新しくコンテナを作るたびに、172.17.0.0/16 の範囲からIP(例:172.17.0.2)を割り当てます。
Dockerのネットワーク一覧も見てみましょう:
docker network lsNETWORK ID NAME DRIVER SCOPE
7f8a2b3c9d4e bridge bridge localこのデフォルトの bridge ネットワークの実体が、まさに docker0 ブリッジです。
veth pair:コンテナへ続く「見えないLANケーブル」
docker0だけでは足りません。コンテナという「密室」(ネットワーク名前空間)と、外の世界(docker0)をどう繋ぐか?
そこで登場するのが veth pair です。これは「仮想LANケーブル」の両端だと思ってください。片方(eth0)はコンテナの中に、もう片方(vethXXX)はホスト側にあり、この2つが対になって通信します。
コンテナを起動してみましょう:
docker run -d --name test-nginx nginxホスト側で確認:
ip addr | grep vethveth で始まるインターフェースが増えているはずです。次にコンテナの中を確認:
docker exec test-nginx ip addrコンテナ内には eth0 があり、IP(例:172.17.0.2)が割り当てられています。この eth0 から出たパケットは、瞬時にホスト側の vethXXX に到達し、docker0 を経由して、ホストの物理NICからインターネットへ出て行きます。
通信経路はこうです:
コンテナ内部(172.17.0.2)
↓ eth0
↓ (仮想LANケーブル)
↓ vethXXX
docker0ブリッジ(172.17.0.1)
↓ NAT変換
宿主機物理NIC(例: 192.168.1.100)
↓
インターネット少し複雑に見えますが、動作は非常に高速です。
Bridgeモード:Dockerの「デフォルト」
なぜデフォルトがBridgeなのか?
ネットワークモードを指定しない場合、Dockerは自動的に此のBridgeモードを使用します。理由はシンプルで、「隔離性」と「使いやすさ」のバランスが一番良いからです。
Bridgeモードでは各コンテナが独立したIPを持ち、ポート競合が起きません。同時に -p オプションで簡単に外部公開できます。
例えば2つのNginxを起動する場合:
docker run -d -p 8080:80 --name web1 nginx
docker run -d -p 8081:80 --name web2 nginx両方のコンテナが内部で80番ポートを使っていても、それぞれ独立したネットワーク空間にいるため衝突しません。ホスト側では8080と8081に振り分けられます。
デフォルトBridge vs カスタムBridge:決定的な違い
ここに初心者がハマる罠があります。デフォルトの bridge ネットワーク(docker0)では、コンテナ名でのDNS解決ができません。
試してみましょう:
docker run -d --name db mysql
docker run -it --name app alpine ping db
# ping: bad address 'db' (失敗!)IP直打ち(ping 172.17.0.2)なら通じますが、IPは変わる可能性があるので実用的ではありません。
しかし、自分で作ったカスタムBridgeネットワークなら話は別です:
docker network create mynet
docker run -d --name db --network mynet mysql
docker run -it --name app --network mynet alpine ping db
# 通信成功!成功しましたね。これが、**「本番環境では必ずカスタムネットワークを使え」**と言われる理由です。サービスディスカバリが圧倒的に楽になります。
-p パラメータの裏側:NAT
-p 8080:80 としたとき、DockerはホストのiptablesにNAT(Network Address Translation)ルールを追加します。
iptables -t nat -L -n | grep 8080これによって「ホストの8080へのアクセス」が「コンテナの172.17.0.2:80」へ転送されるわけです。
Bridgeモードの適用シーン
- マイクロサービス:複数コンテナが協調動作する場合(カスタムBridge必須)。
- 開発環境:手軽に環境を作る場合。
- Webアプリ:ポートマッピングが必要な一般的な用途。
性能面ではNATやvethのオーバーヘッドがわずかにありますが、99%のWebアプリでは誤差の範囲です。
Hostモード:「性能至上主義」の選択
Hostモードとは?
Hostモードは豪快です。「コンテナのネットワーク隔離?いらねぇ!」と、ホストのネットワークスタックをそのまま共有します。
docker run -d --net=host --name web nginxこのコンテナには独立したIPも eth0 もありません。ホストのIPをそのまま使います。したがって、**ポートマッピング(-p)も不要(無効)**です。コンテナが80番ポートをリッスンすれば、それはホストの80番ポートが開くことを意味します。
性能のメリット
docker0もvethもNATも全部パススルーします。パケットはホストのNICからダイレクトにプロセスに届きます。
ベンチマークによると、高負荷時でBridgeモードより5〜10%ほど高速と言われています。「たった10%?」と思うかもしれませんが、高頻度トレーディングやリアルタイムゲームサーバーのようなシビアな世界では、この数ミリ秒が命取りになります。
Hostモードの代償
速さの代償は以下の通りです:
- ポート競合の地獄:ホスト上で既に80番を使っていたら起動できません。同じコンテナを複数起動することも(ポートを変える設定をしない限り)不可能です。
- セキュリティリスク:コンテナからホストの全ネットワーク通信が見えてしまいます。
- OS依存:Docker Desktop for Mac/Windowsでは、仮想マシンの構造上、HostモードがLinux通りに動作しません(ホストからアクセスできない等の問題あり)。
いつHostモードを使うべきか?
正直なところ、どうしても性能が出ない時の最終手段と考えたほうがいいです。
- モニタリング:Prometheusや各Exporterなど、ホストのネットワーク情報を収集する必要がある場合。
- 超高性能プロキシ:NginxやHAProxyで、極限までレイテンシを削りたい場合。
- 巨大なポートレンジ:RTP(音声・動画通信)のように数千のポートを使う場合、NATの負荷がバカにならないのでHostモードが有利。
NoneとContainerモード:特殊部隊
Noneモード:陸の孤島
docker run -it --net=none alpine shネットワーク一切なし。loopback(自分自身)以外どことも通信できません。
使い道:
- 完全隔離されたバッチ処理:外部と通信させたくない、機密データの計算処理など。
- ネットワークの自作:Dockerの機能を使わず、自分で特殊なネットワーク設定を注入したい変態的な上級者向け。
日常的にはほぼ使いません。
Containerモード:二人羽織
あるコンテナのネットワーク名前空間を、別のコンテナが再利用するモードです。
docker run -d --name web nginx
docker run -it --net=container:web alpine sh2つ目のコンテナ(alpine)は、1つ目のコンテナ(web)と同じIP、同じポート範囲を共有します。まるで1つのマシンの上で2つのプロセスが動いているかのように localhost で通信できます。
使い道:
- KubernetesのPod:実はPodの正体はこれです。複数コンテナが「Pauseコンテナ」のネットワークを共有しています。
- デバッグ:動いているコンテナに、ネットワークツール満載の別コンテナを「寄生」させて調査する場合。
決定版:ネットワークモード選択フローチャート
迷ったらこれを見てください。
Q1: ネットワーク隔離は必要?
│
├─ No(性能最優先/ポート管理面倒)
│ └─ 【Hostモード】(注意:ポート競合、セキュリティ)
│
└─ Yes(通常ケース)
│
├─ コンテナ間で名前解決(DNS)したい?
│ ├─ Yes → 【カスタムBridge】★推奨
│ └─ No → 【デフォルトBridge】
│
└─ 極限のセキュリティ/ネットワーク不要?
└─ 【Noneモード】ケース別推奨設定
| シナリオ | 推奨モード | 理由 |
|---|---|---|
| 一般的なWebアプリ | カスタムBridge | 隔離性、接続性、管理のしやすさがベストバランス。 |
| マイクロサービス群 | カスタムBridge | コンテナ名で相互通信できるのが必須。 |
| Redis/MySQL単体 | Bridge / Host | 通常はBridgeで十分。超高負荷ならHost検討。 |
| Jenkins/CI | Bridge | ビルドごとに環境を隔離したい。 |
| ネットワーク監視Agent | Host | ホストのトラフィックを見る必要があるため。 |
| K8s Pod内のSidecar | Container | メインアプリとlocalhostで通信するため。 |
まとめ
長くなりましたが、持ち帰ってほしいのは以下の3点です:
- 基本は「カスタムBridge」:
docker network createして使う。これが現代のベストプラクティスです。デフォルトBridgeはDNSが効かないので避けましょう。 - Hostモードは「切り札」:性能問題で詰んだ時だけ出すカードです。常用するものではありません(特にMac/Winユーザーは注意)。
- トラブル時はモード確認:繋がらない時は、まず
docker network lsとdocker inspectで、コンテナが正しいネットワークに属しているか確認しましょう。
ネットワークはDockerの鬼門ですが、この「モードの使い分け」さえ理解していれば、8割のトラブルは回避できます。さあ、今すぐ docker network create して、快適なコンテナライフを!
Dockerネットワークモード選択ガイド
bridge, host, none, containerの4つのモードから最適なネットワーク構成を選ぶための手順
⏱️ Estimated time: 5 min
- 1
Step1: 要件の確認
アプリケーションに「極限のネットワーク性能」が必要か、それとも「管理のしやすさと隔離」が重要かを判断します。 - 2
Step2: モードの選択
通常は`bridge`を選択します。コンテナ間で通信する場合は必ず`docker network create`で作成したカスタムブリッジを使用します。ホストのネットワーク情報を直接扱う監視ツール等の場合は`host`を選択します。 - 3
Step3: 設定と実行
Bridgeの場合:`docker run --network my-net -p 8080:80 ...`
Hostの場合:`docker run --network host ...`
を設定して起動します。
FAQ
BridgeモードとHostモードの主な違いは何ですか?
なぜデフォルトのbridgeネットワークを使ってはいけないのですか?
Mac/WindowsでHostモードが機能しないのはなぜですか?
4 min read · 公開日: 2025年12月17日 · 更新日: 2026年1月22日
関連記事
Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践

Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践
Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド

Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド
Next.js ユニットテスト実践:Jest + React Testing Library 完全設定ガイド


コメント
GitHubアカウントでログインしてコメントできます