IPVS
這篇文章主要講述:
- 什麼是IPVS?
- IPVS 和 IPTABLES 差別
- 如何設定kube-proxy按照ipvs模式運 行和故障排查
什麼是IPVS
IPVS(IP虛拟伺服器)實作傳輸層負載平衡,通常稱為第4層LAN交換,是Linux核心的一部分。
IPVS在主機上運作,在真實伺服器叢集前充當負載均衡器。 IPVS可以将對基于TCP和UDP的服務的請求定向到真實伺服器,并使真實伺服器的服務在單個IP位址上顯示為虛拟服務。
IPVS vs. IPTABLES
IPVS模式在Kubernetes v1.8中引入,并在v1.9中進入了beta。 IPTABLES模式在v1.1中添加,并成為自v1.2以來的預設操作模式。 IPVS和IPTABLES都基于netfilter。 IPVS模式和IPTABLES模式之間的差異如下:
- IPVS為大型叢集提供了更好的可擴充性和性能。
- IPVS支援比iptables更複雜的負載平衡算法(最小負載,最少連接配接,位置,權重等)。
- IPVS支援伺服器健康檢查和連接配接重試等。
什麼時候ipvs會降級到iptables
IPVS proxier将使用iptables,在資料包過濾,SNAT和支援NodePort類型的服務這幾個場景中。具體來說,ipvs proxier将在以下4個場景中回歸iptables。
kube-proxy 啟動項設定了 –masquerade-all=true
如果kube-proxy以--masquerade-all = true開頭,則ipvs proxier将僞裝通路服務群集IP的所有流量,其行為與iptables proxier相同。假設有一個群集IP 10.244.5.1和端口8080的服務,那麼ipvs proxier安裝的iptables應該如下所示。
# iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain OUTPUT (policy ACCEPT) target prot opt source destination KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain POSTROUTING (policy ACCEPT) target prot opt source destination KUBE-POSTROUTING all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes postrouting rules */ Chain KUBE-POSTROUTING (1 references) target prot opt source destination MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service traffic requiring SNAT */ mark match 0x4000/0x4000 Chain KUBE-MARK-DROP (0 references) target prot opt source destination MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x8000 Chain KUBE-MARK-MASQ (6 references) target prot opt source destination MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x4000 Chain KUBE-SERVICES (2 references) target prot opt source destination KUBE-MARK-MASQ tcp -- 0.0.0.0/0 10.244.5.1 /* default/foo:http cluster IP */ tcp dpt:8080
在kube-proxy啟動中指定叢集CIDR
如果kube-proxy以--cluster-cidr = <cidr>開頭,則ipvs proxier将僞裝通路服務群集IP的群集外流量,其行為與iptables proxier相同。假設kube-proxy随叢集cidr 10.244.16.0/24提供,服務叢集IP為10.244.5.1,端口為8080,則ipvs proxier安裝的iptables應如下所示。
# iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain OUTPUT (policy ACCEPT) target prot opt source destination KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain POSTROUTING (policy ACCEPT) target prot opt source destination KUBE-POSTROUTING all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes postrouting rules */ Chain KUBE-POSTROUTING (1 references) target prot opt source destination MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service traffic requiring SNAT */ mark match 0x4000/0x4000 Chain KUBE-MARK-DROP (0 references) target prot opt source destination MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x8000 Chain KUBE-MARK-MASQ (6 references) target prot opt source destination MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x4000 Chain KUBE-SERVICES (2 references) target prot opt source destination KUBE-MARK-MASQ tcp -- !10.244.16.0/24 10.244.5.1 /* default/foo:http cluster IP */ tcp dpt:8080
為LB類型服務指定Load Balancer Source Ranges
當服務的LoadBalancerStatus.ingress.IP不為空并且指定了服務的LoadBalancerSourceRanges時,ipvs proxier将安裝iptables,如下所示。
假設服務的LoadBalancerStatus.ingress.IP為10.96.1.2,服務的LoadBalancerSourceRanges為10.120.2.0/24。
# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
KUBE-POSTROUTING all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes postrouting rules */
Chain KUBE-POSTROUTING (1 references)
target prot opt source destination
MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service traffic requiring SNAT */ mark match 0x4000/0x4000
Chain KUBE-MARK-DROP (0 references)
target prot opt source destination
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x8000 Chain KUBE-MARK-MASQ (6 references)
target prot opt source destination
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x4000 Chain KUBE-SERVICES (2 references)
target prot opt source destination
ACCEPT tcp -- 10.120.2.0/24 10.96.1.2 /* default/foo:http loadbalancer IP */ tcp dpt:8080 DROP tcp -- 0.0.0.0/0 10.96.1.2 /* default/foo:http loadbalancer IP */ tcp dpt:8080
支援 NodePort type service
為了支援NodePort類型的服務,ipvs将在iptables proxier中繼續現有的實作。例如,
# kubectl describe svc nginx-service Name: nginx-service ... Type: NodePort IP: 10.101.28.148 Port: http 3080/TCP NodePort: http 31604/TCP Endpoints: 172.17.0.2:80 Session Affinity: None
# iptables -t nat -nL [root@100-106-179-225 ~]# iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain OUTPUT (policy ACCEPT) target prot opt source destination KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain KUBE-SERVICES (2 references) target prot opt source destination KUBE-MARK-MASQ tcp -- !172.16.0.0/16 10.101.28.148 /* default/nginx-service:http cluster IP */ tcp dpt:3080 KUBE-SVC-6IM33IEVEEV7U3GP tcp -- 0.0.0.0/0 10.101.28.148 /* default/nginx-service:http cluster IP */ tcp dpt:3080 KUBE-NODEPORTS all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL Chain KUBE-NODEPORTS (1 references) target prot opt source destination KUBE-MARK-MASQ tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/nginx-service:http */ tcp dpt:31604 KUBE-SVC-6IM33IEVEEV7U3GP tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/nginx-service:http */ tcp dpt:31604 Chain KUBE-SVC-6IM33IEVEEV7U3GP (2 references) target prot opt source destination KUBE-SEP-Q3UCPZ54E6Q2R4UT all -- 0.0.0.0/0 0.0.0.0/0 /* default/nginx-service:http */ Chain KUBE-SEP-Q3UCPZ54E6Q2R4UT (1 references) target prot opt source destination KUBE-MARK-MASQ all -- 172.17.0.2 0.0.0.0/0 /* default/nginx-service:http */ DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/nginx-service:http */ tcp to:172.17.0.2:80
以 ipvs 模式 運作kube-proxy
前提條件
確定IPVS需要核心子產品
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack_ipv4
- 檢查上訴已編譯到節點核心中。使用
grep -e ipvs -e nf_conntrack_ipv4 /lib/modules/$(uname -r)/modules.builtin
如果編譯成核心,則得到如下結果。
kernel/net/ipv4/netfilter/nf_conntrack_ipv4.ko
kernel/net/netfilter/ipvs/ip_vs.ko
kernel/net/netfilter/ipvs/ip_vs_rr.ko
kernel/net/netfilter/ipvs/ip_vs_wrr.ko
kernel/net/netfilter/ipvs/ip_vs_lc.ko
kernel/net/netfilter/ipvs/ip_vs_wlc.ko
kernel/net/netfilter/ipvs/ip_vs_fo.ko
kernel/net/netfilter/ipvs/ip_vs_ovf.ko
kernel/net/netfilter/ipvs/ip_vs_lblc.ko
kernel/net/netfilter/ipvs/ip_vs_lblcr.ko
kernel/net/netfilter/ipvs/ip_vs_dh.ko
kernel/net/netfilter/ipvs/ip_vs_sh.ko
kernel/net/netfilter/ipvs/ip_vs_sed.ko
kernel/net/netfilter/ipvs/ip_vs_nq.ko
kernel/net/netfilter/ipvs/ip_vs_ftp.ko
- 是否被加載
# load module <module_name> modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 # to check loaded modules, use lsmod | grep -e ipvs -e nf_conntrack_ipv4
# or cut -f1 -d " " /proc/modules | grep -e ip_vs -e nf_conntrack_ipv4
在使用IPVS模式之前,還應在節點上安裝ipset等軟體包。
如果不滿足這些要求,Kube-proxy将回退到IPTABLES模式。
kubeadm 安裝的叢集
預設情況下,Kube-proxy将在kubeadm部署的叢集中以iptables模式運作。
如果您将kubeadm與配置檔案一起使用,則可以在kubeProxy字段下指定ipvs模式,添加SupportIPVSProxyMode:true。
kind: MasterConfiguration apiVersion: kubeadm.k8s.io/v1alpha1 ... kubeProxy: config: featureGates: SupportIPVSProxyMode=true mode: ipvs ...
如果您使用的是Kubernetes v1.8,您還可以在kubeadm init指令中添加标志--feature-gates = SupportIPVSProxyMode = true(自v1.9起不推薦使用)
kubeadm init --feature-gates=SupportIPVSProxyMode=true
PS
如果成功啟用了ipvs模式,你應該看到ipvs代理規則(使用ipvsadm)例如:
# ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.0.0.1:443 rr persistent 10800
-> 192.168.0.1:6443 Masq 1 1 0
當本地群集運作時,kube-proxy日志中會出現類似的日志(例如,本地群集的/tmp/kube-proxy.log):
Using ipvs Proxier.
然而沒有ipvs代理規則或有以下日志則表明kube-proxy無法使用ipvs模式:
Can't use ipvs proxier, trying iptables proxier
Using iptables Proxier.
調試和排查
檢查ipvs 代理規則
使用者可以使用ipvsadm工具檢查kube-proxy是否正确維護IPVS規則。例如,我們在叢集中有以下服務:
# kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 1d
kube-system kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 1d
我們應該能看到如下的規則:
# ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.0.0.1:443 rr persistent 10800
-> 192.168.0.1:6443 Masq 1 1 0
TCP 10.0.0.10:53 rr
-> 172.17.0.2:53 Masq 1 0 0
UDP 10.0.0.10:53 rr
-> 172.17.0.2:53 Masq 1 0 0
為什麼kube-proxy不能以ipvs模式啟動
- Enable IPVS feature gateway
對于Kubernetes v1.10及更高版本,功能門SupportIPVSProxyMode預設設定為true。但是,您需要在v1.10之前為Kubernetes明确啟用--feature-gates = SupportIPVSProxyMode = true。
- 指定proxy-mode=ipvs
檢查kube-proxy模式是否已設定為ipvs
- 安裝所需的核心子產品和包
檢查是否已将ipvs所需的核心子產品編譯到核心和軟體包中。
本文轉自SegmentFault-
kube-proxy的ipvs模式解讀