完整指南)
Cilium eBPF 数据面 IP 分片跟踪Fragment Handling完整指南【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/ciliumCilium 的 eBPF 数据面默认启用 IP 分片跟踪IP fragment tracking用于让不支持分段segmentation的协议典型如 UDP能够透明地传输超过链路 MTU 的大报文。本文以 Cilium 官方文档 fragmentation.rst 为核心结合仓库内 pkg/option/config.go、bpf/lib/ipv4.h、bpf/lib/ipv6.h 等源码系统讲解分片跟踪的启用/禁用开关、BPF map 容量参数、底层处理逻辑与配套监控指标帮助读者在真实集群中完成配置、排障与容量评估。为什么 Cilium 需要跟踪 IP 分片当网络报文长度超过路径上某个链路的 MTU最大传输单元时发送方或中间设备会把报文拆分为多个分片fragment。TCP 通过 MSS 协商避免这种情况但 UDP 等无连接协议没有分段机制只能依赖 IP 层分片来传递大报文。问题在于分片报文里只有第一个分片携带完整的 L4 头TCP/UDP 端口号后续分片只有 IP 层信息。而 Cilium 数据面做策略过滤、连接跟踪conntrack和负载均衡时都需要基于「五元组源/目的 IP、协议、源/目的端口」进行查找。如果不对分片做跟踪后续分片将因为查不到 L4 端口信息而无法完成 L4 语义的处理。为此Cilium 在 eBPF 数据面实现了分片跟踪机制收到第一个带 L4 头的分片时将「分片标识 → L4 端口对」写入一张 BPF map后续到达的不带 L4 头的分片通过同样的分片标识源地址、目的地址、IP 标识符、协议在 map 中查到端口信息从而复用与首片相同的 L4 语义完成查表。这样无论分片以何种顺序到达数据面都能正确执行策略与连接跟踪。核心配置项分片跟踪默认开启可通过以下cilium-agent命令行选项配置参数定义见 pkg/option/config.go命令行选项作用默认值--enable-ipv4-fragment-tracking启用/禁用 IPv4 分片跟踪启用默认开启--enable-ipv6-fragment-tracking启用/禁用 IPv6 分片跟踪启用默认开启--bpf-fragments-map-max控制使用 IP 分片的并发连接的最大数量即分片跟踪 BPF map 容量上限8k见下文「容量与边界」这三个选项分别映射到源码中的常量EnableIPv4FragmentsTrackingName、EnableIPv6FragmentsTrackingName与FragmentsMapEntriesName在 pkg/option/config.go 中通过 viper 解析为 Daemon 配置c.EnableIPv4FragmentsTracking vp.GetBool(EnableIPv4FragmentsTrackingName) c.EnableIPv6FragmentsTracking vp.GetBool(EnableIPv6FragmentsTrackingName) c.FragmentsMapEntries vp.GetInt(FragmentsMapEntriesName)配置注意事项这两个开关是相互独立的可以只跟踪 IPv4、只跟踪 IPv6或同时关闭关闭跟踪后不带 L4 头的分片将无法获得端口信息数据面会以DROP_FRAG_NOSUPPORT处理对应 BPF 代码ipv4_load_l4_ports/ipv6_load_l4_ports中enable_*_fragments配置为 false 的分支在 Helm 部署场景下对应 values 中的 agent 命令行参数可在安装时通过--set覆盖或直接修改 agent DaemonSet 的启动参数。底层实现分片跟踪 BPF map 与处理路径分片跟踪的核心数据载体是两张 BTF 类型的 BPF map在 BPF 代码中定义IPv4cilium_ipv4_frag_datagrams定义见 bpf/lib/ipv4.hIPv6cilium_ipv6_frag_datagrams定义见 bpf/lib/ipv6.h。map 的 key 是分片标识结构struct ipv4_frag_id/struct ipv6_frag_id由报文头字段构成struct ipv4_frag_id { __be32 daddr; __be32 saddr; __be16 id; /* IP Identification 字段 */ __u8 proto; ... } __packed;即以「目的地址 源地址 IP 标识符 协议号」唯一定位一个原始数据报datagramvalue 则保存该数据报的源端口与目的端口。分片处理主函数以 IPv4 为例核心处理函数ipv4_handle_fragmentation位于 bpf/lib/ipv4.h其逻辑分三种情况分片不带 L4 头后续分片调用ipv4_frag_get_l4ports在 map 中查找端口若查不到返回DROP_FRAG_NOT_FOUND表示首片尚未到达bpf/lib/ipv4.h分片带 L4 头且是分片首片或中间某片从报文加载源/目的端口然后map_update_elem将「分片标识 → 端口」写入cilium_ipv4_frag_datagrams。注意源码注释特别说明即使 map 写入失败也不返回错误当前报文仍可正常处理只是后续分片无法复用该记录bpf/lib/ipv4.h完整未分片报文直接加载 L4 端口不涉及 map。最终由ipv4_load_l4_ports统一入口按配置开关分发if (CONFIG(enable_ipv4_fragments)) return ipv4_handle_fragmentation(ctx, ip4, fraginfo, l4_off, dir, (struct ipv4_frag_l4ports *)ports); if (unlikely(!ipfrag_has_l4_header(fraginfo))) return DROP_FRAG_NOSUPPORT;IPv6 的处理路径与 IPv4 对称ipv6_handle_fragmentationbpf/lib/ipv6.h中有一个实现细节——利用 IPv6 头与ipv6_frag_id中 saddr/daddr 偏移相同的特性复用栈上空间避免额外的 32 字节拷贝先清零填充位、写入id与proto处理完毕后再恢复原值。这些 eBPF 程序通过DECLARE_CONFIG(bool, enable_ipv4_fragments, ...)bpf/lib/ipv4.h与 agent 侧参数联动实现开关与数据面的映射。容量与边界分片跟踪 map 的容量不是无上限的源码在 pkg/option/config.go 定义了硬边界FragmentsMapMin 1 8 // 256 FragmentsMapMax 1 16 // 65536--bpf-fragments-map-max的取值在 pkg/option/config.go 中被校验超出边界会直接导致 agent 启动失败并返回明确错误信息if c.FragmentsMapEntries FragmentsMapMin { return fmt.Errorf(specified max entries %d for fragment-tracking map must be greater or equal to %d, ...) } if c.FragmentsMapEntries FragmentsMapMax { return fmt.Errorf(specified max entries %d for fragment-tracking map must not exceed maximum %d, ...) }即该参数的可配置区间为256 ~ 65536。默认情况下IPv4 与 IPv6 分片跟踪 map 的节点级容量均为8k8192含义是「同一节点上最多同时有 8192 个分片数据报在途」见 Documentation/network/ebpf/maps.rst 的 BPF map 默认容量表。当数据报数量超过该上限时map 插入会失败意味着超出的数据报将无法获得端口关联可能影响对应流的 L4 处理。在分片流量密集的节点例如大量跨网传输大 UDP 报文应根据监控指标评估是否需要调大该值。监控指标确认分片是否发生1. 分片跟踪 map 压力指标检查以下两个 Prometheus 指标是否非零即可确认数据面是否处理过分片报文cilium_bpf_map_pressure{map_namecilium_ipv4_frag_datagrams}cilium_bpf_map_pressure{map_namecilium_ipv6_frag_datagrams}指标非零表示曾经有分片报文进入跟踪流程。同时cilium_bpf_map_pressure也能反映 map 的填充水位帮助判断 8k 默认容量是否接近极限、是否需要调大--bpf-fragments-map-max。2. MTU 错误消息指标分片行为往往由路径 MTU 不足触发Cilium 数据面会处理相应的 ICMP 报错消息。可通过以下指标观察mtu_error_message_totalCilium 数据面处理的 ICMPfragmentation_neededIPv4或 ICMPv6packet_too_big消息总数。该指标的实现位于 pkg/maps/metricsmap/metricsmap.go定义为fragNeededCountDesc: prometheus.NewDesc( prometheus.BuildFQName(metrics.Namespace, , mtu_error_message_total), Total number of icmp fragmentation-needed or icmpv6 packet-too-big messages processed, []string{metrics.LabelDirection}, nil, ),这类报文正是**路径 MTU 发现PMTUD**的基础它们的出现说明网络中某段路径上的报文尺寸超出了链路最大 MTU通常意味着需要排查 MTU 配置如隧道开销、VXLAN/Geneve 封装尺寸、底层网络巨型帧支持等。同一文件中还有一个配套指标fragmented_count_totalTotal number of fragmented packets processed by datapath可直接统计数据面处理的分片报文总数适合与mtu_error_message_total一起观察。指标使用小结指标含义典型用途cilium_bpf_map_pressure{map_namecilium_ipv4_frag_datagrams}IPv4 分片跟踪 map 压力/水位确认 IPv4 分片是否发生、评估 map 容量cilium_bpf_map_pressure{map_namecilium_ipv6_frag_datagrams}IPv6 分片跟踪 map 压力/水位确认 IPv6 分片是否发生、评估 map 容量mtu_error_message_totalICMP fragmentation_needed / ICMPv6 packet_too_big 处理数判断路径 MTU 是否不足、定位大报文被丢弃的根因fragmented_count_total数据面处理的分片报文总数量化分片流量规模测试验证NodePort 场景下的分片处理仓库的 BPF 测试套件为分片跟踪提供了端到端用例见 bpf/tests/tc_nodeport_lb_fragments.h。该测试通过ASSIGN_CONFIG(bool, enable_ipv4_fragments, true)与ASSIGN_CONFIG(bool, enable_ipv6_fragments, true)显式开启 IPv4/IPv6 分片跟踪bpf/tests/tc_nodeport_lb_fragments.h构造外部访问 NodePort 服务的 IPv4/IPv6 分片报文lb4_ns_nodeport_fragment1/2、lb6_ns_nodeport_fragment1/2等覆盖首片与后续分片校验分片经 DNAT 后仍能正确匹配 conntrack并检查分片相关指标键。这说明分片跟踪与负载均衡NodePort/LB路径紧密耦合——只有正确关联分片端口DNAT 后连接跟踪才能对同一条流的所有分片生效。读者在启用/调大分片跟踪配置后可参考该测试理解预期行为。运维建议与常见问题确认分片是否真的发生先查cilium_bpf_map_pressure{map_namecilium_ipv4_frag_datagrams}等指标全部为 0 说明当前网络路径没有分片流量无需调整任何参数。出现大量mtu_error_message_total时优先排查链路 MTU而不是盲目调大 map。大报文被丢弃、重传、性能劣化通常根因是 MTU 不匹配例如 Pod 网络接口 MTU 与底层网络不一致或隧道封装未考虑开销。map 容量接近上限时结合cilium_bpf_map_pressure的水位将--bpf-fragments-map-max在 256~65536 的合法区间内调大并重启 agent 生效。安全/合规考虑分片本身可能被用于绕过策略fragment evasion若业务明确不需要分片传输大 UDP 报文可在确认无分片流量后通过--enable-ipv4-fragment-trackingfalse/--enable-ipv6-fragment-trackingfalse关闭关闭后无 L4 头的分片会被DROP_FRAG_NOSUPPORT丢弃行为更严格。改动重启影响调整--bpf-fragments-map-max会导致分片跟踪 map 重建涉及存量分片流的短暂重学习建议在维护窗口执行。小结Cilium 的 IP 分片跟踪是保证 UDP 等协议大报文在 eBPF 数据面「透明穿越」的关键机制默认开启的 IPv4/IPv6 跟踪通过cilium_ipv4_frag_datagrams/cilium_ipv6_frag_datagrams两张 BPF map 将分片标识映射到 L4 端口使连接跟踪、策略与负载均衡对分片流保持完整语义。运维时可借助--enable-ipv4-fragment-tracking、--enable-ipv6-fragment-tracking、--bpf-fragments-map-max三个参数灵活控制并通过cilium_bpf_map_pressure与mtu_error_message_total等指标精准定位分片与 MTU 问题实现数据面的精细化调优。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考