This commit is contained in:
yunwei37
2024-09-26 01:17:19 +00:00
parent 9449556590
commit 5371b7c6a9
25 changed files with 245906 additions and 231346 deletions

View File

@@ -173,19 +173,81 @@
<div id="content" class="content">
<main>
<h1 id="ebpf-入门实践教程二十一使用-xdp-实现可编程包处理"><a class="header" href="#ebpf-入门实践教程二十一使用-xdp-实现可编程包处理">eBPF 入门实践教程二十一:使用 xdp 实现可编程包处理</a></h1>
<h2 id="背景"><a class="header" href="#背景">背景</a></h2>
<p>xdp(eXpress Data Path)是 Linux 内核中新兴的一种绕过内核的、可编程的包处理方案。相较于 cBPF,xdp 的挂载点非常底层,位于网络设备驱动的软中断处理过程,甚至早于 skb_buff 结构的分配。因此,在 xdp 上挂载 eBPF 程序适用于很多简单但次数极多的包处理操作(如防御 Dos 攻击),可以达到很高的性能(24Mpps/core)。</p>
<h2 id="xdp-概述"><a class="header" href="#xdp-概述">XDP 概述</a></h2>
<p>xdp 不是第一个支持可编程包处理的系统,在此之前,以 DPDK(Data Plane Development Kit)为代表的内核旁路方案甚至能够取得更高的性能,其思路为完全绕过内核,由用户态的网络应用接管网络设备,从而避免了用户态和内核态的切换开销。然而,这样的方式具有很多天然的缺陷:</p>
<h1 id="ebpf-入门实践教程二十一-使用-xdp-进行可编程数据包处理"><a class="header" href="#ebpf-入门实践教程二十一-使用-xdp-进行可编程数据包处理">eBPF 入门实践教程二十一: 使用 XDP 进行可编程数据包处理</a></h1>
<p>在本教程中,我们将介绍 XDP(eXpress Data Path),并通过一个简单的例子帮助你入门。之后,我们将探讨更高级的 XDP 应用,例如负载均衡器、防火墙及其他实际应用。如果你对 eBPF 或 XDP 感兴趣,请在 <a href="https://github.com/eunomia-bpf/bpf-developer-tutorial">Github</a> 上为我们点赞!</p>
<h2 id="什么是-xdp"><a class="header" href="#什么是-xdp">什么是 XDP?</a></h2>
<p>XDP 是 Linux 内核中的一种高性能可编程数据路径,专为网络接口级的数据包处理而设计。通过将 eBPF 程序直接附加到网络设备驱动程序上,XDP 能够在数据包到达内核网络栈之前拦截并处理它们。这使得 XDP 能够进行极低延迟和高效的数据包处理,非常适合如 DDoS 防护、负载均衡和流量过滤等任务。实际上,XDP 每核心的吞吐量可以高达 <strong>每秒 2400 万包(Mpps)</strong>。</p>
<h3 id="为什么选择-xdp"><a class="header" href="#为什么选择-xdp">为什么选择 XDP?</a></h3>
<p>XDP 运行在比传统 Linux 网络组件(如 cBPF)更低的层级,在网络设备驱动程序的软中断上下文中执行。它能够在数据包被内核标准网络栈处理之前对其进行处理,避免了创建 Linux 中表示网络数据包的 <code>skb_buff</code> 结构。这种早期处理为简单但频繁的操作(如丢弃恶意数据包或负载均衡服务器)带来了显著的性能提升。</p>
<p>与其他数据包处理机制相比,XDP 在性能和可用性之间取得了平衡,它利用了 Linux 内核的安全性和可靠性,同时通过可编程的 eBPF 提供了灵活性。</p>
<h2 id="xdp-与其他方法的比较"><a class="header" href="#xdp-与其他方法的比较">XDP 与其他方法的比较</a></h2>
<p>在 XDP 出现之前,一些解决方案通过完全绕过内核来加速数据包处理。其中一个显著的例子是 <strong>DPDK</strong>(数据平面开发工具包)。DPDK 允许用户空间应用程序直接控制网络设备,从而实现非常高的性能。然而,这种方法也存在一些权衡:</p>
<ol>
<li>
<p><strong>缺乏内核集成</strong>:DPDK 及其他内核绕过解决方案无法利用现有的内核网络功能,开发者必须在用户空间重新实现许多协议和功能。</p>
</li>
<li>
<p><strong>安全边界</strong>:这些绕过技术破坏了内核的安全模型,使得难以利用内核提供的安全工具。</p>
</li>
<li>
<p><strong>用户空间与内核的转换开销</strong>:当用户空间数据包处理需要与传统内核网络交互时(例如基于套接字的应用程序),数据包必须重新注入到内核中,增加了开销和复杂性。</p>
</li>
<li>
<p><strong>专用 CPU 使用</strong>:为了处理高流量,DPDK 和类似解决方案通常需要专用的 CPU 核心来处理数据包,这限制了通用系统的可扩展性和效率。</p>
</li>
</ol>
<p>另一个替代 XDP 的方法是使用 Linux 网络栈中的 <strong>内核模块</strong> 或 <strong>挂钩</strong>。虽然这种方法可以很好地集成现有的内核功能,但它需要大量的内核修改,且由于在数据包处理管道的后期运行,无法提供与 XDP 相同的性能优势。</p>
<h3 id="xdp--ebpf-的优势"><a class="header" href="#xdp--ebpf-的优势">XDP + eBPF 的优势</a></h3>
<p>XDP 与 eBPF 结合提供了介于内核绕过方案(如 DPDK)和内核集成方案之间的中间地带。以下是 XDP + eBPF 脱颖而出的原因:</p>
<ul>
<li>无法与内核中成熟的网络模块集成,而不得不在用户态将其重新实现;</li>
<li>破坏了内核的安全边界,使得内核提供的很多网络工具变得不可用;</li>
<li>在与常规的 socket 交互时,需要从用户态重新将包注入到内核;</li>
<li>需要占用一个或多个单独的 CPU 来进行包处理;</li>
<li>
<p><strong>高性能</strong>:通过在网络接口卡(NIC)驱动程序级别拦截数据包,XDP 可以实现接近线速的性能,用于丢弃、重定向或负载均衡数据包,同时保持低资源消耗。</p>
</li>
<li>
<p><strong>内核集成</strong>:与 DPDK 不同,XDP 在 Linux 内核中工作,允许与现有的内核网络栈和工具(如 <code>iptables</code>、<code>nftables</code> 或套接字)无缝交互。无需在用户空间重新实现网络协议。</p>
</li>
<li>
<p><strong>安全性</strong>:eBPF 虚拟机确保用户定义的 XDP 程序是被隔离的,不会对内核造成不稳定影响。eBPF 的安全模型防止恶意或有缺陷的代码损害系统,提供了一个安全的可编程数据包处理环境。</p>
</li>
<li>
<p><strong>不需要专用 CPU</strong>:XDP 允许数据包处理而无需将整个 CPU 核心专用于网络任务。这提高了系统的整体效率,允许更灵活的资源分配。</p>
</li>
</ul>
<p>总的来说,XDP + eBPF 提供了一种强大的可编程数据包处理解决方案,结合了高性能与内核集成的灵活性和安全性。它消除了完全绕过内核方案的缺点,同时保留了内核安全性和功能的优势。</p>
<h2 id="xdp-的项目和应用案例"><a class="header" href="#xdp-的项目和应用案例">XDP 的项目和应用案例</a></h2>
<p>XDP 已经在许多高调的项目中得到应用,这些项目展示了它在实际网络场景中的强大功能和灵活性:</p>
<h3 id="1-cilium"><a class="header" href="#1-cilium">1. <strong>Cilium</strong></a></h3>
<ul>
<li><strong>描述</strong>:Cilium 是一个为云原生环境(尤其是 Kubernetes)设计的开源网络、安全和可观测性工具。它利用 XDP 实现高性能的数据包过滤和负载均衡。</li>
<li><strong>应用案例</strong>:Cilium 将数据包过滤和安全策略卸载到 XDP,实现高吞吐量和低延迟的容器化环境流量管理,同时不牺牲可扩展性。</li>
<li><strong>链接</strong>:<a href="https://cilium.io/">Cilium</a></li>
</ul>
<h3 id="2-katran"><a class="header" href="#2-katran">2. <strong>Katran</strong></a></h3>
<ul>
<li><strong>描述</strong>:Katran 是由 Facebook 开发的第 4 层负载均衡器,优化了高可扩展性和性能。它使用 XDP 处理数据包转发,开销极小。</li>
<li><strong>应用案例</strong>:Katran 每秒处理数百万个数据包,高效地将流量分配到后端服务器上,利用 XDP 在大规模数据中心中实现低延迟和高性能的负载均衡。</li>
<li><strong>链接</strong>:<a href="https://github.com/facebookincubator/katran">Katran GitHub</a></li>
</ul>
<h3 id="3-cloudflare-的-xdp-ddos-保护"><a class="header" href="#3-cloudflare-的-xdp-ddos-保护">3. <strong>Cloudflare 的 XDP DDoS 保护</strong></a></h3>
<ul>
<li><strong>描述</strong>:Cloudflare 已经实现了基于 XDP 的实时 DDoS 缓解。通过在 NIC 级别处理数据包,Cloudflare 能够在恶意流量进入网络栈之前过滤掉攻击流量,最小化 DDoS 攻击对其系统的影响。</li>
<li><strong>应用案例</strong>:Cloudflare 利用 XDP 在管道早期丢弃恶意数据包,保护其基础设施免受大规模 DDoS 攻击,同时保持对合法流量的高可用性。</li>
<li><strong>链接</strong>:<a href="https://blog.cloudflare.com/l4drop-xdp-ebpf-based-ddos-mitigations/">Cloudflare 博客关于 XDP</a></li>
</ul>
<p>这些项目展示了 XDP 在不同领域的可扩展和高效的数据包处理能力,从安全和负载均衡到云原生网络。</p>
<h3 id="为什么选择-xdp-而不是其他方法"><a class="header" href="#为什么选择-xdp-而不是其他方法">为什么选择 XDP 而不是其他方法?</a></h3>
<p>与传统方法(如 <code>iptables</code>、<code>nftables</code> 或 <code>tc</code>)相比,XDP 提供了几个明显的优势:</p>
<ul>
<li>
<p><strong>速度与低开销</strong>:XDP 直接在 NIC 驱动程序中运行,绕过了内核的大部分开销,使数据包处理更快。</p>
</li>
<li>
<p><strong>可定制性</strong>:XDP 允许开发人员通过 eBPF 创建自定义的数据包处理程序,提供比传统工具(如 <code>iptables</code>)更大的灵活性和细粒度控制。</p>
</li>
<li>
<p><strong>资源效率</strong>:XDP 不需要像 DPDK 等用户空间解决方案那样将整个 CPU 核心专用于数据包处理,因此它是高性能网络的更高效选择。</p>
</li>
</ul>
<p>除此之外,利用内核模块和内核网络协议栈中的 hook 点也是一种思路,然而前者对内核的改动大,出错的代价高昂;后者在整套包处理流程中位置偏后,其效率不够理想。</p>
<p>总而言之,xdp + eBPF 为可编程包处理系统提出了一种更为稳健的思路,在某种程度上权衡了上述方案的种种优点和不足,获取较高性能的同时又不会对内核的包处理流程进行过多的改变,同时借助 eBPF 虚拟机的优势将用户定义的包处理过程进行隔离和限制,提高了安全性。</p>
<h2 id="编写-ebpf-程序"><a class="header" href="#编写-ebpf-程序">编写 eBPF 程序</a></h2>
<pre><code class="language-C">#include "vmlinux.h"
#include &lt;bpf/bpf_helpers.h&gt;