Docker 网络模式详解:bridge/host/none/container怎么选

一、容器A ping不通容器B,你遇到过吗?

刚上手 Docker 的时候,最让人困惑的往往不是 Dockerfile,而是网络。

“我的 nginx容器怎么访问不到 MySQL 容器?”
“为什么宿主机能访问 8080,但容器之间死活不通?”
“服务部署完了,跨容器通信全靠 --link 硬撑,加了新服务又得重启……”

这些都是 Docker 网络没搞清楚的典型症状。

Docker 提供了 4 种单机网络模式:bridge、host、none、container,外加一个升级方案——自定义 bridge 网络。每一种都对应不同的隔离级别和通信场景,用错了轻则多写配置,重则服务不通。

这篇文章用命令 + 原理 + 场景三管齐下的方式,一次讲透。

二、先搞懂底层:网络命名空间和 veth pair

Docker 网络的底层依赖 Linux 内核的 Network Namespaceveth pair,理解这两个概念,后面四种模式就是一层层叠加。

1.Network Namespace(网络命名空间)

每个 Docker 容器有自己独立的网络栈:网卡、IP 地址、路由表、iptables 规则,互不干扰。

# 查看容器内的网络栈
docker exec nginx ip addr

# 宿主机上可以查看所有 network namespace
ls /var/run/docker/netns/

2.veth pair(虚拟网线)

veth pair 是一对虚拟网卡,一端插在容器里(eth0),另一端插在宿主机的 docker0 网桥上。数据从一端进,另一端出,就像一根虚拟网线。

# 宿主机上查看 veth 设备
ip link show | grep veth

有了这个基础,四种模式的差异就很清晰了——本质上就是容器网络栈和宿主机网络栈之间建立关系的不同方式。

三、四种网络模式逐一拆解

1. Bridge(默认模式)

1.1 概述

Bridge 是 Docker 的默认模式。宿主机上建一个虚拟交换机 docker0,每个容器通过 veth pair 连上去,各自有独立 IP,docker run 不加 --network 就走这个模式。

1.2 基本用法
docker run -d --name web01 nginx:alpine
docker run -d --name web02 nginx:alpine

ip addr show docker0        # 172.17.0.1/16
docker inspect web01 --format '{{.NetworkSettings.IPAddress}}'  # 172.17.0.2
docker inspect web02 --format '{{.NetworkSettings.IPAddress}}'  # 172.17.0.3

1.3 特性
特性 说明
容器间通信 ✅ 通过 IP 互通(172.17.0.0/16)
容器→外网 ✅ NAT(MASQUERADE)
外网→容器 ✅ 需要 -p 端口映射
DNS 解析 ❌ 不支持容器名解析
适用场景 开发环境、单容器测试
1.4 NAT 数据路径

Bridge 的核心是 NAT,分两个方向:

容器 → 外网(SNAT)

容器 IP 是 172.17.0.x,私有地址公网不认识。数据包经过宿主机路由时,宿主机做一次 SNAT,把源 IP 换成宿主机公网 IP。这条规则叫 MASQUERADE——动态 SNAT,宿主机换 IP 也不会断。

iptables -t nat -L POSTROUTING -n | grep MASQUERADE
# MASQUERADE  all  --  172.17.0.0/16  0.0.0.0/0
容器(172.17.0.2) → veth → docker0 → SNAT → ens32 → 公网

外网 → 容器(DNAT)

公网请求 宿主机IP:8080,通过 -p 8080:80 做 DNAT:宿主机把目标地址从 宿主机IP:8080 改写为 容器IP:80,再转发进去。

docker run -d -p 8080:80 nginx:alpine
iptables -t nat -L DOCKER -n | grep 8080
# DNAT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:8080 to:172.17.0.4:80
公网 → ens32:8080 → DNAT → docker0 → veth → 容器:80

1.5 常见的 -p 写法
写法 含义
-p 8080:80 所有网卡映射
-p 127.0.0.1:8080:80 仅本地回环
-p 8080:80/udp 指定 UDP
-p 8080-8090:80 端口范围
1.6 默认 bridge 的坑

容器之间只能用 IP 互访,不能用容器名。新加容器后旧容器不会自动感知。所以生产环境不推荐用默认 bridge。

2. Host 模式

2.1 概述

容器直接"借用"宿主机的网络栈,没有独立 IP,没有 NAT,性能和宿主机一样。

2.2 基本用法
docker run -d --network host --name web nginx:alpine

启动后,容器的 80 端口直接绑定在宿主机的 80 端口上。

2.3 特性
特性 说明
容器间通信 ✅ 同宿主机,无隔离
容器→外网 ✅ 直通,零损耗
外网→容器 ✅ 无需 -p,端口直接暴露
端口冲突 ⚠️ 容易冲突,多实例不能用同一端口
适用场景 高性能网络需求、监控 agent(如 Prometheus node_exporter)
2.4 适用场景

