本文地址:https://www.ebpf.top/post/cloudflare-replatforming-4

原文地址:https://ebpf.io/blog/cloudflare-replatforming-4/
作者:Cloudflare Engineering
发布时间:2026-10-02
翻译:狄卫华
许可:原文采用 CC BY 4.0 许可,本文为其中文翻译

本系列记录 Cloudflare 与 eBPF 的八年历程:从专用的 DDoS 工具,成长为其全球网络的可编程骨干。内容涵盖向 Linux 内核贡献代码、技术挑战、业务投资回报(ROI),以及给其他希望采用 eBPF 的公司的建议与运维策略。

在第 3 部分中,我们介绍了构建 Cloudflare 基于 eBPF 的网络数据路径所需的架构转变与上游合入工作。这些代码一旦合入,把数据路径移入内核就改变了运维边界。当每秒数百万个报文在驱动中经由 XDP 被直接丢弃、甚至早于 sk_buff 分配时,tcpdump 这类标准工具便彻底「失明」。同样,用户态计数器也常常掩盖那些损害服务可靠性的 CFS 限流或 I/O 延迟微突发。本文将详述 Cloudflare 如何借助 eBPF 从根本上改善其运维态势。我们将考察可观测性为何必须从零重建,例如实现定制的 XDP 抓包工具(xdpcap),以及导出高分辨率的内核直方图。更重要的是,我们将探讨这些可观测性收益,如何与自主的边缘本地缓解(l4drop)和 BPF LSM 热补丁相结合,直接转化为可度量的可靠性提升与更具韧性的集群运维。

1. eBPF 可观测性提升实践

在报文损坏、延迟尖峰、丢包、内存耗尽、调度异常以及 DDoS 验证等各类事件中,eBPF 可观测性工具在诊断与解决问题上都起到了决定性作用,其中包括 top、tcpdump、node_exporter 等传统工具完全无法提供任何可见性的情形。

1.1 调试「不可能发生」的报文损坏(flowtrackd 事件)

最复杂的事件之一是:Cloudflare 的 TCP 防护系统服务 flowtrackd 开始因报文损坏而崩溃,损坏发生在报文被接收之后、被处理之前,这种情形起初看上去根本不可能发生。

这个问题罕见、难以复现,且看似随机。工程师把 BPF 程序挂载到 ftrace 和 kprobe 跟踪点上,构建了一个「飞行记录仪」,在不压垮系统的前提下,跟踪单个报文描述符在内核环形缓冲区(ring buffer)中流转的生命周期。跟踪结果揭示了 Linux 内核 veth 驱动中的一个竞态条件:它在乱序处理报文,违反了 NAPI 的保证,导致内核覆写了应用仍在读取的内存缓冲区。修复方式是一个已合入上游的内核补丁。

1.2 借助 kfree_skb 跟踪解决神秘的 VoIP 丢包

多起客户升级工单报告,经由 Magic Transit 转发的 SIP(VoIP)流量出现间歇性故障。DoS 团队确认没有任何缓解措施在丢弃分片,问题似乎藏在 Linux 网络协议栈深处的某个地方。

一个 bpftrace 脚本钩入了 kfree_skb 跟踪点(每当套接字缓冲区被释放时内核都会调用该函数),揭示出由于针对客户的分片洪泛攻击,内核耗尽了 IP 分片重组缓冲区。已有的 Prometheus 指标证实,多个地点的大量服务器都已触及该上限。修复方式是调整缓冲区参数并缩短分片存活时间,使受影响的服务器数量降至接近零。tcpdump 能看到分片到达,却无从判断内核为何丢弃它们。只有借助 eBPF 跟踪 kfree_skb,拿到丢弃原因(drop reason)和内核调用栈,才能精确定位到负责丢弃的代码路径。

1.3 漂移流检测:一类全新的事件可观测性

漂移流(shifty flows)是指由于 ECMP 或负载均衡器哈希发生变化,TCP 连接在中途被送达另一台服务器。这类问题过去在大规模下根本无法检测。如今,eBPF 钩子(hook)会跟踪 TCP 重置与非正常的连接关闭,通过 ringbuffer 把事件发给用户态守护进程,以便做跨服务器关联。即便在整个集群中采用很低的采样率,系统也能持续检测到相当数量的漂移流。这一整类事件(因路由变化导致的 TCP 连接中断)此前完全不可见,Cloudflare 的多个团队多年来一直试图解决它。

1.4 细粒度指标与内核级分布式追踪(ebpf_exporter)

