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

Kube-Proxy中使用Ipvs和Iptables的对比

时间:2023-03-12 08:45:55 科技观察

本文转载自微信公众号《运维开发故事》,作者无文案夏先生。转载本文请联系运维开发故事公众号。Iptables模式下的kube-proxy可以通过ServiceInformer感知APIServer中服务和端点的变化。为了响应这个事件,它会在主机上创建这样一个iptables规则(你可以通过iptables-save看到)。这些规则抓取服务的clusterIP和端口的流量,随机将流量重定向到服务的后端Pod。对于每个端点对象,它都会生成选择后端Pod的iptables规则。如果选择的第一个Pod没有响应,kube-proxy将检测到与第一个Pod的连接失败并自动重试另一个后端Pod。拓扑图:iptables是Linux内核的一个功能,一个高效的防火墙,提供大量的数据包处理和过滤能力。它可以使用Hook在核心数据包处理管道上挂接一系列规则。在iptables模式下,kube-proxy在NATpre-routingHook中实现了它的NAT和负载均衡功能。这种方法简单有效,依赖成熟的内核功能,可以和其他配合iptables的应用程序相处融洽。因为它纯粹是为防火墙设计的,并且基于内核规则列表,所以kube-proxy使用了一个O(n)的算法,其中n随着集群的大小同步增长,所以这里的集群规模越大,越具体服务和后端Pod的数量越大,查询时间就越长。举个例子,在一个5000节点的集群中使用NodePort服务,如果我们有2000个服务,每个服务有10个pod,这将在每个工作节点上生成至少20000个iptable记录,这会使内核非常繁忙。结论:kube-proxy通过iptables处理Service的过程其实需要在主机上设置相当多的iptables规则。而且,kube-proxy还需要在控制循环中不断刷新这些规则,以确保它们始终是正确的。不难想象,当你的宿主机上有大量的Pod时,几十万条iptables规则不断刷新,这会消耗宿主机大量的CPU资源,甚至让宿主机“卡”在这个过程中。因此,长期以来,基于iptables实现Service一直是制约Kubernetes项目承载更多数量级Pod的主要障碍。ipvs模式在IPVS模式下,kube-proxy监控Kubernetes服务和端点,调用netlink接口创建IPVS规则,并定期将IPVS规则与Kubernetes服务和端点同步。访问服务时,IPVS将流量定向到后端Pod之一。IPVS代理模式基于类似于iptables模式的netfilterhook函数,但使用哈希表作为底层数据结构,工作在内核空间。这意味着,与iptables模式下的kube-proxy相比,IPVS模式下的kube-proxy在同步代理规则时以更低的延迟和更好的性能重定向流量。与其他代理模式相比,IPVS模式还支持更高的网络流量吞吐量。IPVS模式的工作原理其实和iptables模式类似。当我们创建前面的Service时,kube-proxy会先在宿主机上创建一个虚拟网卡(称为:kube-ipvs0),并为其分配一个ServiceVIP作为IP地址。接下来kube-proxy会通过LinuxIPVS模块为这个IP地址设置三个IPVS虚拟主机,并在这三个虚拟主机之间设置round-robinmode(rr)作为负载均衡策略。拓扑图如下:IPVS是Linux内核的负载均衡特性。在IPVS模式下,kube-proxy使用IPVS负载均衡而不是iptable。这个模型也是有效的。IPVS旨在对大量服务进行负载均衡。它具有优化的API并使用优化的查找算法,而不是简单地从列表中查找规则。这样,IPVS模式下kube-proxy的连接过程复杂度为O(1)。也就是说,在大多数情况下,它的连接处理效率与簇大小无关。另外,作为一个独立的负载均衡器,IPVS包含了多种不同的负载均衡算法,如roundrobin、最短预期延迟、最少连接、各种hash方法等。而iptables只有一种随机均等的选择算法。IPVS的一个潜在缺点是IPVS处理的数据包通过iptables过滤器挂钩的路径与正常情况下的数据包不同。如果您打算将IPVS与其他使用iptables的程序一起使用,则需要调查它们是否可以一起正常工作。不过Ipvs代理模式已经推出很久了,很多组件已经很好的适配了,比如Calico。结论:IPVS专为内核四层负载均衡而设计。由于它使用了哈希表的数据结构,所以它的性能会比iptables更好。基于IPVS实现Service转发,Kubernetes几乎可以拥有无??限的水平扩展能力。随着Kubernetes的部署越来越大,应用越来越广泛,IPVS必然会取代iptables成为KubernetesService的默认实现后端。总结IPVS(IPVirtualServer,IP虚拟服务器)是一种基于Netfilter的技术,作为linux内核的一部分,在传输层实现负载均衡,通常称为四层局域网交换。IPVS集成在LVS(LinuxVirtualServer)中,运行在宿主机中,充当真实服务器集群前的负载均衡器。IPVS可以将对TCP/UDP服务的请求转发到后端的真实服务器,使真实服务器的服务在单个IP地址上表现为一个虚拟服务。因此,IPVS天然支持KubernetesService。随着Kubernetes使用量的增长,其资源的可扩展性变得越来越重要。特别是对于使用kubernetes运行大量工作负载的开发人员或公司而言,服务的可扩展性至关重要。kube-proxy是一个为服务构建路由规则的模块。以前,它依赖iptables来支持主要的服务类型,例如(ClusterIP和NodePort)。但是iptables很难支持上万个服务,因为iptables纯粹是为防火墙设计的,底层数据结构是内核规则列表。与iptables相比,IPVS在内核中的实现实际上是基于Netfilter的NAT模式,所以理论上IPVS在转发层并没有明显的性能提升。而IPVS不需要在宿主机上为每个Pod设置iptables规则,而是将这些“规则”的处理放在内核态,大大降低了维护这些规则的成本。早在1.6版本,kubernetes就已经具备了支持5000个以上节点的能力,所以基于iptables的kube-proxy成为了集群扩展到5000个节点的瓶颈。比如在一个5000节点的集群中,我们创建了2000个服务,每个服务有10个pod,那么我们每个节点上至少会有20000条iptables规则,这会导致内核非常繁忙。基于IPVS的集群内负载均衡可以完美解决这个问题。IPVS是专门为负载均衡而设计的,底层采用哈希表等非常高效的数据结构,几乎可以无限扩展。但需要注意的是,IPVS模块只负责上述的负载均衡和代理功能。但是,一个完整的服务进程正常工作所需要的包过滤、SNAT等操作仍然依赖于iptables。但是,这些辅助iptables规则的数量是有限的,不会随着Pod数量的增加而增加。IPVS模式在Kubernetesv1.8中引入,并在v1.9中进入测试阶段。GA(GeneralAvailability)在1.11中实现。IPTABLES模式是在v1.1中添加的,自v1.2以来一直是默认的操作模式。IPVS和IPTABLES都是基于netfilter的。IPVS模式与IPTABLES模式的区别如下:IPVS为大型集群提供了更好的可扩展性和性能。(常规存储方式使用的数据结构效率更高)IPVS支持比iptables更复杂的负载均衡算法(rr:roundrobin,lc:leastconnection,dh:targethash,sh:sourcehash,sed:最短预期延迟,nq:从不排队)。IPVS支持服务器健康检查和连接重试等,当集群中服务不超过1000个时,iptables和ipvs区别不大。并且由于iptables与网络策略实现的良好兼容性,iptables是一个非常好的选择。当你的集群服务超过1000个,并且服务之间的链路大部分没有开启keepalive时,IPVS模式可能是一个不错的选择。参考文章:https://kubernetes.io/blog/2018/07/09/ipvs-based-in-cluster-load-balancing-deep-dive/https://cloud.tencent.com/developer/article/1470033https://blog.csdn.net/qq_36807862/article/details/106068871