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 封装/解封装)

四、选型决策框架与边界分析

维度BridgeHostOverlayMacvlan
NAT 开销有(小)VXLAN 封装
同主机延迟0.05ms0.02msN/A0.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 模式"追求极致性能",安全部门不会同意的。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