传统 Linux 指标依赖计数器,而计数器只能给出平均值。平均值常常掩盖那些给用户带来痛苦的「微尖峰」。Cloudflare 使用 ebpf_exporter 直接从内核采集高分辨率直方图,并结合 OpenTelemetry 追踪,使那些用传统工具看不见的性能事件得以做根因分析。

运行队列延迟直方图可以揭示进程何时因 CPU 饱和而在等待运行,即便平均 CPU 使用率看起来正常。对于 TCP 重传追踪,内核级追踪可以挂到用户态服务上,并与应用的请求 trace 关联起来:「如果我们看到某个请求的 trace 中有一段无法解释的空白,可能就有一段内核 span 告诉我们发生了一次重传,从而解释这段空白。」

eBPF span 还能显示 CFS 限流何时打断了应用工作(约 80ms 的工作周期之后跟着约 20ms 的限流)。在较长的时间尺度上,这对标准指标是不可见的;但作为 span 插入常规 trace 后,就变得精准可见。内核追踪可以只针对特定区域或特定请求启用,因此能用于有针对性的事件调查,而不会带来全集群范围的开销。

1.5 发现「看不见」的延迟尖峰(SSD 更换)

在一次常规的 SSD 更换中,平均延迟指标看起来可以接受。ebpf_exporter 直方图把 I/O 延迟分布以热力图形式可视化,揭示出一种双峰延迟分布:大多数写入很快,但有相当数量的写入耗时 500ms 到 1.0s。这在标准监控中不可见,却在损害缓存性能。发现这些尖峰后,工程师得以在该硬件造成更大范围的客户影响之前将其退回。

1.6 定位操作系统升级故障

在一次大版本操作系统升级(Debian Jessie 升级到 Stretch)期间,Cloudflare 遭遇了 CPU 负载神秘地飙升 5 倍。标准工具显示 CPU 很高,却解释不了原因。工程师用 eBPF 跟踪内核定时器指标,发现内存分配函数会停滞长达 12 秒,矛头直指一个 systemd bug:它破坏了 TCP 分段卸载(TCP segmentation offload),从而导致了内存分配停滞。

1.7 eBPF JIT 内存耗尽

工程师发现,某些服务器几乎耗尽了内核的 BPF JIT 内存上限,导致 eBPF 程序加载静默失败。没有崩溃,没有日志,只是程序加载不上。这影响了多个依赖 eBPF 的服务,其中包括 seccomp 这类安全关键功能。

调查使用 bpftrace 直接读取一个内核内部计数器,找出了哪些服务器已接近上限。团队随后对整个集群做了普查,摸清问题范围。

通过 bpftool prog list 进行系统性排查,团队找到了 BPF 程序内存消耗过高的来源,并编写了一个 ebpf_exporter 探针把该指标导出到 Prometheus,使这个此前不可见的内核内部计数器在全集群范围内变得可见。

2. eBPF 安全提升实践

虽然 eBPF 最常与网络数据路径和深度可观测性联系在一起,但 eBPF Linux 安全模块(LSM)钩子同样为集群安全运维带来了显著提升,而 XDP 也能迅速缓解哪怕规模最大的 DDoS 攻击。保护 20% 的互联网流量绝非易事,但 eBPF 在事件响应与安全工程上为 Cloudflare 带来了多方面的提升。

2.1 XDP l4drop:高吞吐、低 CPU 的 DDoS 攻击缓解

检测到事件后,缓解的速度与效率直接决定影响范围。在生产环境中,使用 XDP 的单台服务器每秒可丢弃超过 800 万个报文。在这类攻击期间,即便入站报文量增加了 40 倍,整体 CPU 使用率也只上升了约 10%。

在多起生产事件中,把 DDoS 缓解从 iptables 迁移到基于 XDP 的 l4drop,一贯表现出低数倍的 CPU 开销,同时能处理显著更高的报文速率。在有代表性的案例中,l4drop 丢弃的攻击流量要多得多,而消耗的 CPU 却只是 iptables 应对更小规模攻击时所需的一小部分。这种效率直接转化为更小的事件影响:缓解消耗的 CPU 越少,留给合法流量服务的容量就越多。

2.2 边缘本地 DDoS 检测(dosd):比集中式系统快若干数量级

影响最大的事件响应改进是 dosd:一个无主节点的分布式 L3/L4(后来扩展到 L7)DDoS 检测系统,运行在每一台边缘物理机上。dosd 把缓解规则直接送入同一台机器上基于 eBPF 的 l4drop XDP 流水线,省去了往返集中式数据中心的过程。

