4. Cilium 网络数据路径详解:Pod 到 Pod、Pod 到 Service、Pod 到外部网络的完整数据包流转路径
在 Serverless 平台中,理解 Cilium 的数据路径是诊断网络性能瓶颈的基础。Cilium 基于 eBPF 技术,将网络策略、负载均衡和可观测性下沉到内核层面,绕过了传统的 iptables 和 kube-proxy 开销。本章将拆解三种核心场景的数据包流转路径,帮助你在性能调优时精准定位延迟和丢包点。
4.1 核心数据路径总览
Cilium 的数据路径主要依赖以下内核 eBPF 钩子点:
| 钩子点 | 挂载位置 | 作用 |
|---|---|---|
| TC Ingress | veth pair 宿主机端 | 入口流量分类、策略执行、封装/解封装 |
| TC Egress | veth pair 宿主机端 | 出口流量分类、策略执行、封装/解封装 |
| XDP | 物理网卡驱动层 | 早期丢包、DDoS 防护、高性能转发(可选) |
| cgroup/sock | Socket 层 | 四层负载均衡(Service 后端选择) |
| kprobe/tracepoint | 内核函数 | 可观测性、指标采集 |
性能要点: Cilium 默认使用 TC 钩子实现完整的数据路径。XDP 模式仅在物理网卡支持且开启
loadBalancer.mode=dsr 或 bandwidthManager 时启用,可进一步降低 CPU 开销。
4.2 场景一:Pod 到 Pod(同节点 & 跨节点)
Pod 到 Pod 通信是 Serverless 函数间调用的基础路径。Cilium 通过 eBPF 直接在内核中完成路由和封装,无需经过主机网络栈的 iptables 或路由表。
4.2.1 同节点 Pod 到 Pod
当两个 Pod 位于同一 Kubernetes 节点时,数据包路径最短,延迟最低。
- 源 Pod 发出数据包:数据包从 Pod 的 netns 通过 veth pair 到达宿主机端(
lxcXXXX接口)。 - TC Egress 钩子(宿主机端):Cilium 的 eBPF 程序在
BPF_PROG_TYPE_SCHED_CLS中执行:- 查找源 Pod 的安全标识(Security Identity)。
- 根据目标 IP 查询本地 endpoint 映射表(
cilium_lxcmap)。 - 如果目标 IP 属于本地 Pod,直接通过 veth pair 转发到目标 Pod 的 netns。
- 执行网络策略检查(L3/L4/L7)。
- 目标 Pod 接收:数据包从宿主机端 veth 进入目标 Pod 的 netns,完成通信。
性能特征: 同节点 Pod 到 Pod 的路径仅经过两次 veth 对和一次 eBPF 策略检查,延迟通常在 10-30μs 级别,是 Cilium 中最高效的路径。
4.2.2 跨节点 Pod 到 Pod
跨节点通信需要封装或路由。Cilium 支持两种覆盖网络模式:VXLAN 和 Geneve(默认),以及直接路由模式。
- 源 Pod 发出数据包:同节点步骤 1。
- TC Egress 钩子:eBPF 程序发现目标 IP 不在本地 endpoint 映射表中,查询全局 identity 和 node 映射。
- 封装决策:
- 覆盖网络模式:eBPF 程序将原始数据包封装为 VXLAN/Geneve 报文,外层 UDP 头目标 IP 为对端节点 IP。
- 直接路由模式:eBPF 程序直接修改数据包的目标 MAC 地址为对端节点 MAC,通过主机路由表转发。
- 物理网卡发送:封装后的数据包通过主机路由和物理网卡发送到对端节点。
- 对端节点接收:物理网卡收到数据包,TC Ingress 钩子解封装(覆盖网络模式)或直接路由到本地 endpoint。
- 目标 Pod 接收:解封装后的原始数据包通过 veth pair 进入目标 Pod。
性能瓶颈点: 跨节点路径中,VXLAN 封装/解封装会引入额外的 CPU 开销和 MTU 问题(外层 50 字节头)。如果物理网络 MTU 为 1500,Pod 内 MTU 应设置为 1450,否则会导致分片和性能下降。直接路由模式可避免封装开销,但要求底层网络支持 Pod IP 路由。
4.3 场景二:Pod 到 Service
Serverless 平台中,Service 用于函数服务的抽象和负载均衡。Cilium 使用 eBPF 在 socket 层实现高效的 Service 后端选择,完全替代 kube-proxy 的 iptables/IPVS 模式。
4.3.1 数据路径步骤
- Pod 发起 Service 请求:源 Pod 发出目标 IP 为 ClusterIP 的数据包。
- cgroup/sock 钩子(socket 层):Cilium 的 eBPF 程序在
BPF_PROG_TYPE_CGROUP_SOCK_ADDR中拦截 connect() 系统调用:- 查找 Service 映射表(
cilium_lb4_servicesmap)。 - 根据负载均衡算法(默认为 Maglev 一致性哈希)选择一个后端 Pod IP。
- 在 socket 层直接替换目标 IP 为后端 Pod IP(DNAT)。
- 查找 Service 映射表(
- 后续路径:替换后的数据包按照 Pod 到 Pod 路径(同节点或跨节点)转发。
- 回程路径:后端 Pod 返回数据包时,Cilium 的 eBPF 程序在 socket 层将源 IP 替换回 ClusterIP(SNAT),确保客户端感知不到后端变化。
性能优势: 相比 kube-proxy 的 iptables 模式(每个 Service 需要遍历规则链),Cilium 的 socket 层负载均衡是 O(1) 的哈希查找,延迟降低 60-80%。Maglev 算法保证连接一致性,减少后端变更时的连接抖动。
4.3.2 Service 路径关键参数
| 参数 | 默认值 | 调优建议 |
|---|---|---|
loadBalancer.algorithm | maglev | Serverless 场景建议保持默认,Maglev 在大量后端时表现稳定 |
loadBalancer.mode | snat | DSR 模式可避免回程 SNAT 开销,但要求后端 Pod 支持直接路由 |
k8sServiceCache | enabled | 开启后 Service 变更事件直接更新 eBPF map,无需重启代理 |
4.4 场景三:Pod 到外部网络
Serverless 函数经常需要访问外部服务(如数据库、API 网关)。Cilium 通过 eBPF 实现 SNAT 和策略控制,确保外部流量可管理。
4.4.1 数据路径步骤
- Pod 发出外部请求:源 Pod 发出目标 IP 为外部地址的数据包(非 ClusterIP、非节点网络)。
- TC Egress 钩子:eBPF 程序判断目标 IP 不在本地或集群网络范围内,标记为外部流量。
- SNAT 转换:Cilium 的 eBPF 程序在
BPF_FIB_LOOKUP辅助函数协助下,将源 IP 替换为节点 IP(或 egress IP),并记录连接跟踪条目。 - 策略检查:如果配置了 Egress 策略(基于 FQDN 或 CIDR),eBPF 程序在此处执行允许/拒绝决策。
- 物理网卡发送:SNAT 后的数据包通过主机路由和物理网卡发送到外部网关。
- 回程路径:外部响应到达节点物理网卡,TC Ingress 钩子根据连接跟踪条目将目标 IP 还原为 Pod IP(反向 SNAT),然后转发到目标 Pod。
调优要点: 外部流量路径中,连接跟踪表(conntrack)的大小和老化时间直接影响性能。在 Serverless 场景下,函数调用频繁创建和销毁连接,建议将
bpf.ctGlobalMaxEntries 调高至 512K 以上,并缩短 bpf.ctTcpCloseTimeout 为 30s,避免连接跟踪表溢出。
4.5 三种场景路径对比总结
| 场景 | 关键钩子点 | 额外开销 | 典型延迟 | 主要瓶颈 |
|---|---|---|---|---|
| Pod → Pod(同节点) | TC Egress/Ingress | 无 | 10-30μs | veth 对性能、eBPF 策略复杂度 |
| Pod → Pod(跨节点) | TC Egress/Ingress + 封装 | VXLAN 封装/解封装 | 50-200μs | MTU 分片、封装 CPU 开销、网络延迟 |
| Pod → Service | cgroup/sock + TC | Socket 层 DNAT/SNAT | 20-50μs | Service 后端变更时的连接一致性 |
| Pod → 外部网络 | TC Egress/Ingress + SNAT | SNAT + 连接跟踪 | 100-500μs | 连接跟踪表大小、外部网络延迟 |
诊断提示: 在 Serverless 平台中,如果观察到函数调用延迟抖动,优先检查跨节点路径的 MTU 配置和 VXLAN 封装 CPU 使用率。使用
cilium monitor 命令可以实时查看数据包路径和策略命中情况,快速定位丢包或延迟点。