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 网络):
- 容器 A 发送数据包,目标为容器 B 的 IP。
- 数据包通过容器 A 的 veth 接口到达虚拟网桥。
- 网桥根据 MAC 地址表,将数据包转发到容器 B 的 veth 接口。
- 数据包进入容器 B 的网络命名空间,到达目标进程。
3.7 端口映射与连通性验证的关系
端口映射的本质是在宿主机和容器网络命名空间之间建立 NAT 规则。当测试工具从宿主机访问 localhost:6379 时,iptables 规则将流量转发到容器内的 Redis 进程。理解网络模型有助于诊断以下常见问题:
| 问题现象 | 可能原因 | 排查方向 |
|---|---|---|
| 容器间 ping 不通 | 不在同一 Bridge 网络 | 检查 docker network inspect |
| 宿主机无法访问映射端口 | Host 网络下端口冲突 | 检查端口占用,改用 Bridge |
| 跨主机容器通信失败 | Overlay 网络未正确配置 | 检查 Swarm 状态和网络子网 |
| 容器名 DNS 解析失败 | 使用了默认 Bridge | 切换到自定义 Bridge 网络 |
最佳实践: 在集成测试脚本中,始终使用自定义 Bridge 网络,并通过容器名(而非 IP)进行服务发现。这样即使容器重启导致 IP 变化,测试用例也不会中断。