cilium 开源版尚未支持 FIP

6 阅读2分钟

是这样的: LB 使用 EIP1 的情况下,如果再配置 一对一 External IP 和 internal IP DNAT 是冲突的。 最多也就是 LB 使用 EIP1 的情况下,最多只有 SNAT 还可以再复用 EIP1。 LB 和 一对一 DNAT 本质上对于一个 EIP,肯定是 二选一的。 也就是说,LB + FIP 是伪需求。LB + SNAT 是正常需求。LB 可以共享 EIP,同时也能满足端口访问的需求,可以理解是 FIP 的替代。

❯ 分析一个问题,cilium 作为 主 cni 模式,它的 bpf LB 替代 kubeproxy 的功能之外,是不是还支持 一对一 dnat 和 snat,也就是说为 pod 配置 Floating external ip(公有云场景的 FIP)

结论:Cilium 的 BPF LB 不支持真正的一对一 Floating IP(FIP)

Cilium BPF LB 实际覆盖的能力

  │      功能       │                                   说明                                    │                       是否一对一 NAT                        │
  ├─────────────────┼───────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────┤
  │ kube-proxy 替代 │ Service ClusterIP / NodePort / LoadBalancer / ExternalIP 的 DNAT 负载均衡 │ 否,是 多对一(VIP → 多个后端 Pod)                         │
  ├─────────────────┼───────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────┤
  │ Egress Gateway  │ 出向流量 SNAT,CiliumEgressGatewayPolicy CRD                              │ 仅 SNAT(出方向),且是 label 匹配的多 Pod → 一个 Egress IP │
  └─────────────────┴───────────────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────┘

Egress Gateway 与 FIP 的关键差异

从代码和文档可以确认 Egress Gateway 的工作方式:

  1. 仅处理出方向(Egress SNAT) - BPF 代码 bpf/lib/egress_gateway.h:155-180 中 egress_gw_snat_needed() 仅对出站流量做 SNAT - 将 Pod 源 IP 替换为 egress_ip(网关节点上的 IP)
  2. 不处理入方向 DNAT - 代码中没有任何 per-pod 的 Ingress DNAT 逻辑 - 回程流量 (egress_gw_reply_matches_policy) 只是做 conntrack 反向匹配来 de-SNAT,不是独立的入向 DNAT 映射
  3. 是"多对一"而非"一对一" - CRD 通过 podSelector + label 选择一批 Pod,所有匹配的 Pod 共享同一个 egressIP - BPF map key 是 (saddr, daddr) 的 LPM 匹配,不是 per-pod 的独占映射

真正的 FIP 需要什么

公有云场景的 Floating IP(如 OpenStack FIP、AWS EIP 绑定到 Pod)需要:

外部 IP (FIP) <--DNAT/SNAT--> Pod IP

入方向:dst=FIP → DNAT → dst=PodIP (外部访问 Pod) 出方向:src=PodIP → SNAT → src=FIP (Pod 访问外部)

这是双向一对一 NAT,Cilium 原生不具备此能力。

如何在 Cilium 体系下实现类似 FIP 的效果

  │                          方案                           │                                       说明                                       │
  ├─────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────┤
  │ 云厂商集成                                              │ AWS Pod ENI + EIP 直接绑定,绕过 NAT(VPC CNI 方案),但这不是 Cilium 自身功能   │
  ├─────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────┤
  │ Service type=LoadBalancer + externalTrafficPolicy=Local │ 可以给单 Pod 暴露一个外部 IP,但本质上走的是 Service LB,不是一对一 NAT          │
  ├─────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────┤
  │ Kube-OVN                                                │ 原生支持 IptablesEIP/FIP 和 OvnEip/OvnFip CRD,实现真正的 per-pod 双向一对一 NAT │
  ├─────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────┤
  │ Isovalent Enterprise (Cilium 企业版)                    │ 可能有增强的 Egress IP 功能,但开源版无此特性                                    │
  └─────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────┘
  

总结

Cilium 开源版的 BPF LB = kube-proxy 替代(Service 级 DNAT)+ Egress Gateway(出向 SNAT)。它缺少入方向的 per-pod DNAT,无法构成完整的 Floating IP 方案。如果需要 FIP 能力,需要额外的组件(云 VPC 集成、Kube-OVN 等)或等待 Cilium 社区/企业版扩展此功能。