K8S中iptables和ipvs区别比较 – 记忆角落

K8S中iptables和ipvs区别比较

/ 0评 / 1

K8S中iptables和ipvs区别比较

从k8s的1.8版本开始,并在v1.9中进入了beta,kube-proxy引入了IPVS模式,IPVS模式与iptables同样基于Netfilter,但是ipvs采用的hash表,iptables采用一条条的规则列表。

iptables又是为了防火墙设计的,集群数量越多iptables规则就越多,而iptables规则是从上到下匹配,所以效率就越是低下。因此当service数量达到一定规模时,hash查表的速度优势就会显现出来,从而提高service的服务性能。

每个节点的kube-proxy负责监听API serverserviceendpoint的变化情况。将变化信息写入本地userspace、iptables、ipvs来实现service负载均衡,使用NAT将vip流量转至endpoint中。由于userspace模式因为可靠性和性能(频繁切换内核/用户空间)早已经淘汰,所有的客户端请求svc,先经过iptables,然后再经过kube-proxy到pod,所以性能很差。

ipvs和iptables都是基于netfilter的,两者差别如下:

  1. ipvs 为大型集群提供了更好的可扩展性和性能
  2. ipvs 支持比 iptables 更复杂的负载均衡算法(最小负载、最少连接、加权等等)
  3. ipvs 支持服务器健康检查和连接重试等功能

在集群中不超过1000个服务的时候,iptables 和 ipvs并无太大的差异。而且由于iptables与网络策略实现的良好兼容性,iptables是个非常好的选择。当你的集群服务超过1000个时,而且服务之间链接大多没有开启keepalive,IPVS模式可能是一个不错的选择。

Iptables模式

kube-proxy就可以通过 ServiceInformer 感知到API Serverserviceendpoint的变化情况。

而作为对这个事件的响应,它就会在宿主机上创建这样一条iptables 规则(你可以通过 iptables-save 看到它)。这些规则捕获到service的clusterIP和port的流量,并将这些流量随机重定向到service后端Pod。对于每个endpoint对象,它生成选择后端Pod的iptables规则。

如果选择的第一个Pod没有响应,kube-proxy将检测到到第一个Pod的连接失败,并将自动重试另一个后端Pod。

拓扑图

image-20230108230309334

iptables是一个 Linux 内核功能,是一个高效的防火墙,并提供了大量的数据包处理和过滤方面的能力。

它可以在核心数据包处理管线上用 Hook 挂接一系列的规则。

iptables模式中 kube-proxyNAT pre-routing Hook中实现它的 NAT 和负载均衡功能。这种方法简单有效,依赖于成熟的内核功能,并且能够和其它跟 iptables 协作的应用融洽相处。

因为它纯粹是为防火墙而设计且基于内核规则列表,kube-proxy使用的是一种 O(n) 算法,其中的 n 随集群规模同步增长,所以这里的集群规模越大,更明确的说就是服务和后端 Pod 的数量越大,查询的时间就会越长。

一个例子是,在5000节点集群中使用NodePort服务,如果我们有2000个服务并且每个服务有10个 pod,这将在每个工作节点上至少产生20000个 iptable 记录,这会使内核非常繁忙。

image-20230108230537087

结论

kube-proxy 通过 iptables处理 Service的过程,其实需要在宿主机上设置相当多的iptables规则。而且kube-proxy还需要在控制循环里不断地刷新这些规则来确保它们始终是正确的。

不难想到,当你的宿主机上有大量 Pod 的时候,成百上千条iptables 规则不断地被刷新,会大量占用该宿主机的 CPU 资源,甚至会让宿主机“卡”在这个过程中。所以说,一直以来,基于iptablesService 实现,都是制约 Kubernetes项目承载更多量级的 Pod 的主要障碍。

ipvs模式

在 IPVS 模式下,kube-proxy监视Kubernetes服务和端点,调用 netlink 接口创建 IPVS 规则, 并定期将 IPVS 规则与 Kubernetes 服务和端点同步。

访问服务时,IPVS 将流量定向到后端Pod之一;IPVS代理模式基于类似于iptables模式的 netfilter挂钩函数, 但是使用哈希表作为基础数据结构,并且在内核空间中工作。

这意味着,与 iptables 模式下的kube-proxy相比,IPVS 模式下的 kube-proxy重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。

IPVS 模式的工作原理,其实跟iptables模式类似。当我们创建了前面的Service之后,kube-proxy首先会在宿主机上创建一个虚拟网卡(叫作:kube-ipvs0),并为它分配 Service VIP作为 IP 地址。接下来,kube-proxy 就会通过 Linux 的 IPVS 模块,为这个 IP 地址设置三个 IPVS 虚拟主机,并设置这三个虚拟主机之间使用轮询模式 (rr) 来作为负载均衡策略。

拓扑图

image-20230108231504262

IPVS 是一个用于负载均衡的 Linux 内核功能。IPVS 模式下,kube-proxy 使用 IPVS 负载均衡代替了iptable。这种模式同样有效,IPVS 的设计就是用来为大量服务进行负载均衡的,它有一套优化过的 API,使用优化的查找算法,而不是简单的从列表中查找规则。

这样一来,kube-proxy在 IPVS 模式下,其连接过程的复杂度为 O(1)。换句话说,多数情况下,他的连接处理效率是和集群规模无关的。

另外作为一个独立的负载均衡器,IPVS 包含了多种不同的负载均衡算法,例如轮询、最短期望延迟、最少连接以及各种哈希方法等。而iptables 就只有一种随机平等的选择算法。IPVS一个潜在缺点是,与正常情况下的数据包相比,由IPVS处理的数据包通过iptables筛选器hook的路径不同。如果打算将IPVS与其他使用iptables的程序一起使用,则需要研究它们是否可以一起正常工作。不过Ipvs代理模式已经推出很久了,很多组件已经适配的很好了,比如Calico

image-20230108231711422

结论

IPVS是专门设计用来做内核四层负载均衡的,由于使用了hash表的数据结构,因此相比iptables来说性能会更好。基于IPVS实现Service转发,Kubernetes几乎能够具备无限的水平扩展能力。随着Kubernetes的部署规模越来越大,应用越来越广泛,IPVS必然会取代iptables成为Kubernetes Service的默认实现后端。

总结

IPVS (IP Virtual Server,IP虚拟服务器)是基于Netfilter的、作为linux内核的一部分实现传输层负载均衡的技术,通常称为第4层LAN交换。IPVS集成在LVS(Linux Virtual Server)中,它在主机中运行,并在真实服务器集群前充当负载均衡器。IPVS可以将对TCP/UDP服务的请求转发给后端的真实服务器,并使真实服务器的服务在单个IP地址上显示为虚拟服务。因此IPVS天然支持Kubernetes Service

发表评论

您的电子邮箱地址不会被公开。