Host 模式本质上是放弃了网络隔离。适合对网络性能要求极高、且不担心端口冲突的场景。

3. None 模式

3.1 概述

容器有独立的网络命名空间,但里面什么都没有——没有网卡,没有 IP,完全与世隔绝。

3.2 基本用法
docker run -d --network none --name isolated busybox sleep 3600

# 容器内看网络
docker exec isolated ip addr
# 输出:只有 lo 回环接口,没有 eth0

3.3 特性
特性 说明
容器间通信 ❌ 完全不通
容器→外网 ❌ 不通
外网→容器 ❌ 不通
适用场景 安全沙箱、不需要网络的批处理任务、手动配置网络的特殊场景
3.4 适用场景

None 模式适合"我只要一个隔离的计算环境,不需要网络"的情况。也可以作为手动配置网络的起点——先 --network none,再用 ip netns 自己建网络。

4. Container 模式

4.1 概述

新容器直接"共享"另一个容器的网络栈,两个容器用同一个 IP,通过 localhost 互通。

4.2 基本用法
# 先启动一个容器(bridge 模式)
docker run -d --name main -p 8080:80 nginx

# 第二个容器共享 main 的网络栈
docker run -d --name sidecar --network container:main alpine:3.19 sleep 3600

# 在 sidecar 容器里 curl localhost:80,访问的是 main 容器的 nginx
docker exec sidecar wget -qO- http://localhost:80

4.3 特性
特性 说明
容器间通信 ✅ 通过 localhost,不需要跨网络
端口 共享,同一端口不能重复监听
网络隔离 ❌ 两个容器网络完全共享
适用场景 Sidecar 模式(如 Istio envoy)、需要 localhost 通信的容器对
4.4 适用场景

Container 模式天然适合 Sidecar 架构。比如主容器跑业务,Sidecar 容器跑代理/日志收集,它们通过 localhost 通信,延迟最低,配置最简单。

5. 四种模式一图对比

维度 Bridge Host None Container
独立 IP ❌ 共用宿主机 ❌ 无 ❌ 共享主容器
端口映射 需要 -p 无需 -p 无端口 共享主容器端口
容器名 DNS N/A N/A N/A
网络性能 有 NAT 损耗 原生 N/A 原生(localhost)
隔离性
典型场景 开发单机 监控 agent 安全沙箱 Sidecar

四、自定义 bridge 网络:生产环境的标配

默认 bridge 不支持容器名 DNS 解析,自定义 bridge 解决的就是这个。

1.创建自定义网络

# 创建自定义网络
docker network create --driver bridge mynet

# 查看
docker network ls
# NETWORK ID     NAME      DRIVER    SCOPE
# abc123def456   mynet     bridge    local

2.容器加入自定义网络

# 把容器加入自定义网络
docker run -d --name web --network mynet nginx:alpine
docker run -d --name app --network mynet myapp:v0.1

# 在 app 容器内直接用容器名 ping 通 db
docker exec app ping web
# PING db (172.18.0.2): 56 data bytes — 通了!

3.自定义 bridge 的三大优势

  1. DNS 自动解析:容器名 → IP,不用记 IP 地址
  2. 网络隔离:不同自定义网络之间默认不通,天然做环境隔离
  3. 热插拔:运行中的容器可以随时加入/退出网络

4.热插拔:运行中容器动态加入/退出网络

# 运行中的容器加入另一个网络
docker network connect mynet web01

# 容器退出网络
docker network disconnect mynet web01

五、生产环境选型速查

场景 推荐模式
普通 Web 应用(Nginx + App + DB) 自定义 bridge
监控 agent(Prometheus exporter) Host
Sidecar 模式(代理/日志收集) Container
安全沙箱/批处理任务 None
多容器需要容器名 DNS 互访 自定义 bridge(不要用默认 bridge)
单容器快速测试 默认 Bridge

一句话口诀:单机默认桥,多服务自定义桥,高性能用 Host,Sidecar 用 Container,安全隔离用 None。

六、总结

Docker 网络没有想象中复杂:bridge 是默认隔离网络,host 交出隔离换性能,none 完全封闭,container 实现共享。真正让 Docker 网络好用起来的,是自定义 bridge——DNS 解析 + 网络隔离 + 热插拔,生产环境必学。

落地清单

  • 把默认 bridge 的容器迁移到自定义 bridge,享受 DNS 解析
  • Docker Compose 项目天然用自定义 bridge,直接写服务名互访
  • Prometheus node_exporter、Filebeat 等网络密集型 agent 考虑 Host 模式
  • Sidecar 架构优先用 Container 模式,localhost 通信延迟最低
  • docker network ls 检查现有网络,docker network inspect 查看拓扑
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