4. Calico 数据平面实战

Calico 的控制平面负责把网络策略、路由和端点信息下发到每个节点,而真正决定“数据包怎么走、策略在哪里生效”的,是节点上的数据平面。Calico 目前支持三种主流数据平面:iptables、eBPF 和 Windows HNS。它们并非可以随意混用,而是与节点操作系统、内核版本以及 Calico 组件形态强绑定。理解三者的原理差异,是做出正确选型与切换的前提。

一、三种数据平面的原理定位

iptables 数据平面是 Calico 最经典、兼容性最好的实现。它依赖 Linux 内核的 netfilter 框架,由 felix 组件把策略翻译成 iptables 规则链,写入 filter、nat、mangle 等表。数据包在协议栈中依次经过 PREROUTING、FORWARD、POSTROUTING 等钩子,逐条匹配规则完成放行、丢弃、DNAT/SNAT。它的优点是成熟稳定、可读可查(iptables-save 即可看到全部规则),缺点是规则数量随 Pod 与策略规模线性增长,大规模集群下匹配开销明显。

eBPF 数据平面把策略执行点下沉到内核的 eBPF 程序,挂载在网卡 TC(traffic control)层和 socket 层。Calico 通过 libbpf 加载程序,用 BPF map 存储端点、策略和连接跟踪信息。数据包在进入协议栈早期就被处理,无需遍历冗长的 iptables 链。它天然支持 DSR(Direct Server Return)、更高效的 NAT 和更细粒度的可观测性,但要求内核版本较高(一般 5.3+,推荐 5.8+),且不兼容部分旧特性。

Windows HNS 数据平面面向 Windows 节点。Windows 没有 netfilter,Calico 借助 HNS(Host Network Service)和 VFP(Virtual Filtering Platform)扩展实现网络策略。Calico 的 felix 在 Windows 上把策略转换为 HNS 的 ACL 规则,由 VFP 在 vSwitch 层执行。它通常与 VXLAN 或 BPF 模式配合,是 Windows 工作节点接入 Calico 集群的唯一可行路径。

Calico 三种数据平面的策略执行位置对比 iptables 数据平面 Pod 发出数据包 veth → 主机协议栈 netfilter 钩子遍历 PREROUTING / FORWARD POSTROUTING 逐条匹配 cali-* 规则链判定 ACCEPT / DROP / DNAT 转发至目标节点 或本机交付 规则数随 Pod/策略线性增长 兼容性最好,内核要求低 可 iptables-save 直接查看 eBPF 数据平面 Pod 发出数据包 veth → TC ingress eBPF 程序早期处理 TC / XDP 钩子 查 BPF map 命中策略 连接跟踪 / NAT 加速 支持 DSR 直接回程 转发至目标节点 或本机交付 规则匹配 O(1) 级 map 查找 需内核 5.3+,推荐 5.8+ 可观测性更强,支持 DSR Windows HNS 数据平面 Windows Pod 发出数据包 vNIC → vSwitch HNS / VFP 策略层 ACL 规则下发 vSwitch 扩展执行 VXLAN 封装转发 跨节点隧道通信 目标 Windows 节点 解封装并交付 仅 Windows 节点使用 依赖 HNS + VFP 扩展 常与 VXLAN 模式配合

二、性能差异的关键来源

三者的性能差异并非来自“谁更先进”,而是来自策略匹配的数据结构与执行位置。iptables 使用线性规则链,第 N 条规则需要前 N-1 条都不匹配才会被检查,因此策略规模越大,单包处理延迟越高。eBPF 使用哈希 map 做端点与策略查找,平均查找复杂度接近 O(1),在数千 Pod 规模下优势明显。Windows HNS 的性能则受限于 vSwitch 与 VFP 的处理路径,通常低于同规格 Linux eBPF 节点,但足以满足大多数 Windows 工作负载。

另一个关键差异是连接建立路径。eBPF 支持在 socket 层做 connect 重定向和 DSR,使回程流量绕过入口节点,减少一跳转发;iptables 模式下回程通常需要原路返回。对于东西向流量密集的微服务集群,这一差异会直接体现在 P99 延迟上。

三、切换方法与前置检查

切换数据平面不是改一个开关那么简单,它涉及组件重启、规则重建和存量连接中断。以 Linux 节点从 iptables 切换到 eBPF 为例,标准做法是修改 FelixConfiguration 资源:

# 查看当前数据平面
kubectl get felixconfiguration default -o jsonpath='{.spec.bpfEnabled}'

# 切换为 eBPF(需先确认内核版本)
kubectl patch felixconfiguration default --type merge \
  -p '{"spec":{"bpfEnabled":true}}'

# 回退到 iptables
kubectl patch felixconfiguration default --type merge \
  -p '{"spec":{"bpfEnabled":false}}'

切换前必须确认内核版本满足要求,可用 uname -r 检查;同时确认节点上没有依赖 iptables 规则的旁路组件(如某些旧版 kube-proxy 模式)。切换过程中 felix 会重建数据平面,存量连接可能短暂中断,建议在维护窗口执行。Windows 节点则通过 calico-node 的 FELIX_WINDOWSNETWORKSTACK 等环境变量控制,通常随安装方式确定,运行中切换风险较高。

切换数据平面后,务必用 calicoctl node status 和实际 Pod 间连通性测试验证策略是否仍按预期生效,不要仅凭组件 Running 就判定成功。

四、选型建议

场景推荐数据平面理由
内核较旧、追求稳定兼容iptables兼容性最好,排障直观
大规模 Linux 集群、低延迟要求eBPFmap 查找高效,支持 DSR
混合 Windows 节点Windows HNSWindows 唯一可行方案
需要细粒度流量可观测eBPF可挂载观测程序,指标更丰富

实际生产中,Linux 与 Windows 节点可以共存于同一 Calico 集群,各自使用适配的数据平面,但跨平台策略语义需要仔细核对。选型的核心不是追求最新,而是让数据平面与节点能力、业务延迟目标和运维习惯匹配。