2026年8月6日
2026年8月6日
Dockerのネットワークモード6種(bridge・host・none・overlay・macvlan・ipvlan)の違いと選び方
Dockerのネットワークは、迷ったら「ユーザー定義のbridge」を選ぶのが基本です。host・none・overlay・macvlan・ipvlanは、性能や隔離、複数ホスト連携、LANへの直結といった特定の理由があるときに使い分けます。この記事では6つのドライバーの仕組みと向き不向き、作成コマンド、つまずきやすい点と確認方法までをまとめます(2026年10月現在の Linux 版 Docker Engine の挙動を前提にしています)。
まず全体像:ネットワークドライバーとは
Dockerでは、コンテナがどのネットワークにつながるかを「ネットワーク」というオブジェクトで管理し、その種類を決めるのが「ドライバー」です。インストール直後に docker network ls を実行すると、bridge・host・none の3つが最初から用意されているのが分かります。
docker network ls
# NETWORK ID NAME DRIVER SCOPE
# 1a2b3c4d5e6f bridge bridge local
# 7a8b9c0d1e2f host host local
# 3a4b5c6d7e8f none null local
SCOPE が local のものは1台のホストの中だけで有効です。overlay は swarm スコープになり、複数ホストにまたがります。
| ドライバー | 通信の範囲 | 主な用途 |
|---|---|---|
| bridge | 同一ホスト内(外部へはNAT) | 一般的なWeb・DB構成 |
| host | ホストのネットワークをそのまま共有 | ポート変換を避けたい監視・高負荷処理 |
| none | ループバックのみ | 通信させないバッチ処理 |
| overlay | 複数ホスト間 | Docker Swarm |
| macvlan | 物理LANに独自MACで直結 | LAN上の1台の機器として見せたい場合 |
| ipvlan | 物理LANに親のMACを共有して直結 | MAC数に制限がある環境 |
bridge:デフォルトとユーザー定義の違いが重要
bridge は、ホスト上に仮想スイッチ(Linuxブリッジ)を作り、コンテナをそこにつなぐ方式です。コンテナはプライベートIP(多くは172.17.0.0/16など)を持ち、外部へはホストのIPでNAT(IPマスカレード)されて出ていきます。外から受けるときは -p でポートを公開します。
ここで多くの人がつまずくのが、**最初からある bridge(docker0)と、自分で作ったbridgeネットワークでは挙動が違う**という点です。ユーザー定義のbridgeでは、Docker内蔵のDNS(コンテナ内から見ると 127.0.0.11)が働き、コンテナ名やサービス名で相手を引けます。デフォルトのbridgeではこの名前解決が効かないため、db という名前で接続しようとして失敗します。
# ユーザー定義bridgeを作り、2つのコンテナを参加させる
docker network create appnet
docker run -d --name db --network appnet -e MYSQL_ROOT_PASSWORD=change-me mysql:8.4
docker run -d --name web --network appnet -p 8080:80 nginx:stable
# web から db を名前で引けるか確認
docker exec web getent hosts db
Docker Compose は、プロジェクトごとに <プロジェクト名>_default というユーザー定義bridgeを自動で作るため、サービス名での接続がそのまま使えます。
ポート公開にはもう一つ注意点があります。-p 8080:80 は既定で全インターフェース(0.0.0.0)に公開され、DockerがiptablesやnftablesのDOCKERチェーンにルールを直接追加するため、ufw で閉じたつもりでも外部から届くことがあります。管理画面やDBなど外に出したくないものは -p 127.0.0.1:8080:80 のように待ち受けアドレスを指定し、前段のリバースプロキシ経由で公開する形が安全です。
host:ポート変換なし、ただし隔離も弱くなる
host を指定すると、コンテナはネットワーク名前空間を持たず、ホストのネットワークをそのまま使います。コンテナ内でポート80を開けば、ホストのポート80で直接待ち受けます。NATを通らないぶんオーバーヘッドが小さく、多数のポートを使うアプリや、ホストのインターフェース情報を見たい監視エージェントに向いています。
docker run -d --name web-host --network host nginx:stable
ss -tlnp | grep ':80 '
代わりに、ホスト上の他のプロセスとポートが衝突しやすく、ネットワーク面の隔離もなくなります。また host モードでは -p は意味を持たず、指定しても警告が出て無視されます。
Docker Desktop(Mac・Windows)での注意:Docker Desktop はコンテナを内部のLinux仮想マシンで動かしています。そのため従来、host モードの「ホスト」はこの仮想マシンを指し、Mac や Windows 本体のポートで直接待ち受けることはできませんでした。新しいバージョンでは設定画面から host ネットワークを有効にできる機能が追加されていますが、対応範囲や制約はバージョンによって異なります。Linuxサーバーと同じ挙動を前提にせず、手元では bridge と -p で検証しておくと本番との差が出にくくなります。
none:ネットワークを持たせない
none はループバック(lo)だけを持ち、外部とも他のコンテナとも通信できません。外部と通信する必要のない変換処理や、信頼できない入力を扱うバッチを閉じ込めたいときに使います。
docker run --rm --network none alpine ip addr
# lo だけが表示される
データの受け渡しはボリュームやバインドマウントで行います。「通信できないこと」自体が要件のときに選ぶドライバーです。
overlay:複数ホストをまたぐ仮想ネットワーク
overlay は、複数のDockerホストの上に1つの仮想ネットワークを作り、別ホストのコンテナ同士を同じセグメントにいるかのように通信させます。内部ではVXLANでパケットをカプセル化しています。利用には Docker Swarm の初期化が前提です。
# マネージャーノードで
docker swarm init --advertise-addr 192.0.2.10
# 通常のコンテナからも参加できるよう --attachable を付ける
docker network create -d overlay --attachable app-overlay
ノード間では、クラスター管理用のTCP 2377、ノード間通信用のTCP/UDP 7946、VXLAN用のUDP 4789 が通る必要があります。ファイアウォールやクラウドのセキュリティグループでこれらを閉じていると「ネットワークは作れたのに別ホストのコンテナに届かない」状態になります。VXLANのトラフィックは既定では暗号化されないため、経路が信頼できない場合は --opt encrypted を検討します。なお、Kubernetes を使う場合はこの overlay ではなく、Kubernetes 側のCNIプラグインがネットワークを担当します。
macvlan:コンテナをLAN上の1台として見せる
macvlan は、コンテナに独自のMACアドレスを割り当て、物理LANに直接参加させます。ルーターや他のPCからは、コンテナが独立した1台の機器に見えます。LAN内の固定IPで動くことを前提にした古いアプリや、ネットワーク監視ツールをコンテナ化するときに使われます。
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
--ip-range=192.168.1.192/27 \
-o parent=eth0 \
lan-macvlan
docker run -d --name app --network lan-macvlan --ip 192.168.1.200 nginx:stable
つまずきやすい点が3つあります。1つ目は、既定ではホスト自身からmacvlanのコンテナに通信できないことです。ホストから触りたい場合は、ホスト側にもmacvlanのサブインターフェースを作ってルートを通す必要があります。2つ目は、DHCPサーバーとアドレスが重ならないよう --ip-range で範囲を分けることです。3つ目は、多くのクラウドVPSやWi-Fi環境では、登録されていないMACアドレスのパケットが破棄されるため動かないことです。macvlan は基本的に、自分で管理できる有線LANや仮想化基盤向けと考えてください。
ipvlan:MACアドレスを増やさずにLANへ直結
ipvlan は macvlan とよく似ていますが、すべてのコンテナが親インターフェースと同じMACアドレスを共有し、IPアドレスだけで区別します。スイッチのポートあたりのMAC数に制限がある環境や、MACの追加を嫌う仮想化基盤で有効です。
# L2モード(既定):親と同じセグメントに参加
docker network create -d ipvlan \
--subnet=192.168.1.0/24 --gateway=192.168.1.1 \
-o parent=eth0 -o ipvlan_mode=l2 \
lan-ipvlan
ipvlan_mode=l3 にすると、ホストがルーターのように振る舞い、コンテナ用に別のサブネットを切れます。この場合は上流のルーターに、そのサブネットへの経路を追加する必要があります。同じMACを共有するため、MACアドレスでIPを割り当てるDHCPとは相性がよくない点も覚えておくと安心です。
状態を確認するコマンド
設定したつもりでも通信できないときは、次の順で確認すると原因を絞り込めます。
# ネットワークの設定と、参加しているコンテナ
docker network inspect appnet
# コンテナがどのネットワークにいるか
docker inspect -f '{{json .NetworkSettings.Networks}}' web
# 実行中のコンテナを別ネットワークにも参加させる
docker network connect backend web
# 使われていないネットワークを掃除(使用中のものは消えない)
docker network prune
inspect で Subnet・Gateway・接続中コンテナのIPを見て、想定と食い違っていないかを確かめます。名前解決の問題であれば、同じユーザー定義ネットワークに両方が参加しているかが最初の確認ポイントです。
どれを選ぶかの目安
- 1台のサーバーでWordPressとDBなどを動かす:ユーザー定義bridge(Composeの既定でよい)
- ポート変換を挟みたくない監視エージェント、大量のポートを使うアプリ:host
- 外部通信を禁止したい処理:none
- 複数サーバーでSwarmを組む:overlay
- 物理LAN上の独立した機器として見せたい:macvlan(MAC制限があるならipvlan)
まとめ
- Dockerのネットワークはドライバーで性格が決まり、迷ったらユーザー定義bridgeを選ぶ
- デフォルトのbridgeではコンテナ名で名前解決できない。自分でネットワークを作るかComposeを使う
-pの公開は既定で0.0.0.0になり、ufwを素通りすることがある。必要なら127.0.0.1に絞る- host は高速だが隔離が弱く、Docker Desktopでは「ホスト」の意味がLinuxと異なる
- overlay はSwarm前提で、2377・7946・4789番の開放が必要
- macvlan・ipvlan はLAN直結用。ホストからの到達性やクラウドでの制約を事前に確認する