Kubernetes 从1.10到1.11升级记录(续):Kubernetes kube-proxy开启IPVS模式
2018-10-20
IPVS(IP Virtual Server)是lvs项目的一部分,作为Linux内核的一部分,提供4层负载均衡器的功能,即传输层负载均衡。ipvs运行在主机内核中,作为真是服务器集群前的负载均衡器,将到对服务的请求转发到真实的服务器上,并将多个ip的真实服务器集群的服务显示为单个ip的虚拟机服务。
kube-proxy作为Kubernetes集群中的网络代理和负载均衡器,其作用是将发送到Service的请求转发到具体的后端。 Kubernetes从1.8开始为kube-proxy组件引入了IPVS模式,并在Kubernetes 1.11进入GA,在Kubernetes 1.12成为kube-proxy的默认代理模式。本文将实践在测试环境中Kubernetes 1.11集群上开启IPVS。
1.kube-proxy代理的三种模式 #
当前Kubernetes kube-proxy的负载均衡支持以下三种代理模式:
- userspace:这种模式下kube-proxy进程在用户空间监听一个本地端口,iptables规则将流量转发到这个本地端口,然后kube-proxy在其内部应用层建立到具体后端的连接,即在其内部进行转发,这是在用户空间的转发,虽然比较稳定,但效率不高。userspace模式是kube-proxy早期(Kubernetes 1.0)的模式,早就不推荐使用,也不会被我们使用。
- iptables:这种模式是从Kubernetes 1.2开始并在Kubernetes 1.12之前的默认方式。在这种模式下kube-proxy监控Kubernetes对Service、Endpoint对象的增删改操作。监控到Service对象的增删改,将配置iptables规则,截获到Service的ClusterIp和端口的流量并将其重定向到服务的某个后端;监控到Endpoint对象的增删改,将更新具体到某个后端的iptables规则。iptables模式基于netfilter,但因为流量的转发都是在Kernel Space,所以性能更高且更加可靠。 这种模式的缺点是,对于超大规模集群,当集群中服务数量达到一定量级时,iptables规则的添加将会出现很大延迟,因为规则的更新出现kernel local,所以此时将会出现性能问题,据这篇文章中《华为云在 K8S 大规模场景下的 Service 性能优化实践》介绍当Service数量达到5000个,iptables规则基数为40000,增加一条规则的时间将达到11分钟。
- ipvs:这种模式从Kubernetes 1.11进入GA,并在Kubernetes 1.12成为kube-proxy的默认代理模式。ipvs模式也是基于netfilter,对比iptables模式在大规模Kubernetes集群有更好的扩展性和性能,支持更加复杂的负载均衡算法(如:最小负载、最少连接、加权等),支持Server的健康检查和连接重试等功能。ipvs依赖于iptables,使用iptables进行包过滤、SNAT、masquared。ipvs将使用
ipset
需要被DROP或MASQUARED的源地址或目标地址,这样就能保证iptables规则数量的固定,我们不需要关心集群中有多少个Service了。
2.配置kube-proxy开启ipvs模式 #
2.1 开启ipvs的前提 #
由于ipvs已经加入到了内核的主干,所以为kube-proxy开启ipvs的前提需要加载以下的内核模块:
1ip_vs
2ip_vs_rr
3ip_vs_wrr
4ip_vs_sh
5nf_conntrack_ipv4
在所有的Kubernetes节点上执行以下脚本:
1cat > /etc/sysconfig/modules/ipvs.modules <<EOF
2#!/bin/bash
3modprobe -- ip_vs
4modprobe -- ip_vs_rr
5modprobe -- ip_vs_wrr
6modprobe -- ip_vs_sh
7modprobe -- nf_conntrack_ipv4
8EOF
9chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
上面脚本创建了的/etc/sysconfig/modules/ipvs.modules
文件,保证在节点重启后能自动加载所需模块。
使用lsmod | grep -e ip_vs -e nf_conntrack_ipv4
命令查看是否已经正确加载所需的内核模块。
接下来还需要确保各个节点上已经安装了ipset软件包yum install ipset
。
为了便于查看ipvs的代理规则,最好安装一下管理攻击ipvsadm yum install ipvsadm
。
以上前提条件如果不满足,则及时kube-proxy的配置开启了ipvs模式,也会退回到iptables模式。
2.2 配置kube-proxy开启ipvs #
Kubernetes 1.12的kube-proxy已经默认开启,对于Kubernetes 1.11,我们为kube-proxy的命令行参数中加入--proxy-mode=ipvs
。
重启kube-proxy后,查看其日志:
1I1020 14:57:11.915294 1 server_others.go:189] Using ipvs Proxier.
2W1020 14:57:11.915505 1 proxier.go:343] IPVS scheduler not specified, use rr by default
3I1020 14:57:11.915676 1 server_others.go:216] Tearing down inactive rules.
可以看出ipvs Proxier已经启用。同时使用ipvsadm命令可以看到相关Service的ipvs规则:
1ipvsadm -ln
2IP Virtual Server version 1.2.1 (size=4096)
3Prot LocalAddress:Port Scheduler Flags
4 -> RemoteAddress:Port Forward Weight ActiveConn InActConn
5TCP 127.0.0.1:30058 rr
6 -> 10.244.1.3:443 Masq 1 0 0
7 -> 10.244.1.4:443 Masq 1 0 0
8TCP 172.17.0.1:30058 rr
9 -> 10.244.1.3:443 Masq 1 0 0
10 -> 10.244.1.4:443 Masq 1 0 0
11TCP 172.17.0.1:31657 rr
12 -> 10.244.1.3:80 Masq 1 0 0
13 -> 10.244.1.4:80 Masq 1 0 0
14TCP 192.168.61.10:80 rr
15 -> 10.244.1.3:80 Masq 1 0 0
16 -> 10.244.1.4:80 Masq 1 0 0
17TCP 192.168.61.10:443 rr
18 -> 10.244.1.3:443 Masq 1 1 0
19 -> 10.244.1.4:443 Masq 1 0 1
20TCP 192.168.61.12:30058 rr
21 -> 10.244.1.3:443 Masq 1 0 0
22 -> 10.244.1.4:443 Masq 1 0 0
23TCP 192.168.61.12:31657 rr
24 -> 10.244.1.3:80 Masq 1 0 0
25 -> 10.244.1.4:80 Masq 1 0 0
26TCP 10.0.2.15:30058 rr
27 -> 10.244.1.3:443 Masq 1 0 0
28 -> 10.244.1.4:443 Masq 1 0 0
29......
注意事项:对于使用了externalIPs的Service,如ingress-controller,当开启IPVS后,externalIP也会作为VIP被ipvs接管,因此如果在externalIp指定的Kubernetes集群中的具体Node节点的IP,在重启kube-proxy之前需要提前将externalIp替换成预先规划好的VIP,否则会出现VIP和Node节点IP冲突的问题。