Docker 网络模式深潜:bridge、host、overlay 的底层差异
·
Docker 网络模式深潜:bridge、host、overlay 的底层差异
一、容器 A 访问不了容器 B,排查发现:一个是 bridge 模式,一个是 host 模式,根本不在一个网络平面
Docker 五种网络模式看起来都叫"网络",底层实现完全不同:
- bridge(默认):NAT 转发,通过 docker0 虚拟网桥通信
- host:直接使用宿主机网络栈,没有隔离
- overlay:跨主机的 VXLAN 隧道网络(Swarm/K8s)
- none:无网络,纯隔离
- macvlan/ipvlan:容器直接获取物理网络中的 MAC/IP
问题不只是"能不能通信",更关键的是:性能损耗、隔离强度、服务发现机制、端口冲突在这几种模式下完全不同。
二、三种核心网络模式底层原理
Bridge 模式数据包路径:
三、生产级网络配置与性能分析
Bridge 模式详解
# 查看 docker0 网桥
$ ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
link/ether 02:42:ac:11:00:01 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
# 查看 iptables NAT 规则
$ iptables -t nat -L -n
Chain POSTROUTING
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
Chain DOCKER
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
# 创建自定义 bridge 网络(比默认 bridge 更好)
docker network create \
--driver bridge \
--subnet=10.5.0.0/16 \
--gateway=10.5.0.1 \
--opt "com.docker.network.bridge.name"="my-bridge" \
--opt "com.docker.network.bridge.enable_icc"="true" \
--opt "com.docker.network.bridge.enable_ip_masquerade"="true" \
my-bridge-net
# 自定义 bridge 的好处:
# 1. DNS 自动解析(默认 bridge 没有)
# 2. 容器间通过 --link 或名称通信
# 3. 可以配置子网范围
docker run -d --network=my-bridge-net --name web nginx
docker run -d --network=my-bridge-net --name app my-app
# 容器内部 DNS 解析
docker exec web ping app # 可以直接 ping 容器名
Host 模式详解
# Host 模式:容器直接使用宿主机网络
docker run -d --network=host nginx
# 此时 nginx 的 80 端口直接绑定在宿主机上
# 不需要 -p 80:80
netstat -tlnp | grep :80
# tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 12345/nginx
# Host 模式的问题:
# 1. 端口冲突:两个容器不能同时用同一个端口
# 2. 无隔离:容器能看到宿主机所有网络接口
# 3. 安全隐患:容器可以修改宿主机网络配置
# 适用场景:
# - 高性能网络需求(无 NAT 损耗)
# - 需要监听大量端口
# - 网络监控工具(需要抓宿主机流量)
Overlay 模式详解
# 初始化 Swarm(创建 overlay 网络的前提)
docker swarm init
# 创建 overlay 网络
docker network create \
--driver overlay \
--subnet=10.0.9.0/24 \
--attachable \
my-overlay-net
# 创建服务使用 overlay
docker service create \
--name web \
--network=my-overlay-net \
--replicas=3 \
nginx
# Overlay 网络底层是 VXLAN 隧道
# 查看 VXLAN 接口
ip -d link show | grep vxlan
# VXLAN 数据包结构:
# [Outer Eth][Outer IP][UDP:4789][VXLAN Header][Inner Eth][Inner IP][Payload]
# VXLAN 封装增加 ~50 字节开销 → MTU 需要考虑
网络性能对比测试
# 测试不同网络模式的延迟和吞吐量
# 1. Bridge 模式
docker run --rm --network=bridge alpine ping -c 100 172.17.0.1
# 平均延迟: 0.05ms (同主机 bridge)
# 2. Host 模式
docker run --rm --network=host alpine ping -c 100 localhost
# 平均延迟: 0.02ms (无任何虚拟化开销)
# 3. 吞吐量测试
docker run --rm --network=bridge alpine \
sh -c "apk add iperf3 && iperf3 -c 172.17.0.1 -t 10"
# Bridge: ~35 Gbps (同主机,受 veth 限制)
# Host: ~50 Gbps (同主机,无虚拟化损耗)
# 4. Overlay 网络延迟
# Node 1 → Node 2 (overlay)
# 额外 ~0.1-0.2ms (VXLAN 封装/解封装)
四、选型决策框架与边界分析
| 维度 | Bridge | Host | Overlay | Macvlan |
|---|---|---|---|---|
| NAT 开销 | 有(小) | 无 | VXLAN 封装 | 无 |
| 同主机延迟 | 0.05ms | 0.02ms | N/A | 0.03ms |
| 端口隔离 | 是 | 否(冲突风险) | 是 | 是 |
| DNS 服务发现 | 自定义 bridge 有 | 无 | 有(Swarm 内置) | 无 |
| 跨主机通信 | 否 | 否(除非手动路由) | 是 | 是(同 VLAN) |
| 安全隔离 | 中(NAT 提供一定隔离) | 低(无隔离) | 中(VXLAN 流量不加密) | 低(直接暴露) |
| 适用 K8s | 是(默认 CNI) | 特殊情况 | 是(Flannel VXLAN) | 特殊情况 |
场景选型指南
你应该用 bridge:
- 单机上的多容器应用(docker-compose)
- 需要端口映射和隔离
- 标准 Web 服务部署
- 快速开发测试
你应该用 host:
- 高性能网络应用(无 NAT 损耗)
- 需要监听大量端口(1000+ 端口避免 NAT 规则膨胀)
- 网络抓包/监控工具(需要访问宿主机网卡)
- 注意:两个相同端口的服务不能同时运行
你应该用 overlay:
- 多主机容器通信(Docker Swarm / K8s)
- 不需要关心容器在哪个节点
- 需要跨主机的服务发现
你应该用 macvlan:
- 容器需要直接从物理网络获取 IP
- 容器需要和物理网络中的设备直接通信
- 遗留系统迁移到容器但不改 IP
常见踩坑
坑 1:默认 bridge 没有 DNS
# 默认 bridge 网络
docker run --name web nginx
docker run --name app alpine ping web # 失败!无法解析 web
# 自定义 bridge 网络
docker network create my-net
docker run --network=my-net --name web nginx
docker run --network=my-net alpine ping web # 成功!DNS 解析
坑 2:iptables 规则爆炸
每个端口映射(-p)会创建 2-4 条 iptables 规则。100 个端口映射 = 400 条 iptables 规则。规则太多导致性能下降。解决方案:减少端口映射,使用反向代理(Nginx/Traefik)。
坑 3:VXLAN MTU 问题
VXLAN 封装增加 ~50 字节。如果物理网络 MTU=1500,VXLAN 内部有效 MTU=1450。大数据包需要分片,性能下降。解决方案:增大物理网络 MTU 到 1550 或配置容器内 MTU=1450。
五、总结
Docker 网络选型一句话:
- 单机开发 → custom bridge(别用默认 bridge)
- 高性能单机 → host(注意端口冲突)
- 多主机集群 → overlay(VXLAN 隧道)
- 直连物理网络 → macvlan(需要特殊 IP 管理)
性能对比一句话:
host > macvlan > bridge > overlay (VXLAN)
调试网络的三个命令:
# 1. 容器视角看网络
docker exec <container> ip addr
# 2. 跟踪 NAT 规则
iptables -t nat -L -n -v
# 3. 抓包看实际流量
tcpdump -i docker0 -nn port 80
选的不是"最快"的模式,而是"最符合场景"的模式。90% 的场景 custom bridge 就够用了。别一上来就 host 模式"追求极致性能",安全部门不会同意的。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)