深入剖析 Docker Swarm 网络:从物理层到容器层的完整数据通路

0 阅读6分钟

在双节点 Swarm 集群中,一次简单的 HTTP 请求背后,隐藏着 Linux 网络技术的精妙交响。本文将带你穿越七层网络模型,揭秘数据包在 Swarm 网络中的完整生命周期。

1. 网络架构全景图

1.1 物理网络基础

我的双节点 Swarm 集群底层拓扑简洁而清晰:

Manager节点: i-xah31y1o - 10.7.191.10/24
Worker节点:  i-hqsrcwx6 - 10.7.191.9/24

这两个节点通过物理网络互联,构成了 Swarm 集群的物理基础。

1.2 Swarm 网络栈层次

Docker Swarm 构建了一个完整的分层网络栈:

Layer 7: 应用层        [Nginx容器]
Layer 4: 传输层        [TCP/UDP端口映射]
Layer 3: 网络层        [Overlay网络 + VXLAN]
Layer 2: 数据链路层    [veth pair + bridge]
Layer 1: 物理层        [宿主机网卡]

2. 网络命名空间深度解析

2.1 宿主机网络命名空间

宿主机是网络流量的起点和终点。查看宿主机网络接口:

# 查看网桥配置
ip addr show docker_gwbridge
# 输出:172.18.0.1/16

# 查看虚拟以太网对
ip addr show vethxxx
# 每个veth接口对应一个容器的网络连接

2.2 ingress-sbox 网络命名空间

这是 Swarm 网络的"流量调度中心",负责负载均衡和路由:

# 进入ingress-sbox的网络命名空间
nsenter --net=/var/run/docker/netns/ingress_sbox ip addr show

# 关键发现:
# eth0连接到ingress网络(10.255.0.2)
# eth1连接到docker_gwbridge网络(172.18.0.2)
# 这两个接口通过veth pair与宿主机连接

ingress-sbox是一个特殊的负载均衡器容器,每个节点都会自动创建,负责处理入站流量。

2.3 容器网络命名空间

每个容器都有独立的网络命名空间:

# 查找容器的网络命名空间
docker inspect web.1 --format '{{.NetworkSettings.SandboxKey}}'
# 输出:/var/run/docker/netns/xxxx

# 进入容器网络命名空间
nsenter --net=/var/run/docker/netns/xxx ip addr show

3. iptables 规则链完整分析

3.1 NAT 表规则链

DNAT 规则实现端口映射的关键:

# 查看完整的NAT表规则
iptables -t nat -L -n --line-numbers

# 关键规则链:
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER-INGRESS  all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-INGRESS (2 references)
num  target     prot opt source               destination
1    DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0  tcp dpt:8080 to:172.18.0.2:8080

3.2 FILTER 表规则链

防火墙规则确保网络安全:

iptables -t filter -L DOCKER-INGRESS -n
# 允许流量到达负载均衡器
ACCEPT     tcp  --  0.0.0.0/0  172.18.0.2  tcp dpt:8080

4. IPVS 负载均衡详细配置

4.1 IPVS 服务配置

ingress-sbox中实现四层负载均衡:

nsenter --net=/var/run/docker/netns/ingress_sbox ipvsadm -L -n

# 输出示例:
TCP  10.255.0.4:80 wrr
  -> 10.255.0.5:80  Masq  1  0  0
  -> 10.255.0.6:80  Masq  1  0  0

IPVS 使用加权轮询算法,将流量分发到不同的容器实例。

4.2 IPVS 连接跟踪

监控负载均衡状态:

nsenter --net=/var/run/docker/netns/ingress_sbox ipvsadm -L -n --stats
# 显示每个后端的连接数、数据包计数

5. VXLAN 隧道技术深度解析

5.1 VXLAN 接口配置

跨节点容器通信的基础:

ip -d link show vxlan0
# vxlan id 4096 dev eth0 srcport 0 0 dstport 4789
# MTU 1450(考虑VXLAN封装开销)

5.2 VXLAN 数据包封装

原始数据包经过 VXLAN 封装:

原始数据包:
[以太网头][IP头][TCP头][数据]

VXLAN封装后(增加50字节开销):
[外部以太网头][外部IP头][UDP头][VXLAN头][原始数据包]

5.3 VXLAN 通信流程

捕获 VXLAN 流量分析:

