当前位置: 首页 > 科技观察

eBPF在哪些场景下不适用?

时间:2023-03-17 10:32:08 科技观察

翻译|陈浩策划|YunZhaoExtendedBerkeleyPacketFilter(eBPF)是Linux内核中的一项相对较新的功能,令许多DevOps专业人员、SRE和工程师兴奋不已。eBPF甚至可以与标准的Linuxiptables相媲美。但它真的可以成为满足您所有Linux内核需求的“一站式商店”吗?eBPF在那个时候对内核进行更改很困难。开发者虽然可以调用API获取数据,但不能影响内核内部的执行代码。相反,您必须向Linux社区提交补丁并等待其获得批准。使用eBPF,可以将程序加载到内核中,并在例如看到某个数据包或发生其他事件时指示执行该程序。eBPF是Linux内核中的一项功能,允许您在内核中运行虚拟机。该虚拟机允许您安全地将程序加载到内核中以自定义其操作。为什么这很重要?使用eBPF,内核及其行为变得高度可定制,而不是固定的。在适当的情况下使用时,这会非常有益。典型用例eBPF有几个典型用例,包括流量控制、创建网络策略、连接时负载平衡和可观察性。流量控制没有eBPF,数据包在到达最终目的地的途中使用标准的Linux网络路径。如果一个数据包来自A点,并且你知道该数据包需要去往B点,你可以通过直接将它发送到B点来优化Linux内核中的网络路径。使用eBPF,你可以利用额外的上下文来在内核中进行这些更改使数据包绕过复杂的路由并简单地到达它们的最终目的地。这在具有广泛网络的Kubernetes容器环境中尤为重要。(除了主机网络堆栈,每个容器都有自己的迷你网络堆栈。)当流量进来时,它通常被路由到容器堆栈,并且必须经过复杂的路径才能从主机堆栈到达那里。可以使用eBPF绕过此路由。创建网络策略在创建网络策略时,有两种情况可以使用eBPF:1.eXpress数据路径(XDP)–eBPF为您提供了一种有效的方法来检查进入系统区域的原始数据包缓冲区,并快速决定如何处理它。2.网络策略——eBPF允许您有效地检查数据包并为pod和主机应用网络策略。连接时负载均衡在Kubernetes中负载均衡服务连接时,端口需要与服务通信,因此必须进行网络地址转换(NAT)。数据包被发送到虚拟IP,虚拟IP将其转换为支持该服务的pod的目标IP;然后pod响应虚拟IP,返回的数据包被转换回源。使用eBPF,您可以通过使用已加载到内核中的eBPF程序并在连接源进行负载平衡来避免这种数据包转换。由于不需要在数据包处理路径上进行目标网络地址转换(DNAT),因此消除了服务连接的所有NAT开销。可观察性收集统计数据和深度调试内核是eBPF用于可观察性的两种有用方式。一个eBPF程序可以附加到内核中的许多不同函数,提供对函数正在处理的数据的访问,同时还允许修改该数据。例如,使用eBPF,如果建立了网络连接,则可以在创建套接字时接收调用。将套接字调用作为事件接收非常有用,由eBPF在打开套接字的程序的上下文中提供,因此您可以获得有关哪个进程正在打开它以及套接字发生了什么的信息。性能的代价所以eBPF比标准的Linuxiptables更高效?这取决于。如果您要对iptables在应用具有大量IP地址(即ipsets)的网络策略时的工作方式进行微基准测试,那么在许多情况下iptables优于eBPF。但是如果你想在Linux内核中做一些需要改变内核中数据包流的事情,eBPF会是更好的选择。标准的Linuxiptables是一个复杂的系统,当然有其局限性,但同时它提供了操纵流量的选项;如果您不知道如何编写iptables规则,将很难进步。eBPF允许将您自己的程序加载到内核中以按需影响行为,因此它比iptables更灵活,因为它不受一组规则的限制。另一点需要考虑的是,虽然eBPF允许您运行程序、添加逻辑、重定向流和绕过处理——这绝对是一个胜利——但它是一个虚拟机,因此必须被翻译成字节码。相比之下,Linux内核的iptables已经被编译成代码。如您所见,将eBPF与iptables进行简单比较没有多大意义。我们需要评估的是性能,这里要看的两个关键因素是延迟(速度)和开销。如果eBPF非常快但占用了你80%的资源,它就像一辆兰博基尼——一辆昂贵的快车。如果这对您有用,那就太好了(也许您真的喜欢昂贵的快车)。请注意,更多的CPU使用率意味着在您的云提供商上花费更多的钱。因此,虽然兰博基尼可能比许多其他汽车更快,但如果您需要在日常通勤中遵守速度限制,那么它可能不是最好的花钱方式。什么时候使用eBPF(什么时候不使用)想要获得高性能,自然是要付出代价的。在使用eBPFizer之前,您需要先计算一下它的性能价格,以确定是否可以接受,从而在两者之间找到一个平衡点。下面是使用eBPF的一些特定场景,包括它可以工作和不工作的场景。何时不使用eBPF来执行应用层策略-由于性价比权衡,使用eBPF执行深度协议检查和执行应用层策略不是很有效。您可以利用Linux内核的连接跟踪器来实施策略,对每个流应用一次策略(无论该流有5个数据包还是5,000个数据包)并在Linuxconntrack表中将其标记为允许或拒绝。您不需要一直检查流中的每个数据包。如果您要使用eBPF执行策略,它允许您在单个TCP连接上进行多个HTTP事务,则您需要检查每个数据包以检测这些事务,然后执行第7层控制。为此,您需要执行CPU周期,这可能会变得昂贵。一种更高效的方法是像Envoy一样获取代理,并使用eBPF优化Envoy的流量,同时让Envoy为您翻译应用程序协议。带有像Envoy这样的代理的iptables是一个更好的设计,在这种情况下会是更好的选择。构建服务网格控制平面——类似地,服务网格依赖于像Envoy这样的代理。多年来,在设计这个方面已经有很多想法。这样做的主要原因是,在很多情况下,在集群内部高速内联处理HTTP等应用协议是不可行的。因此,与其用它来代替代理本身,不如考虑使用eBPF以高效的方式将流量路由到像Envoy这样的代理。按数据包处理——使用eBPF执行CPU密集型或按数据包处理,例如加密流的解密和重新加密,效率不高,因为您需要构建结构并查找每个数据包,这是昂贵的。何时使用XDP-eBPF提供了一种在原始数据包缓冲区进入系统时检查它们的有效方法,使您可以快速决定如何处理它们。连接上的负载平衡——使用eBPF,您可以使用加载到内核中的程序在源头进行负载平衡,而不是使用虚拟IP。由于DNAT不需要在数据包处理路径上进行,因此消除了所有用于服务连接的NAT开销。可观察性——eBPF程序是在Linux内核中为上下文丰富的数据添加探测器作为传感器的绝佳方式。这是一个巨大的好处,因为可以在不更改内核的情况下启用跟踪和分析。您可以轻松地在打开套接字的程序的上下文中接收套接字调用,或者添加一个程序来跟踪内核中的系统调用。在我们看来,可观察性是eBPF最有益的用例。写在最后eBPF是iptables的替代品吗?不完全的。很难想象使用eBPF和使用iptables一样高效。目前两者并存,用户可以权衡性价比,根据自己的具体需求决定何时使用哪种功能。我们相信正确的解决方案是利用eBPF以及Linux内核中的现有机制来实现您想要的结果。这就是为什么一些开源解决方案支持多个数据平面,例如标准Linux、WindowsHNS、LinuxeBPF等。既然我们已经确定eBPF和iptables都是有用的,那么唯一合乎逻辑的事情就是拥抱两者。译者介绍陈浩,社区编辑,资深系统工程师,6年工作经验。擅长的技能包括Linux嵌入式汇编语言、Python、C、C++、Java、Linux内核分析、智能机器人软件设计等。原标题:When(AndWhenNot)toUseeBPF,作者:ManishSampat链接:https://containerjournal.com/topics/when-and-when-not-to-use-ebpf/