Dockerネットワークモード完全解説:bridge/host/none/containerの4モード性能比較と使い分け
ターミナルに緑色の「Container started」が表示され、サービスは起動しているはずなのに、curlはタイムアウトのまま。docker logsを3回見てもエラーは出ない。-p 8080:80のポートマッピングも設定済み、ルーティングも問題なし、ファイアウォールもオフ。一体どこがおかしいのでしょうか?
原因はネットワークモードの選択ミスでした。docker run -pさえすれば十分だと思っていたのに、Dockerにはbridge、host、none、containerの4つのネットワークモードがあることを知りませんでした。
「コンテナは起動したのにアクセスできない」という経験がある方、あるいはDockerのネットワーク設定に自信がない方に向けて、本記事では4つのネットワークモードの違い、仕組み、使い分けをわかりやすく解説します。複雑な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、172.17.0.3のように。
Dockerのネットワーク一覧も確認してみましょう:
docker network ls
NETWORK ID NAME DRIVER SCOPE
7f8a2b3c9d4e bridge bridge local
このデフォルトのbridgeネットワークは、下層でdocker0ブリッジを使っています。
veth pair:コンテナをつなぐ「トランシーバー」
docker0だけでは不十分です。コンテナはそれぞれ独立した「部屋」(ネットワーク名前空間)にいるのに、どうやってdocker0と通信するのでしょうか?
答えはveth pairです。一対のトランシーバーのようなもので、片方はコンテナ内のeth0、もう片方はホスト上のvethXXX(例:veth9a7b4c)として存在し、両端が直接通信します。
コンテナを起動してみましょう:
docker run -d --name test-nginx nginx
ホスト上のNICを確認します:
ip addr | grep veth
vethで始まるデバイスが増えているはずです。コンテナ内も見てみましょう:
docker exec test-nginx ip addr
コンテナ内にはeth0インターフェースがあり、IPは172.17.0.2です。このeth0とホスト上のvethXXXは一対になっており、eth0から出たパケットは瞬時にvethXXXに届き、docker0を経由して、ホストのNIC(eth0やens33など)から外部ネットワークへ出ていきます。
通信経路は次のとおりです:
コンテナ内部(172.17.0.2)
↓ eth0
↓ (veth pair)
↓ vethXXX
↓
docker0ブリッジ(172.17.0.1)
↓ NAT転送
↓
ホストNIC(例:192.168.1.100)
↓
インターネット
少し回りくどく見えますが、実際の動作は非常に高速です。コンテナのIPにpingを打てば、レイテンシはだいたい0.数ミリ秒です。
正直、veth pairを初めて見たときはしばらく理解できませんでした。要するに仮想LANケーブルで、片端をコンテナ、もう片端をdocker0に差すだけ——そう考えるとシンプルです。
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でアクセスでき、裏側ではDockerがNATポート転送を行っています。
docker inspect web1でネットワーク設定を確認してみましょう:
"Networks": {
"bridge": {
"IPAddress": "172.17.0.2",
"Gateway": "172.17.0.1"
}
}
ご覧のとおり、コンテナは172.17.0.2というプライベートIPを取得し、ゲートウェイはdocker0の172.17.0.1です。
デフォルトbridge vs カスタムbridge:決定的な違い
ここに落とし穴があります。デフォルトのbridgeネットワーク(docker0)では、コンテナ間はIPアドレスでのみ通信でき、コンテナ名による名前解決はサポートされません。
試してみましょう:
docker run -d --name db mysql
docker run -it --name app alpine ping db
pingは通りません。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
今度は通ります。カスタムbridgeネットワークにはDNS解決機能が組み込まれており、コンテナ名をそのままホスト名として使えます。
これが本番環境ではデフォルトdocker0ではなくカスタムネットワークを推奨する理由です。サービスディスカバリが格段に楽になり、IPを固定する必要がなくなります。
-pオプションの裏側:NAT転送
-p 8080:80を使うと、DockerはホストのiptablesにNATルールを追加します:
iptables -t nat -L -n | grep 8080
次のような出力が見えます:
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
これは、ホストの8080番ポート宛てのトラフィックをすべてコンテナの172.17.0.2:80に転送する、という意味です。
外部からhttp://ホストIP:8080でコンテナ内のサービスにアクセスできるのは、Dockerがアドレス変換を代行してくれているからです。
Bridgeモードの適用シナリオ
結局、bridgeモードは次のようなシナリオに向いています:
- マイクロサービスアーキテクチャ:複数コンテナが協調動作し、隔離しつつ相互通信が必要(カスタムbridgeネットワークを使用)
- 開発環境:素早くサービスを立ち上げてテスト、デフォルトbridgeで十分
- ポートマッピングが必要なWebアプリ:ブログやAPIサービスなど
性能面では、bridgeモードにはNATとveth pairのオーバーヘッドがあります。ただし正直なところ、大多数のアプリケーションではこの損失は無視できます。本当に性能のボトルネックになるケースは多くありません。最初から心配しすぎる必要はありません。
Hostモード——「性能最優先」の選択
Hostモードとは?ネットワーク隔離なしの「直結」
Hostモードは最もシンプルで大胆です。コンテナに独立したネットワークを持たせず、ホストのネットワークスタックをそのまま共有します。
起動時に--net=hostを付けます:
docker run -d --net=host --name web nginx
このときコンテナには独立したIPもeth0もありません。ホストのネットワークインターフェースを直接共有します。コンテナ内でip addrを実行すると、ホスト上の出力とまったく同じ内容が表示されます。
さらに重要なのは、-pによるポートマッピングが不要になることです。コンテナ内のサービスが80番ポートをリッスンすれば、外部からホストIP:80で直接アクセスできます。
性能上のメリットはどこにある?
Hostモードはdocker0ブリッジとveth pairをスキップし、NAT転送も不要です。パケットはホストNICから直接出入りし、ホスト上でプロセスを動かしているのとほぼ同じ状態になります。
ベンチマークによると、高並行シナリオではhostモードがbridgeモードより5〜10%ほど高速です。一見わずかに見えますが、高頻度取引やリアルタイムゲームサーバーなど、レイテンシに極端に敏感なアプリケーションでは、この差が意味を持ちます。
以前、Nginxをリバースプロキシとして使い、毎秒数万リクエストを処理する案件がありました。hostモードに切り替えたところ、P99レイテンシが12msから9msに下がりました。3ミリ秒の差ですが、そのプロジェクトにとっては相当な価値がありました。
Hostモードの落とし穴と代償
性能は上がりますが、落とし穴も少なくありません:
落とし穴1:ポート競合
ホストのポートを直接使用するため、同じポートをリッスンする複数コンテナを起動するとエラーになります:
docker run -d --net=host nginx # 80番をリッスン
docker run -d --net=host nginx # また80番、エラー:Address already in use
ホスト上で2つのNginxを直接起動するのと同じです。複数インスタンスを動かしたいなら、コンテナ内のリッスンポートを変えるか、hostモードを使わないでください。
落とし穴2:コンテナ内サービスは0.0.0.0をリッスンする必要がある
コンテナ内のサービスが127.0.0.1だけをリッスンしていると、外部からアクセスできません。0.0.0.0をリッスンする必要があります。
あるとき、Node.jsサービスをhostモードで起動したのに、コードがapp.listen(3000, 'localhost')になっていて、外部から接続できませんでした。app.listen(3000, '0.0.0.0')に変更して解決しました。
落とし穴3:ネットワーク隔離の喪失
コンテナからホストのすべてのネットワークリソースに直接アクセスできます。セキュリティリスクが高く、信頼できないサードパーティコードを動かす場合はhostモードは避けるべきです。
Hostモードはいつ使う?
正直なところ、本当に性能ボトルネックに直面したときだけhostモードを検討してください。大多数のシナリオでは、bridgeモードのオーバーヘッドは問題になりません。
Hostモードが向いているシナリオ:
- 監視ツール:Prometheus、Grafana、ELKなど、ホストのネットワークリソースに直接アクセスが必要
- 高性能プロキシ:Nginx、HAProxyによるロードバランシングで、極限のレイテンシを追求
- データベース:MySQL、Redisなどネットワーク性能に敏感なサービス(ただしセキュリティは要評価)
アプリケーションのリクエスト量が毎秒数千以内なら、hostモードにわざわざ切り替える必要はありません。bridgeで十分です。
NoneとContainerモード——「特殊シナリオ専用」
Noneモード:完全にネットワークを切断したサンドボックス
Noneモードは文字どおり、コンテナにネットワークがありません。
docker run -it --net=none alpine sh
コンテナ内でip addrを実行すると、loopbackインターフェース(lo)しか見えません。外部ネットワークにも接続できず、他のコンテナからもアクセスできません。
Noneモードはいつ使う?
正直、実務ではnoneモードを使ったことがほとんどありません。用途は非常に限定的です:
- セキュリティテスト:信頼できないコードを実行し、ネットワークを完全隔離してデータ漏洩を防ぐ
- オフラインのデータ処理:コンテナはローカル計算のみ行い、ネットワーク通信が不要
- 手動ネットワーク設定:ごく稀に、pipeworkなどのツールでvethを手動設定する必要がある場合
セキュリティ研究や特殊なネットワーク構成が必要な場合を除き、基本的に使う機会はありません。
Containerモード:2つのコンテナが「ネットワークを共有」
Containerモードは、あるコンテナが別のコンテナのネットワーク名前空間を使います。言葉だけだとわかりにくいので、例を見てみましょう:
# 最初のコンテナを起動
docker run -d --name web nginx
# 2つ目のコンテナがwebのネットワークを共有
docker run -it --net=container:web alpine sh
2つのコンテナは同じネットワーク設定を共有します。IPアドレス、ポート空間、NIC設定がすべて同一です。2つ目のコンテナ内からlocalhost:80でnginxにアクセスできます。
Containerモードの典型例:KubernetesのPod
KubernetesのPodは、実はcontainerモードで実装されています。1つのPod内に複数コンテナがあり、それらは「pause」コンテナのネットワークを共有します。
例えば、Pod内でアプリケーションコンテナとログ収集用のsidecarコンテナが動いている場合、両者はlocalhost経由で通信でき、外部にポートを公開する必要がありません。
ただし、KubernetesではなくDocker単体を使う場合、containerモードを使う機会は多くありません。bridgeモード+カスタムネットワークでもコンテナ間通信は実現でき、より柔軟です。
この2モードの位置づけ
結局、noneとcontainerは「日常の選択肢」というより「下層の能力」に近いものです。特殊シナリオ向けの柔軟性を提供しますが、80%のケースでは不要です。
覚えておくポイント:
- Noneモード:ネットワークを完全隔離したいとき(非常に稀)
- Containerモード:Kubernetesなどのオーケストレーションツールでよく見る。Docker単体ではあまり使わない
実践的な意思決定:適切なネットワークモードの選び方
意思決定フローチャート
具体的なプロジェクトでどのモードを選ぶべきか?シンプルな意思決定フローをまとめました:
ネットワーク隔離は必要?
│
├─ No → 性能ボトルネックはある?
│ │
│ ├─ Yes → Hostモード(セキュリティリスクに注意)
│ └─ No → Bridgeモード(より安全)
│
└─ Yes → コンテナ名での通信が必要?
│
├─ Yes → カスタムBridgeネットワーク
└─ No → デフォルトBridgeネットワーク
特殊シナリオ:
- ネットワークがまったく不要 → Noneモード
- Kubernetes Pod内のコンテナ → Containerモード
シナリオ別おすすめ早見表
| シナリオ | 推奨モード | 理由 |
|---|---|---|
| マイクロサービス(複数コンテナ協調) | カスタムbridge | コンテナ名解決に対応、隔離性も良好 |
| 単一Webアプリ | デフォルトbridge | シンプルで十分、1コマンドで起動可能 |
| 高性能DB/キャッシュ | Host | ネットワークオーバーヘッドを削減(セキュリティ要評価) |
| 監視ツール(Prometheus/ELK) | Host | ホストリソースへの直接アクセスが必要 |
| ロードバランサー(Nginx/HAProxy) | Host | 極限のレイテンシを追求 |
| 開発・テスト環境 | デフォルトbridge | 素早く起動、複雑な設定不要 |
| K8s Pod内のsidecarコンテナ | Container | メインコンテナとネットワーク共有 |
| セキュリティサンドボックス/オフラインタスク | None | ネットワークを完全隔離 |
3つのよくある誤解
誤解1:「Hostモードが常に最善」
違います。Hostモードは隔離性と柔軟性を犠牲にして得る性能向上は、多くのシナリオでは無視できるレベルです。
すべてのコンテナをhostモードで動かしている人を見たことがあります。ポート競合やセキュリティ問題が山積みになり、性能は確かに少し上がりましたが、運用コストは10倍になっていました。
真実:80%のアプリケーションはbridgeモードで十分。「性能が良い」という言葉に惑わされないでください。
誤解2:「デフォルトbridgeで十分」
本番環境では推奨されません。デフォルトbridgeはコンテナ名解決をサポートしないため、複数サービス間の通信でIPを固定するか、環境変数でIPを渡す必要があり、非常に脆い構成になります。
カスタムbridgeネットワークの作成は簡単です:
docker network create mynet
# docker-compose.yml で network を指定
真実:2分かけてカスタムネットワークを設定すれば、何時間ものトラブルシュートを省けます。
誤解3:「コンテナのネットワーク問題はすべてモード選択ミス」
必ずしもそうではありません。多くの場合、ファイアウォール、iptables設定、DNSの問題です。
トラブルシュート手順:
- コンテナ内からゲートウェイ(docker0のIP)にpingできるか確認
- 次にホストの外部IPにpingできるか確認
- iptablesルールにDROPがないか確認
- Docker daemonの設定(/etc/docker/daemon.json)を確認
真実:モード選択は第一歩にすぎません。ネットワーク問題は体系的に切り分ける必要があります。
応用テクニック
テクニック1:1つのコンテナを複数ネットワークに参加させる
フロントエンドネットワークとバックエンドネットワークの両方に接続したい場合:
docker network create frontend
docker network create backend
docker run -d --name web --network frontend nginx
docker network connect backend web
webコンテナはfrontendとbackendの両方のネットワークに同時に参加します。
テクニック2:IP割り当てを精密に制御
カスタムネットワーク作成時にサブネットとゲートウェイを指定できます:
docker network create \
--driver bridge \
--subnet 192.168.10.0/24 \
--gateway 192.168.10.1 \
mynet
docker run -d --network mynet --ip 192.168.10.100 nginx
固定IPが必要なシナリオ(ファイアウォールのホワイトリストなど)で有用です。
テクニック3:ネットワーク問題の切り分けに使えるツール
コンテナ内でのネットワークトラブルシュートに便利なコマンド:
# ネットワークツールをインストール
docker exec -it <container> apk add curl netcat-openbsd
# 接続テスト
docker exec <container> nc -zv <host> <port>
# ルーティングテーブル確認
docker exec <container> ip route
# パケットキャプチャ(ホスト権限が必要)
docker exec <container> tcpdump -i eth0
まとめ
ここまで4つのネットワークモードを見てきました。要点をおさらいします:
- Bridgeモード:デフォルト選択。大多数のシナリオに適し、本番ではカスタムbridgeネットワークを推奨
- Hostモード:性能優先だが隔離性を犠牲にする。本当にボトルネックがあるときだけ
- Noneモード:完全にネットワークを切断。ほとんど使わない
- Containerモード:ネットワーク共有。主にKubernetesで使われる
覚えておいてほしいのは、「最善のモード」はなく、「最適なモード」があるということです。
Dockerを始めたばかりなら、デフォルトbridgeから始めましょう。具体的な問題が出たら調整します。サービスディスカバリが面倒ならカスタムbridgeに切り替え、性能が本当に足りなければhostを検討。最初からどのモードが「最適」か悩む必要はありません。
カスタムネットワークを作成し、いくつかコンテナを起動して、コンテナ名で相互アクセスできるか試してみてください。実際に動かす方が、10記事読むより理解が深まります。
実プロジェクトでDockerのネットワーク問題に直面したら、ぜひコメントで共有してください。この分野は奥が深いですが、ここで紹介した基本概念を押さえておけば、80%の問題は自分で解決できるはずです。
Dockerネットワークモード選択完全ガイド
bridge/host/none/containerの4モードの仕組み、性能比較、適用シナリオを深掘り解説
⏱️ 目安時間: 30 分
- 1
ステップ1: 4つのネットワークモードを理解する
4つのネットワークモード:
bridge(デフォルト)
• docker0ブリッジ経由で通信、ポートマッピングが必要
• 大多数のシナリオに適し、hostより性能はやや劣るがセキュリティは高い
hostモード
• ホストのネットワークを直接使用、ポートマッピング不要
• 性能最高(ネイティブに近い)だがセキュリティは低い(コンテナがホストネットワークに直接露出)
• 高性能シナリオ向け
noneモード
• ネットワークなし、完全隔離
containerモード
• 他コンテナのネットワーク名前空間を共有 - 2
ステップ2: 性能比較とシナリオ選択
性能比較:
• hostモードが最高(ネイティブに近い)
• bridgeモードはやや劣る(NATオーバーヘッドあり)
• containerモードは共有先コンテナ次第
• noneモードはネットワークなし
シナリオ選択:
• 大多数のケースはbridgeモード(デフォルト、安全、ポートマッピング必要)
• 高性能要件はhostモード(性能最高だがセキュリティ低)
• 完全隔離はnoneモード(ネットワークなし、完全隔離)
• コンテナ間でネットワーク共有はcontainerモード(他コンテナのネットワーク名前空間を共有) - 3
ステップ3: 実践設定とベストプラクティス
bridgeモードの設定:
• docker run -d -p 8080:80 nginx(デフォルトbridge、ポートマッピング)
• カスタムネットワーク作成:docker network create my-network
• カスタムネットワーク使用:docker run --network my-network
hostモードの設定:
• docker run --network host nginx(ホストネットワークを直接使用)
ベストプラクティス:
• Dockerを始めたばかりなら、デフォルトbridgeから始めれば十分
• 具体的な問題が出たら調整する
• サービスディスカバリが面倒ならカスタムbridgeに切り替える
• 性能が本当に足りなければhostを検討
• 最初からどのモードが「最適」か悩まない
FAQ
Dockerには4つのネットワークモードがある?それぞれの特徴は?
bridge(デフォルト):
• docker0ブリッジ経由で通信、ポートマッピングが必要
• 大多数のシナリオに適し、hostより性能はやや劣るがセキュリティは高い
hostモード:
• ホストのネットワークを直接使用、ポートマッピング不要
• 性能最高(ネイティブに近い)だがセキュリティは低い(コンテナがホストネットワークに直接露出)
• 高性能シナリオ向け
noneモード:
• ネットワークなし、完全隔離
containerモード:
• 他コンテナのネットワーク名前空間を共有
bridgeモードとhostモードの違いは?
• デフォルトモード、コンテナはdocker0ブリッジ経由で通信
• -pオプションでポートマッピングが必要
• 大多数のシナリオに適し、hostより性能はやや劣るがセキュリティは高い
hostモード:
• ホストのネットワークを直接使用、ポートマッピング不要
• 性能最高(ネイティブに近い)
• ただしセキュリティは低い(コンテナがホストネットワークに直接露出)
• 高性能シナリオ向け
性能比較:hostモードが最高(ネイティブに近い)、bridgeモードはやや劣る(NATオーバーヘッドあり)。
適切なネットワークモードの選び方は?
• 大多数のケースはbridgeモード(デフォルト、安全、ポートマッピング必要)
• 高性能要件はhostモード(性能最高だがセキュリティ低)
• 完全隔離はnoneモード(ネットワークなし、完全隔離)
• コンテナ間でネットワーク共有はcontainerモード(他コンテナのネットワーク名前空間を共有)
ベストプラクティス:
• Dockerを始めたばかりなら、デフォルトbridgeから始めれば十分
• 具体的な問題が出たら調整する
• サービスディスカバリが面倒ならカスタムbridgeに切り替える
• 性能が本当に足りなければhostを検討
• 最初からどのモードが「最適」か悩まない
5分で読めます · 公開日: 2025年12月17日 · 更新日: 2026年6月8日
Docker 実践ガイド
検索からこのページに来た場合は、前後の記事もあわせて読むと同じテーマの理解がかなり早く深まります。
前の記事
Dockerマウントディレクトリの権限問題完全解決ガイド:診断から実践まで5つの解決策
コンテナで生成されたファイルが削除できない?Permission Deniedが頻発する?Docker権限問題の根本原因を徹底解説し、Linux/Mac/Windowsの違いを考慮した5つの解決策と5つのリアルなケーススタディを紹介。3つの診断コマンドで権限問題を完全に解決。
第 16 / 37 記事
次の記事
Docker コンテナ間通信の実践:Web と DB を名前でつなぐ正しい方法
Docker コンテナはどう相互アクセスする?カスタムネットワークでコンテナ名解決の失敗と IP 変動を解決し、Web と DB を安定接続。完全なコマンドとトラブルシューティング付き。
第 18 / 37 記事
関連記事
Dockerfile入門:ゼロから最初の Docker イメージを作る(実例付き)
Dockerfile入門:ゼロから最初の Docker イメージを作る(実例付き)
Docker vs 仮想マシン:5分で理解する性能差とシーン別選び方ガイド
Docker vs 仮想マシン:5分で理解する性能差とシーン別選び方ガイド
Docker インストールの落とし穴ガイド 2025:permission denied から正常起動までの完全解決策
コメント
GitHubアカウントでログインしてコメントできます