tcpdump -i any -n -e vlan and port 4789
# 10.7.191.10.41862 > 10.7.191.9.4789: VXLAN, vni 4096

6. Linux Bridge 详细配置

6.1 docker_gwbridge 配置

容器与外部通信的桥梁:

brctl show docker_gwbridge
# bridge name     bridge id               STP enabled     interfaces
# docker_gwbridge 8000.0242ac120001       no              vethxxxx

6.2 网桥转发表

MAC 地址学习与转发:

brctl showmacs docker_gwbridge
# 显示学习到的MAC地址及其端口

7. 路由表详细分析

7.1 宿主机路由表

网络流量的导航图:

ip route show
# 10.255.0.0/16 dev br0
# 172.18.0.0/16 dev docker_gwbridge

7.2 ingress-sbox 路由表

负载均衡器的路由决策:

nsenter --net=/var/run/docker/netns/ingress_sbox ip route show
# 10.255.0.0/16 dev eth0
# 172.18.0.0/16 dev eth1
# 默认路由指向网关

8. 数据包完整生命周期追踪

8.1 请求到达阶段

外部请求的旅程开始:

外部请求: 10.7.191.10:8080 → 宿主机物理网卡
        ↓
iptables PREROUTING链 → DOCKER-INGRESS链
        ↓
DNAT转换: 10.7.191.10:8080 → 172.18.0.2:8080
        ↓
通过docker_gwbridge路由到ingress-sbox

8.2 负载均衡阶段

IPVS 的流量调度:

ingress-sbox接收数据包 (172.18.0.2:8080)
        ↓
IPVS负载均衡器选择后端
        ↓
目标重写: 172.18.0.2:8080 → 10.255.0.5:80
        ↓
通过ingress网络路由到目标容器

8.3 跨节点通信阶段

VXLAN 隧道的作用:

如果目标容器在远程节点:
        ↓
通过vxlan0接口封装
        ↓
VXLAN隧道传输到目标节点
        ↓
目标节点解封装,路由到容器

9. 性能监控和调优

9.1 网络性能指标

关键监控指标:

# 查看网络接口统计
nsenter --net=/var/run/docker/netns/ingress_sbox netstat -i

# 查看IPVS连接统计
nsenter --net=/var/run/docker/netns/ingress_sbox ipvsadm -L -n --stats

9.2 性能调优参数

优化网络性能:

# 调整VXLAN MTU避免分片
ip link set vxlan0 mtu 1500

# 增加网络缓冲区
sysctl -w net.core.rmem_max=26214400
sysctl -w net.core.wmem_max=26214400

10. 故障排查工具箱

10.1 网络连通性测试

分步诊断网络问题:

# 从ingress-sbox测试容器连通性
nsenter --net=/var/run/docker/netns/ingress_sbox ping 10.255.0.5
nsenter --net=/var/run/docker/netns/ingress_sbox curl http://10.255.0.5:80

10.2 数据包追踪

深入分析数据流:

# 在关键节点进行tcpdump捕获
tcpdump -i docker_gwbridge -n host 172.18.0.2
tcpdump -i br0 -n host 10.255.0.5

10.3 连接状态检查

查看连接跟踪信息:

# 查看IPVS连接状态
nsenter --net=/var/run/docker/netns/ingress_sbox ipvsadm -L -n -c

# 查看conntrack连接跟踪
conntrack -L | grep 8080

技术要点总结

Docker Swarm 网络的核心设计思想是分层解耦透明转发

  1. 命名空间隔离:每个容器和 ingress-sbox都有独立的网络环境
  2. veth pair 连接:虚拟以太网对连接不同的网络命名空间
  3. Linux Bridgedocker_gwbridgebr0作为网络交换设备
  4. iptables DNAT:实现端口映射和流量重定向
  5. IPVS 负载均衡:在 ingress-sbox中实现高效的四层负载均衡
  6. VXLAN overlay:通过隧道技术实现无缝的跨主机通信
  7. 路由策略:基于目标地址的智能路由决策

这种架构使得 Swarm 能够在保持网络性能的同时,提供灵活的容器网络解决方案。每个技术组件都有明确的职责,共同构成了一个高可用、可扩展的容器网络栈。

通过深入理解这些底层机制,我们不仅能更好地排查网络问题,还能针对特定场景进行精细化调优,充分发挥容器化部署的优势。