3. Docker 网络模型:Bridge、Host、None、Overlay 与容器间通信原理

在集成测试中,容器间的网络连通性是验证缓存服务端口映射是否生效的前提。Docker 提供了多种网络驱动,每种驱动对应不同的隔离级别、性能特征和适用场景。理解这些网络模型,是设计可靠测试环境的基础。

3.1 核心网络驱动对比

网络驱动 隔离性 外部访问 跨主机通信 典型场景
Bridge 容器间隔离,通过虚拟网桥互通 需端口映射(-p) 不支持 单机多容器集成测试
Host 无隔离,共享宿主机网络栈 直接暴露端口 不支持 性能敏感型测试
None 完全隔离,无网络接口 无法访问 不支持 安全沙箱、离线计算
Overlay 跨主机虚拟网络 需端口映射或 ingress 支持 Swarm/K8s 多节点测试
测试选型建议: 单机集成测试优先使用 Bridge 网络;需要模拟生产多节点部署时,使用 Overlay 网络;仅在需要极致网络性能且不关心端口冲突时使用 Host 网络。

3.2 Bridge 网络:默认与自定义

Docker 安装时会自动创建一个名为 bridge 的默认桥接网络。所有未指定网络的容器默认加入此网络,通过 Docker 内部的 DNS 解析(容器名)实现通信。

默认 Bridge 的局限:

  • 容器间只能通过 IP 地址通信,不支持容器名自动 DNS 解析。
  • 所有容器共享同一网段,无法实现网络隔离分组。

自定义 Bridge 的优势:

  • 支持容器名自动 DNS 解析,便于测试脚本中通过服务名访问。
  • 可以创建多个隔离的 Bridge 网络,模拟不同的测试环境。
  • 容器可以动态加入/离开网络,不影响其他容器。
# 创建自定义 Bridge 网络
docker network create --driver bridge --subnet 172.20.0.0/16 test-net

# 启动两个容器并连接到同一网络
docker run -d --name redis-cache --network test-net redis:7-alpine
docker run -d --name app-server --network test-net alpine:3.19 sleep 3600

# 通过容器名验证连通性
docker exec app-server ping -c 3 redis-cache
关键点: 在集成测试中,始终使用自定义 Bridge 网络。它提供了可预测的 IP 分配、内置 DNS 解析和网络隔离能力,是端口映射验证的基础设施。

3.3 Host 网络:性能与风险

Host 网络模式下,容器直接使用宿主机网络栈,没有网络隔离。容器内监听的端口会直接暴露在宿主机上,无需 -p 映射。

# 使用 Host 网络启动 Redis
docker run -d --name redis-host --network host redis:7-alpine

# 宿主机上直接访问
redis-cli -h 127.0.0.1 -p 6379 ping
测试风险: Host 网络下端口冲突概率高,且无法同时运行多个相同端口的容器。在集成测试中,除非需要测试网络吞吐极限,否则应避免使用 Host 网络。

3.4 None 网络:完全隔离

None 网络为容器提供完全的网络隔离,容器内只有 loopback 接口,无法与外界通信。适用于安全敏感的计算任务或离线测试场景。

# 启动无网络容器
docker run -d --name isolated-calc --network none alpine:3.19 sleep 3600

# 验证无网络接口
docker exec isolated-calc ip addr
# 输出仅包含 lo 接口

3.5 Overlay 网络:跨主机通信

Overlay 网络通过 VXLAN 隧道技术,将多个 Docker 主机上的容器连接到一个虚拟二层网络。容器间可以像在同一个 Bridge 网络中一样通信,不受物理主机边界限制。

Overlay 网络的关键特性:

  • 需要 Docker Swarm 或 Kubernetes 集群环境。
  • 每个容器分配一个虚拟 IP,跨主机可达。
  • 支持服务发现和负载均衡(Swarm 模式下)。
  • 网络性能受封装/解封装开销影响。
# 初始化 Swarm 集群(管理节点)
docker swarm init

# 创建 Overlay 网络
docker network create --driver overlay --subnet 10.10.0.0/16 overlay-test

# 在 Swarm 服务中使用 Overlay 网络
docker service create --name redis-overlay \
  --network overlay-test \
  --replicas 2 \
  redis:7-alpine

3.6 容器间通信原理

容器间通信的核心机制是 veth pair(虚拟以太网对)和 网络命名空间。每个容器拥有独立的网络命名空间,通过 veth pair 的一端连接到容器内,另一端连接到 Docker 创建的虚拟网桥(如 docker0)。

通信流程(Bridge 网络):
  1. 容器 A 发送数据包,目标为容器 B 的 IP。
  2. 数据包通过容器 A 的 veth 接口到达虚拟网桥。
  3. 网桥根据 MAC 地址表,将数据包转发到容器 B 的 veth 接口。
  4. 数据包进入容器 B 的网络命名空间,到达目标进程。
容器间通信原理(Bridge 网络) 容器 A eth0: 172.17.0.2 veth 端 容器 B eth0: 172.17.0.3 veth 端 虚拟网桥 docker0 MAC 地址表 / ARP 代理 数据包转发路径 通信步骤: 1. 容器 A 发送数据包,目标 IP = 172.17.0.3 2. 数据包通过 veth 到达 docker0 网桥 3. 网桥查询 MAC 表,转发到容器 B 的 veth 4. 数据包进入容器 B 网络命名空间,到达应用进程

3.7 端口映射与连通性验证的关系

端口映射的本质是在宿主机和容器网络命名空间之间建立 NAT 规则。当测试工具从宿主机访问 localhost:6379 时,iptables 规则将流量转发到容器内的 Redis 进程。理解网络模型有助于诊断以下常见问题:

问题现象 可能原因 排查方向
容器间 ping 不通 不在同一 Bridge 网络 检查 docker network inspect
宿主机无法访问映射端口 Host 网络下端口冲突 检查端口占用,改用 Bridge
跨主机容器通信失败 Overlay 网络未正确配置 检查 Swarm 状态和网络子网
容器名 DNS 解析失败 使用了默认 Bridge 切换到自定义 Bridge 网络
最佳实践: 在集成测试脚本中,始终使用自定义 Bridge 网络,并通过容器名(而非 IP)进行服务发现。这样即使容器重启导致 IP 变化,测试用例也不会中断。