3. Bridge网络深度解析:默认桥接网络原理、端口映射机制、容器间通信

Bridge网络是Docker默认的网络驱动,也是单机容器通信的基础。理解其底层原理、端口映射机制以及容器间通信方式,是排查网络故障的核心前提。本章将深入剖析Docker默认桥接网络的工作模型。

3.1 默认桥接网络原理

Docker守护进程启动时,会在宿主机上创建一个名为docker0的虚拟网桥。所有未指定网络的容器,默认都会连接到这个docker0网桥上。其核心架构如下:

核心组件:
  • docker0 网桥: 宿主机上的虚拟二层交换机,默认IP段为 172.17.0.0/16。
  • veth pair: 每创建一个容器,Docker会创建一对虚拟以太网卡(veth pair)。一端连接到容器内的eth0,另一端连接到docker0网桥。
  • 网络命名空间: 每个容器拥有独立的网络栈(网卡、路由表、iptables规则),通过veth pair与宿主机网络桥接。
默认桥接网络架构图 默认桥接网络 (docker0) 架构 宿主机 docker0 网桥 172.17.0.1/16 容器 A eth0: 172.17.0.2 网络命名空间 容器 B eth0: 172.17.0.3 网络命名空间 vethA vethB 外部网络 / 物理网卡 (eth0) NAT / 路由
关键点: 同一宿主机上,连接到 docker0 网桥的容器处于同一个二层网络中,可以直接通过IP地址通信。容器与外部网络通信时,需要通过宿主机的iptables进行网络地址转换(NAT)。

3.2 端口映射机制

默认情况下,容器可以访问外部网络,但外部网络无法直接访问容器。端口映射机制通过-p或--publish参数,将宿主机端口流量转发到容器端口,实现外部访问。

映射模式 命令示例 说明
指定端口映射 -p 8080:80 宿主机 8080 端口 → 容器 80 端口
随机端口映射 -p 80 宿主机随机端口(32768-60999)→ 容器 80 端口
指定IP映射 -p 192.168.1.100:8080:80 绑定到特定宿主机IP的 8080 端口
UDP端口映射 -p 8080:80/udp 映射 UDP 协议端口

端口映射的底层实现依赖iptables的DNAT规则。当外部请求到达宿主机映射端口时,iptables将目标地址和端口改写为容器IP和端口,然后通过docker0网桥转发给容器。

故障排查提示: 如果端口映射不生效,请检查:
  • 宿主机防火墙是否放行了映射端口。
  • 容器内服务是否监听在 0.0.0.0 而非 127.0.0.1。
  • 使用 iptables -t nat -L -n 查看DNAT规则是否生成。

3.3 容器间通信

在默认桥接网络下,容器间通信主要通过两种方式:IP地址通信和--link机制(已废弃,推荐使用自定义网络)。

3.3.1 通过IP地址通信

连接到同一docker0网桥的容器,可以直接使用对方的IP地址进行通信。Docker内置的DNS服务默认不解析容器名称,因此无法通过容器名直接访问。

# 启动两个容器
docker run -d --name web1 nginx
docker run -d --name web2 nginx

# 进入 web2 容器,ping web1 的 IP
docker exec -it web2 sh
/ # ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.123 ms

3.3.2 通过容器名通信(自定义网络)

使用自定义Bridge网络时,Docker内置的DNS服务会自动解析容器名称,实现容器名通信,这是推荐的生产实践。

# 创建自定义桥接网络
docker network create my-bridge

# 启动容器并连接到自定义网络
docker run -d --name app1 --network my-bridge nginx
docker run -d --name app2 --network my-bridge nginx

# 进入 app2,通过容器名访问 app1
docker exec -it app2 sh
/ # ping app1
PING app1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.089 ms
容器间通信方式对比 容器间通信方式对比 默认桥接网络 (docker0) 容器 A 172.17.0.2 容器 B 172.17.0.3 IP通信 ✗ 不支持容器名解析 ✗ 需手动管理IP 自定义桥接网络 (my-bridge) 容器 app1 172.18.0.2 容器 app2 172.18.0.3 容器名通信 内置DNS解析 ✓ 自动DNS解析容器名 ✓ 网络隔离与灵活管理

3.4 常见故障与排查

故障现象 可能原因 排查命令
容器间无法ping通 不在同一网络;iptables规则阻断 docker network inspect bridge
端口映射外部无法访问 宿主机防火墙;容器服务未启动 ss -tlnp | grep 8080
容器无法访问外网 宿主机IP转发未开启;DNS配置错误 sysctl net.ipv4.ip_forward
DNS解析失败 容器DNS配置错误;宿主机resolv.conf问题 docker exec <容器> cat /etc/resolv.conf
最佳实践:
  • 生产环境始终使用自定义Bridge网络,利用内置DNS实现容器名通信。
  • 避免使用 --link 参数,该机制已废弃且功能有限。
  • 端口映射时优先指定宿主机端口,避免随机端口带来的管理复杂性。
  • 定期使用 docker network inspect 检查网络连接状态。