Kubernetes集群如何用Ipvs替換Iptables
我們都知道k8s中的 kube-proxy 是一個(gè)網(wǎng)絡(luò)代理(proxy),它負(fù)責(zé)為 Kubernetes 集群中的服務(wù)提供負(fù)載均衡和服務(wù)發(fā)現(xiàn)功能。kube-proxy 會(huì)以不同的模式運(yùn)行,其中 iptables 模式和 ipvs 模式是其中兩種常見的模式。
iptables 和 ipvs 都是 Linux 內(nèi)核中的網(wǎng)絡(luò)代理技術(shù),都可以用于實(shí)現(xiàn)負(fù)載均衡和服務(wù)發(fā)現(xiàn)。但兩種模式之間存在以下幾個(gè)區(qū)別:
實(shí)現(xiàn)方式不同
iptables 基于 iptables 規(guī)則實(shí)現(xiàn),每個(gè)節(jié)點(diǎn)都會(huì)在 iptables 中添加一組規(guī)則來(lái)實(shí)現(xiàn)負(fù)載均衡和服務(wù)發(fā)現(xiàn);而 ipvs 則是基于內(nèi)核層面的負(fù)載均衡技術(shù),可以實(shí)現(xiàn)更高效的網(wǎng)絡(luò)代理處理。
性能不同
在高負(fù)載的情況下,ipvs 模式下的 kube-proxy 性能更好,因?yàn)樗鼘?duì)網(wǎng)絡(luò)的負(fù)載均衡處理是基于內(nèi)核層面的,更加高效。但是,Iptables 模式在部分場(chǎng)景下也可以獲得更好的性能。
功能不同
Iptables 模式下的 kube-proxy 在 Kubernetes 1.16 版本之前,使用 iptables 實(shí)現(xiàn)端口轉(zhuǎn)發(fā),只能實(shí)現(xiàn)基于TCP的負(fù)載均衡和服務(wù)發(fā)現(xiàn),且不能支持四層負(fù)載均衡。而在 Kubernetes 1.16 版本中新增了 iptables-nat 模式,可以支持四層負(fù)載均衡。相比之下,ipvs 模式支持 TCP、UDP、SCTP 和四層負(fù)載均衡,支持 Online Hashed、IP Hash、Round Robin 和 Least Connection 等多種負(fù)載均衡算法。
iptable 的一個(gè)缺點(diǎn)在于由于工作在 Kernel 級(jí)別,如果 iptables 規(guī)則過于復(fù)雜,可能會(huì)對(duì)系統(tǒng)產(chǎn)生性能影響,并且由于 iptables 規(guī)則集中在 Kernel 中,修改比較困難。
在 Kubernetes 系統(tǒng)中,kubeadm 管理工具將默認(rèn)選擇 ipvs 模式來(lái)處理 kube-proxy,同時(shí) Kubernetes 還提供了多種異常處理機(jī)制,如自動(dòng)拉起、Rollback、故障轉(zhuǎn)移等,以確保系統(tǒng)的可靠性、高可用性和容錯(cuò)性,從而避免了 iptables 處理過程中可能出現(xiàn)的問題,并且改善了整個(gè)系統(tǒng)在故障處理和容錯(cuò)性方面的性能。
操作是在所有節(jié)點(diǎn)上
開啟內(nèi)核支持
cat >> /etc/sysctl.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOFsysctl -p
開啟ipvs支持
yum -y install ipvsadm ipset
臨時(shí)生效
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4永久生效
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF配置kube-proxy,在master上操作
因使用kubeadmin安裝,所以操作方式如下
[root@master] # kubectl edit cm kube-proxy -n kube-system
configmap/kube-proxy edited修改如下
kind: MasterConfiguration
apiVersion: kubeadm.k8s.io/v1alpha1
...
ipvs:
    excludeCIDRs: null
    minSyncPeriod: 0s
    scheduler: ""
    syncPeriod: 30s
  kind: KubeProxyConfiguration
  metricsBindAddress: 127.0.0.1:10249
  mode: "ipvs"                 #修改在master重啟kube-proxy
kubectl get pod -n kube-system | grep kube-proxy | awk '{print $1}' | xargs kubectl delete pod -n kube-system
驗(yàn)證ipvs是否開啟
kubectl logs kube-proxy-cvzb4 -n kube-system
I0409 03:37:29.194391       1 server_others.go:170] Using ipvs Proxier.
W0409 03:37:29.194779       1 proxier.go:401] IPVS scheduler not specified, use rr by default
I0409 03:37:29.194981       1 server.go:534] Version: v1.15.3
I0409 03:37:29.214255       1 conntrack.go:52] Setting nf_conntrack_max to 524288
I0409 03:37:29.216744       1 config.go:96] Starting endpoints config controller
I0409 03:37:29.216812       1 controller_utils.go:1029] Waiting for caches to sync for endpoints config controller
I0409 03:37:29.217445       1 config.go:187] Starting service config controller
I0409 03:37:29.218320       1 controller_utils.go:1029] Waiting for caches to sync for service config controller
I0409 03:37:29.318218       1 controller_utils.go:1036] Caches are synced for endpoints config controller
I0409 03:37:29.318564       1 controller_utils.go:1036] Caches are synced for service config controller驗(yàn)證
進(jìn)入pod內(nèi),現(xiàn)在可以ping通servicename了,使用iptables時(shí),發(fā)現(xiàn)ping的時(shí)候出現(xiàn)了如下錯(cuò)誤,執(zhí)行完上述操作,一切正常
root@xxxxxx-cb4c9cb8c-hpzdl:/opt# ping xxxxxx
PING xxxxxx.xxxxx.svc.cluster.local (172.16.140.78) 56(84) bytes of data.
From 172.16.8.1 (172.16.8.1) icmp_seq=1 Time to live exceeded
From 172.16.8.1 (172.16.8.1) icmp_seq=2 Time to live exceeded錯(cuò)誤
圖片
解決(降低kube-proxy 版本)
kubectl -n kube-system set image daemonset/kube-proxy *=registry.aliyuncs.com/k8sxio/kube-proxy:v1.17.6














 
 
 










 
 
 
 