与此前的集中式系统(Gatebot)相比,可度量的速度提升包括:

  • 采样速度快若干数量级:边缘采样的速率远高于旧的集中式系统,使得收到攻击的服务器能立即完成检测并生成规则。
  • 以秒计,而非以分钟计:集中式系统需要把样本发送到核心数据中心处理,生成缓解措施,再传播回边缘并生效;在大规模攻击期间,这一过程可能需要数十秒甚至更久。dosd 只需几秒即可检测到攻击,持续优于集中式流水线。
  • 更高的灵敏度:由于 dosd 在本地以高得多的采样率分析流量,它能检测到那些低于集中式系统检测下限的小规模攻击。
  • 自动化缓解:绝大多数 L3/L4 DDoS 攻击如今都在本地被检测并缓解,无需人工干预。系统扩展之后,dosd 也在本地缓解了大多数第 7 层攻击。
  • 韧性提升:dosd 没有单点故障。每台服务器都独立参与整个 PoP 范围的威胁分析,这意味着即便核心数据中心不可达,攻击检测也仍会继续。

2.3 调试与验证此前不可见的丢包(xdpcap)

像 tcpdump 这样的标准工具,是在网络驱动处理完报文之后才钩入网络协议栈的。由于 eBPF/XDP 程序直接在驱动中运行(在操作系统分配 sk_buff 之前),在这一层被丢弃或重定向的报文对标准调试工具不可见。这会让最关键的缓解层上的事件调试无从下手。

xdpcap 是一款定制的抓包工具,通过 eBPF 调试 map 直接钩入 XDP 程序。它能在 XDP 流水线的每个阶段(sampler > l4drop > l4lb)抓包,支持与 tcpdump 兼容的过滤语法,按动作展示报文计数(XDPDrop、XDPPass、XDPTx、XDPAborted),并输出可管道传给 tcpdump 或在 Wireshark 中打开的 pcap。它还支持基于偏移的过滤,用于匹配 Unimog 封装流量内部的原始(封装前)报文。这让工程师在活跃事件期间能完整看见被丢弃的恶意流量,从而验证缓解措施是否正确生效、且没有丢弃合法流量。

2.4 安全事件预防:eBPF LSM 热补丁

eBPF 让 Cloudflare 能够立即响应内核零日漏洞,而无需重启服务器。eBPF LSM(Linux Security Module)程序充当动态的内核安全策略,可在不重启的情况下部署到整个集群。

它们可以阻止那些能导致提权的特定系统调用模式(例如限制带 CLONE_NEWUSER 的 unshare/clone),还可以用额外的 eBPF LSM 程序保护这些安全策略本身不被禁用。其开销可以忽略不计,只会在被限制的特定系统调用上带来少量周期损耗。内核安全漏洞可以立即得到缓解,而无需等待上游补丁或安排重启。eBPF LSM 的行为类似动态加载的内核模块,但具备 eBPF 验证器提供的安全保证。

3. 结语

正如这些事后复盘所示,eBPF 与深度内核追踪的结合,从根本上改变了 Linux 的运维、可靠性与安全。解决 veth 驱动中「不可能发生」的 NAPI 违规,或借助 kfree_skb 跟踪点发现 IP 分片耗尽,都表明 eBPF 是大规模系统运维的关键工具。

通过把遥测直接移入内核,并在边缘自主处理威胁缓解,Cloudflare 在降低 CPU 开销的同时,显著提升了集群的整体可靠性。然而,在庞大的集群上运营动态 BPF 追踪工具与 BPF LSM 安全策略,也带来了新的运维复杂性。在第 5 部分中,我们将考察 Cloudflare 如何管理这些 eBPF 对象的生命周期、确保安全的全集群分发,并在大规模下把 eBPF 投入运营的部署机制。

回顾本系列已发布的内容:

  • 在第 1 部分中,我们说明了 Cloudflare 为何把 eBPF 当作一个平台来押注,而不是一堆单点方案。
  • 在第 2 部分中,我们考察了标准 Linux 网络 API 无法支撑 Cloudflare 需求的那些地方,以及团队为填补这些缺口所构建的内容。
  • 在第 3 部分中,我们介绍了构建 Cloudflare 基于 eBPF 的网络数据路径所需的架构转变与上游合入工作。

延伸阅读

若还想顺着读,可看这几篇:

  1. Cloudflare 平台重塑:从硬件厂商锁定到可编程网络 eBPF 平台(上)
  2. Cloudflare 平台重塑:用 eBPF 填补 Linux 生态缺口(中)
  3. Cloudflare 平台重塑:落地 eBPF 的技术挑战与五项开创性成果(下)