作者:李毓
k8s中1.8版本中就加入了ipvs模式。那么这个模式相对于iptables模式来说有什么优缺点呢,我们就来探讨一下。
我们先来回顾一下一个pod的信息是如何产生变化的。
首先由kubectl发起请求,请求到了 api-server,然后api-server把信息存储到etcd。然后kube-proxy监听到了api-server的变化,然后将信息传送到service,接着再通过iptables送到后端的endpoint。
这一系列请求最后是通过iptables来传递的。
对于后台的每一个endpoint,是如何选择到底如何发送到哪一个的呢?如果选择的第一个pod没有响应,那么他将选择另外一个pod进行启动。
这样就产生了一个问题,iptables是基于内核规则列表的,集群节点越多,那么性能就越差。比如我们在1000个节点中使用了nodeport服务,并且1000个服务中每个服务有10个pod。那么每个节点上将至少产生了10000个iptables规则,这将使得内核变得非常的繁忙。机器的性能会大打折扣。
然后我们再看看ipvs模式,再这个模式中,仍然是由kube-proxy监听service的变化。并通过网络接口定期将ipvs规则和service信息进行同步。当访问service的时候,流量将流向后端的endpoint地址。
ipvs是基于netfilter hook函数的,这个函数使用的是hash表作为底层数据结构。这意味着ipvs用更少的流量同步规则,使得网络吞吐量效率更加高效。
在这里,我们就可以总结一下了。
ipvs和iptables都是基于netfilter的,他们的差别为:
ipvs 为大规模集群提供了更好的可扩展性和性能
ipvs 支持比 iptables 更复杂的复制均衡算法(最小负载、最少连接、加权轮询等)
ipvs 支持服务器健康检查和连接重试等功能
至于为什么这么好的性能但是K8S却一直默认使用iptables呢?估计是他们认为大多数公司都不会有大规模使用集群的要求吧。
接下来我们试一下ipvs的模式。
先查看一下目前的模式,我的是K8S1.18版本。
我们改成ipvs模式,查看内核模块是否加载。
[root@adm-master ~]# lsmod|grep ip_vs
ip_vs_sh 12688 0
ip_vs_wrr 12697 0
ip_vs_rr 12600 0
ip_vs 145497 6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack 139224 9 ip_vs,nf_nat,nf_nat_ipv4,nf_nat_ipv6,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_netlink,nf_conntrack_ipv4,nf_conntrack_ipv6
libcrc32c 12644 4 xfs,ip_vs,nf_nat,nf_conntrack
这里原来是空的,修改成ipvs模式
[root@adm-master ~]# kubectl edit configmap kube-proxy -n kube-system
configmap/kube-proxy edited
删除所有kube-proxy的pod
[root@adm-master ~]# kubectl delete pod/kube-proxy-84p9n -n kube-system
pod "kube-proxy-84p9n" deleted
[root@adm-master ~]# kubectl delete pod/kube-proxy-mkbk8 -n kube-system
pod "kube-proxy-mkbk8" deleted
[root@adm-master ~]# kubectl delete pod/kube-proxy-xzwxl -n kube-system
pod "kube-proxy-xzwxl" deleted
查看模式
查看ipvs相关规则。
安装ipvsadm
yum install -y ipvsadm