言語を切り替える
テーマを切り替える

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 ls
NETWORK 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 veth

veth で始まるインターフェースが増えているはずです。次にコンテナの中を確認:

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モードの代償

速さの代償は以下の通りです:

  1. ポート競合の地獄:ホスト上で既に80番を使っていたら起動できません。同じコンテナを複数起動することも(ポートを変える設定をしない限り)不可能です。
  2. セキュリティリスク:コンテナからホストの全ネットワーク通信が見えてしまいます。
  3. 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 sh

2つ目のコンテナ(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/CIBridgeビルドごとに環境を隔離したい。
ネットワーク監視AgentHostホストのトラフィックを見る必要があるため。
K8s Pod内のSidecarContainerメインアプリとlocalhostで通信するため。

まとめ

長くなりましたが、持ち帰ってほしいのは以下の3点です:

  1. 基本は「カスタムBridge」docker network create して使う。これが現代のベストプラクティスです。デフォルトBridgeはDNSが効かないので避けましょう。
  2. Hostモードは「切り札」:性能問題で詰んだ時だけ出すカードです。常用するものではありません(特にMac/Winユーザーは注意)。
  3. トラブル時はモード確認:繋がらない時は、まず docker network lsdocker inspect で、コンテナが正しいネットワークに属しているか確認しましょう。

ネットワークはDockerの鬼門ですが、この「モードの使い分け」さえ理解していれば、8割のトラブルは回避できます。さあ、今すぐ docker network create して、快適なコンテナライフを!

Dockerネットワークモード選択ガイド

bridge, host, none, containerの4つのモードから最適なネットワーク構成を選ぶための手順

⏱️ Estimated time: 5 min

  1. 1

    Step1: 要件の確認

    アプリケーションに「極限のネットワーク性能」が必要か、それとも「管理のしやすさと隔離」が重要かを判断します。
  2. 2

    Step2: モードの選択

    通常は`bridge`を選択します。コンテナ間で通信する場合は必ず`docker network create`で作成したカスタムブリッジを使用します。ホストのネットワーク情報を直接扱う監視ツール等の場合は`host`を選択します。
  3. 3

    Step3: 設定と実行

    Bridgeの場合:`docker run --network my-net -p 8080:80 ...`
    Hostの場合:`docker run --network host ...`
    を設定して起動します。

FAQ

BridgeモードとHostモードの主な違いは何ですか?
Bridgeモードは仮想ネットワークを作り、NAT経由で外部と通信します(隔離性高、ポート変換あり)。Hostモードはホストマシンのネットワークを直接使います(隔離性低、ポート変換なし、性能高)。
なぜデフォルトのbridgeネットワークを使ってはいけないのですか?
デフォルトのbridgeネットワークでは、コンテナ名によるDNS解決(サービスディスカバリ)機能が無効だからです。コンテナ同士が通信するにはIPアドレスを直接指定する必要があり、管理が困難になります。
Mac/WindowsでHostモードが機能しないのはなぜですか?
Docker Desktop for Mac/Windowsは、Linux VM(仮想マシン)の中でDockerを動かしています。Hostモードにしても「VMのネットワーク」を共有するだけで、あなたのPC(ホストOS)のネットワークには直接繋がりません。これがLinux環境との大きな違いです。

4 min read · 公開日: 2025年12月17日 · 更新日: 2026年1月22日

コメント

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

関連記事