Kubernetes 從1.10到1.11升級記錄(續):Kubernetes kube-proxy開啟IPVS模式
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,所以此時將會出現效能問題,據這篇文章中 ofollow,noindex" target="_blank">《華為雲在 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的前提需要載入以下的核心模組:
ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack_ipv4
在所有的Kubernetes節點上執行以下指令碼:
cat > /etc/sysconfig/modules/ipvs.modules <<EOF #!/bin/bash modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 EOF chmod 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後,檢視其日誌:
I1020 14:57:11.9152941 server_others.go:189] Using ipvs Proxier. W1020 14:57:11.9155051 proxier.go:343] IPVS scheduler not specified, use rr by default I1020 14:57:11.9156761 server_others.go:216] Tearing down inactive rules.
可以看出ipvs Proxier已經啟用。同時使用ipvsadm命令可以看到相關Service的ipvs規則:
ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:PortForward Weight ActiveConn InActConn TCP127.0.0.1:30058 rr -> 10.244.1.3:443Masq100 -> 10.244.1.4:443Masq100 TCP172.17.0.1:30058 rr -> 10.244.1.3:443Masq100 -> 10.244.1.4:443Masq100 TCP172.17.0.1:31657 rr -> 10.244.1.3:80Masq100 -> 10.244.1.4:80Masq100 TCP192.168.61.10:80 rr -> 10.244.1.3:80Masq100 -> 10.244.1.4:80Masq100 TCP192.168.61.10:443 rr -> 10.244.1.3:443Masq110 -> 10.244.1.4:443Masq101 TCP192.168.61.12:30058 rr -> 10.244.1.3:443Masq100 -> 10.244.1.4:443Masq100 TCP192.168.61.12:31657 rr -> 10.244.1.3:80Masq100 -> 10.244.1.4:80Masq100 TCP10.0.2.15:30058 rr -> 10.244.1.3:443Masq100 -> 10.244.1.4:443Masq100 ......
注意事項:對於使用了externalIPs的Service,如ingress-controller,當開啟IPVS後,externalIP也會作為VIP被ipvs接管,因此如果在externalIp指定的Kubernetes叢集中的具體Node節點的IP,在重啟kube-proxy之前需要提前將externalIp替換成預先規劃好的VIP,否則會出現VIP和Node節點IP衝突的問題。