3. 容器网络通信基础:veth pair、namespace隔离、路由转发原理、iptables/ipvs规则链
容器网络的核心在于“隔离”与“连通”的平衡。Linux内核提供的Namespace实现了网络栈的隔离,而veth pair、路由转发、iptables/ipvs则构成了跨Namespace通信的桥梁。理解这些底层机制,是后续优化Calico缓存命中率的前提。
3.1 网络命名空间(Network Namespace)
每个容器拥有独立的网络命名空间,拥有自己的网络设备、IP地址、路由表、防火墙规则等。宿主机与容器、容器与容器之间默认完全隔离。
| 资源类型 | 隔离范围 | 默认可见性 |
|---|---|---|
| 网络设备(eth0, lo) | 仅本Namespace | 不可见 |
| IP地址与路由表 | 仅本Namespace | 不可见 |
| iptables/ipvs规则 | 仅本Namespace | 不可见 |
| /proc/net 文件系统 | 仅本Namespace | 不可见 |
性能提示: 过多的Namespace切换(如频繁的nsenter操作)会增加上下文切换开销。在Calico的eBPF模式下,通过绕过部分Namespace隔离,可显著降低路径延迟。
3.2 veth pair:虚拟以太网线缆
veth pair是一对虚拟网卡,像一根“网线”的两端。一端放入容器Namespace(通常命名为eth0),另一端留在宿主机根Namespace(通常命名为caliXXXX)。数据包从一端进入,必然从另一端流出。
- 创建方式:
ip link add veth0 type veth peer name veth1 - 典型拓扑: 宿主机端(cali0)↔ 容器端(eth0)
- 数据流特性: 全双工、二层直连、无中间交换机
# 创建一对veth
ip link add veth-host type veth peer name veth-ctr
# 将一端移入容器Namespace(假设PID为1234)
ip link set veth-ctr netns 1234
# 在容器内重命名并配置IP
ip netns exec 1234 ip link set veth-ctr name eth0
ip netns exec 1234 ip addr add 10.0.0.2/24 dev eth0
ip netns exec 1234 ip link set eth0 up
# 在宿主机端配置IP并启用
ip addr add 10.0.0.1/24 dev veth-host
ip link set veth-host up
调优关注点: veth pair的MTU(最大传输单元)必须与宿主机物理网卡及Calico隧道模式匹配。MTU不匹配会导致分片,严重降低吞吐量并增加CPU开销。建议统一设置为1450(Calico VXLAN)或1500(Direct路由)。
3.3 路由转发原理
容器间的通信依赖内核路由表。当数据包从容器eth0发出,到达宿主机veth端后,宿主机内核根据路由表决定下一跳。Calico利用主机的路由表实现高性能转发,避免额外封装。
# 查看宿主机路由表(典型Calico节点)
ip route show
# 输出示例
# 10.0.0.0/24 dev cali0 scope link
# 10.0.1.0/24 via 192.168.1.2 dev eth0 proto bird
# 10.0.2.0/24 via 192.168.1.3 dev eth0 proto bird
路由转发流程(同节点容器通信):
- 容器A(10.0.0.2)发送数据包到容器B(10.0.0.3)。
- 数据包通过veth pair到达宿主机caliA端。
- 宿主机内核查询路由表,发现10.0.0.3/32直连在caliB设备上。
- 数据包直接通过caliB设备进入容器B的Namespace。
- 整个过程在二层完成,无需三层网关或隧道封装。
缓存命中率关键: 路由表查找依赖FIB(转发信息库)和邻居表(ARP/NDP)。当容器规模超过数千时,路由表条目膨胀会导致FIB缓存失效。Calico通过BGP聚合路由、使用ECMP(等价多路径)以及eBPF的LRU映射来提升查找效率。
3.4 iptables/ipvs规则链
Kubernetes Service的负载均衡和网络策略(NetworkPolicy)依赖iptables或ipvs。理解规则链的执行顺序对性能调优至关重要。
3.4.1 iptables规则链流程
数据包在宿主机Netfilter框架中经过以下关键链(以PREROUTING → FORWARD → POSTROUTING为例):
PREROUTING
├── raw (TRACE, NOTRACK)
└── mangle (TTL, DSCP)
└── nat (DNAT, REDIRECT)
└── 路由决策
├── FORWARD (filter)
│ ├── cali-FORWARD (Calico策略)
│ └── KUBE-FORWARD (Service转发)
└── POSTROUTING
├── mangle
└── nat (SNAT, MASQUERADE)
| 表 | 链 | 典型用途 | 性能影响 |
|---|---|---|---|
| raw | PREROUTING, OUTPUT | 连接跟踪(conntrack)绕过 | 高(可减少conntrack开销) |
| mangle | 所有链 | 报文标记、QoS | 中 |
| nat | PREROUTING, POSTROUTING, OUTPUT | DNAT/SNAT | 高(规则匹配次数多) |
| filter | FORWARD, INPUT, OUTPUT | 网络策略、安全组 | 高(规则数量线性影响) |
3.4.2 ipvs:高性能替代方案
ipvs(IP Virtual Server)工作在内核空间,使用哈希表直接查找转发规则,避免了iptables的链式遍历。Kube-proxy在ipvs模式下,Service规则数量增加时性能几乎线性不变。
# 查看ipvs规则
ipvsadm -Ln
# 输出示例
# IP Virtual Server version 1.2.1 (size=4096)
# Prot LocalAddress:Port Scheduler Flags
# -> RemoteAddress:Port Forward Weight ActiveConn InActConn
# TCP 10.96.0.1:443 rr
# -> 192.168.1.10:6443 Masq 1 0 0
# -> 192.168.1.11:6443 Masq 1 0 0
调优建议: 对于大规模集群(>1000 Service),强烈建议使用ipvs模式替代iptables。ipvs使用O(1)查找复杂度,而iptables规则链是O(n)。Calico的eBPF模式甚至可以完全绕过kube-proxy,进一步消除Netfilter开销。
3.5 容器网络通信全景图
下图展示了同节点与跨节点容器通信的完整路径,以及各组件在路径中的位置。
3.6 关键性能指标与调优方向
| 组件 | 关键指标 | 瓶颈表现 | 调优方向 |
|---|---|---|---|
| veth pair | MTU、队列长度 | 分片、丢包 | 统一MTU、启用多队列 |
| 路由表 | FIB缓存命中率、路由条目数 | 路由查找延迟增加 | 路由聚合、ECMP、eBPF LRU |
| iptables | 规则数量、conntrack表大小 | CPU软中断飙升 | 迁移至ipvs或eBPF |
| ipvs | 连接数、调度算法 | 哈希冲突 | 增大哈希表、使用SH调度器 |
| 邻居表 | GC阈值、条目数 | ARP/NDP解析延迟 | 增大gc_thresh、静态邻居 |
核心结论: 容器网络通信的每一层都可能是缓存命中率的瓶颈。veth pair的MTU配置影响分片与重传;路由表的FIB缓存决定转发速度;iptables的链式遍历消耗CPU;邻居表的GC机制影响新连接建立延迟。Calico的eBPF数据平面通过将路由、邻居、策略全部下沉到内核的BPF映射中,实现了真正的O(1)查找,从根本上解决了传统Netfilter路径的缓存失效问题。