kube-iptables与ipvs模式的性能对比与分析
背景:iptables代理模式
iptables 是一个 Linux 核心功能旨在成为一种高效的防火墙,具有足够的灵活性来处理各种常见的数据包操作和过滤要求。它允许在内核数据包处理管道中的各种钩子上附加灵活的规则序列。在 iptables 模式下,kube-proxy 将规则附加到“NAT “预路由”钩子实现 NAT 负载平衡功能。但是,kube-proxy 对 iptables 规则编程意味着它是一种 O(n) 算法,其中 n 增长与您的集群大小大致相同(或者更准确地说,每个服务背后的服务数量和后端) pod 数量)成正比)。
背景:IPVS代理模式
IPVS 它是专为负载平衡而设计的 Linux 内核功能。在 IPVS 模式下,kube-proxy 对 IPVS 编程负载均衡器而不是使用负载均衡器 iptables。IPVS 是 设计了大量的负载平衡服务;它是优化的 API 搜索和优化的例程,而不是顺序规则列表。kube-proxy 在 IPVS 名义上的计算复杂性是模式下的连接处理 O(1)。换句话说,在大多数情况下,它的连接处理性能将保持不变,与您的集群大小无关。
另外,作为一种特殊的负载均衡器,IPVS 有很多不同的调度算法,例如,循环、最短预期延迟、最少连接和各种散列方法。相比之下,iptables 中的 kube-proxy 使用随机等成本选择算法。
oube-proxy在iptables模式下的连接处理是oube-proxy(n),O(1)在IPVS模式下。但是,现实中的差距是什么呢?
在大多数情况下,当涉及到应用程序和微服务时 kube-proxy 在性能方面,您可能会关心两个关键属性:
1、影响往返响应时间。当一个微服务对另一个微服务进行时 API 调用时,第一个微服务需要多长时间才能向第二个微服务发送请求,并从第二个微服务接收响应?
2、对总 CPU 利用率的影响。支持微服务(包括 kube-proxy)在所需的所有过程中,主机在运行微服务时的总数 CPU 包括用户空间和内核/系统在内的使用率是多少?
测试场景:
“客户端”微服务在一个特殊节点上运行 pod,每秒向 Kubernetes 服务生成 1000 个请求,该 Kubernetes 集群中其他节点运行的服务 10 “服务器”微服务 pod 支持。
然后,在 iptables 和 IPVS 在模式下测量客户端节点的性能,包括不同数量 Kubernetes 服务,每个服务由 10 个 pod 支持,最多 10,000 服务(有 100,000 服务后端)。
我们使用微服务 golang 作为客户端微服务编制的简单测试工具,并采用标准 NGINX 后端作为服务器微服务 pod。
性能测试结果:
在考虑往返响应时间时,了解连接与请求之间的区别是非常重要的。通常,大多数微服务都会使用持久连接或“keepalive“连接,这意味着每个连接都可以在多个请求中重用,而不是每个请求都需要新的连接。这是非常重要的,因为大多数新连接需要通过网络三次 TCP 握手(这需要时间) Linux 更多的网络堆栈处理(这需要更多的时间和时间) CPU)。
为了说明这些差异,我们在使用和不使用时进行了测试。对于 keepalive 我们使用的连接 NGINX 默认配置,使每个连接保持活动状态,最多 100 请求重复使用。请参见下图,并注意响应时间越短越好。
图表显示了两个关键内容:
结果分析:
在超过 1,000 个服务(10,000 个后端 pod)之前,iptables 和 IPVS 平均往返响应时间的差异是微不足道的。平均往返响应时间的差异只是不使用 keepalive 只有在连接时才能识别。也就是说,当每个请求使用新的连接时。
重点注意:
1、对于 iptables 和 IPVS 模式,kube-proxy 响应时间费用与建立连接有关,而不是您在这些连接上发送的数据包或请求的数量。这是因为 Linux 使用连接跟踪 (conntrack) 数据包可以与现有连接非常有效地匹配。若一个数据包在里面 conntrack 如果中匹配,则不需要通过 kube-proxy 的 iptables 或 IPVS 规则来决定如何处理它。
2、我们使用了本示例中的“服务器”微服务 NGINX pod 提供小型静态响应体。许多微服务需要比这更多的工作,这将导致更高的响应时间,这意味着与图表相比,kube-proxy 响应时间的百分比较小。
最后还有一个奇怪的解释:
如果 IPVS 处理中新连接的复杂性是 O(1),为什么? IPVS 在 10,000 非保存响应时间会减慢吗?为了真正理解这一点,我们需要做更多的挖掘,但其中一个因素是由于主机 CPU 随着利用率的提高,整个系统会变慢。
性能测试结果:CPU总利用率
结果分析:
1、iptables 和 IPVS 之间的 CPU 利用率的差异相对微不足道,直到你得到超过 1,000 服务(有 10,000 个后端 pod)。
2、在 10,000 服务(有 100,000 个后端 pod)时,使用 iptables 的 CPU 增加约为内核 35%,而使用 IPVS 的 CPU 增加约为内核 8%。
原因分析:
kube-proxy 使用 iptables 或 IPVS 处理新连接所需的时间 iptables,这名义上是 O(n)。这将显著增加大量的服务 CPU 使用率。例如,在 10,000 服务(带 100,000 个后端 pod)的情况下,iptables 为每个新连接执行约数万条规则。请记住,在这张图中,我们展示了微服务的最坏情况,即每个请求都使用新的连接。
注意:
假如我们用它 NGINX 的默认 keepalive(每个连接 100 一个请求),所以 kube-proxy 的 iptables 规则的执行频率会降低 100 倍