kube-proxy的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 使用随机等成本选择算法。
性能比较 kube-proxy在iptables模式下的连接处理是O(n),在IPVS模式下是O(1)。但是,在现实中的差距是怎么样的呢?
在大多数情况下,当涉及到应用程序和微服务上下文中 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 为每个新连接执行约几万条规则。请记住,在此图表中,我们展示了微服务的最坏情况,即为每个请求使用新连接。
注意:
标签:iptables,服务,IPVS,ipvs,proxy,kube,连接 From: https://blog.51cto.com/u_12948550/6363223如果我们使用 NGINX 的默认 keepalive(每个连接 100 个请求),那么 kube-proxy 的 iptables 规则的执行频率会降低 100 倍