站长杂谈

为什么内核社区用BPF替换iptables

时间:2018-12-22 14:49 点击:

  Linux内核社区最近宣布了bpfilter,它将用Linux BPF支持的高性能网络过滤取代iptables的长期内核实现,同时保证Linux用户的无中断转换。作为tcpdump和Wireshark等流行工具背后的包过滤功能,BPF已经发展成为一个丰富的框架,以高度灵活的方式扩展Linux的功能,而不会牺牲性能和安全等关键属性。这种强大的组合使得Google,Facebook和 Netflix等Linux内核技术的前沿用户可以选择BPF,用于从网络安全和负载平衡到性能监控和故障排除。Netflix的Brendan Gregg首先称为BPF Superpowers对于Linux。小编将介绍这些“超级大国”如何呈现像iptables冗余这样的长期内核子系统,同时启用新的内核事例,这些事例很少有人能够想到。

  过去15年在Linux内核社区中为许多子系统(包括TCP/IP,iptables等)编写代码,使我能够近距离观察BPF的发展。我很快意识到BPF不仅仅是另一个功能,而是代表了一种基础技术转变,它将及时改变Linux内网络和安全的几乎所有方面。我开始贡献并成为其最大的支持者之一,与Alexei Starovoitov和Daniel Borkmann一起维持BPF上游。在这个镜头中,从iptables到bpfilter的转变只是BPF为现代领域重振Linux网络堆栈之旅的下一个合乎逻辑的步骤。要理解为什么这种转变如此令人兴奋,请允许我带您了解内核中iptables的历史。

  iptables和顺序过滤的根源

  多年来,iptables一直是在Linux上实现防火墙和数据包过滤器的主要工具。从早期开始,iptables及其前身ipchains已成为我个人Linux之旅的一部分。最初作为用户,之后作为内核开发人员。多年来,iptables一直是一种祝福和诅咒:它是灵活性和快速修复的祝福,在多个系统组件争夺谁安装iptables规则的环境中调试5K规则iptables设置时的诅咒。当iptables在20年前开始使用以取代其前身的ipchains时,防火墙功能的编写范围很简单:保护本地应用程序免受不必要的网络流量(INPUT链),保护发送不需要的网络流量的本地应用程序(OUTPUT链)过滤由Linux系统转发/路由的网络流量(FORWARD链)。那时,网络速度很慢,还记得调制解调器在拨入时发出的声音吗?这是iptables最初开发和设计的时代。实现iptables实现的访问控制列表(ACL)的标准做法是使用顺序的规则列表,即接收或发送的每个数据包逐个与规则列表进行匹配。然而,线性处理具有明显的巨大缺点,过滤分组的成本可以随着添加的规则的数量线性增加。

  一段时间过去了,网络速度提高了,iptables设置已经从十几个规则发展到成千上万的规则。从性能和延迟的角度来看,遍历顺序iptables列表变得无法忍受。社区很快发现了最常见的瓶颈:长长的规则列表拒绝或允许单独的IP地址和端口组合。这导致了ipset的引入。ipset允许将匹配IP地址和/或端口组合的规则列表压缩到哈希表中,以减少整体iptables规则的数量。从那时起,这就成了解决核心问题的一种解决方法。不幸的是,ipset并不能解决所有问题。一个突出的例子是 Kubernetes的kube-proxy一个组件,它使用iptables和规则来为服务提供负载平衡。它为服务所服务的每个后端安装多个iptables规则。对于添加到Kubernetes的每个服务,要遍历的iptables规则列表呈指数级增长。DNATKubeCon最近的一次演讲,在所有细节上都考察了kube-proxy性能。该演讲提供的测量显示随着服务数量的增长,不可预测的延迟和性能降低。它还揭示了iptables的另一个主要缺点:缺乏增量更新。每次添加新规则时都必须替换整个规则列表。这导致安装160K iptables规则的总持续时间为5小时,代表20K Kubernetes服务。

  使用基于IP/端口的机制通常具有许多其他明显的缺点,特别是在应用容器时代。容器经常被部署和拆除。这可能导致单个IP地址的生命周期短。容器可以使用IP地址几秒钟,然后几秒钟后由另一个容器重用。这会给依赖于使用IP地址进行安全过滤的系统带来压力,因为集群中的所有节点必须始终了解最新的IP到容器映射。虽然在群集中这几乎不困难,但群集之间的挑战变得极其困难。以上就是小编对于为什么内核社区用BPF替换iptables的一些简单看法,如果您也有相关的看法,欢迎前来和小编交流探讨。