kube-proxy的ipvs模式解讀

IPVS

這篇文章主要講述:node

  • 什麼是IPVS?
  • IPVS 和 IPTABLES 區別
  • 如何設置kube-proxy按照ipvs模式運行和故障排查

什麼是IPVS

IPVS(IP虛擬服務器)實現傳輸層負載平衡,一般稱爲第4層LAN交換,是Linux內核的一部分。nginx

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模式之間的差別以下:api

  • 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應以下所示。tcp

# 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中繼續現有的實現。例如,post

# 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所需的內核模塊編譯到內核和軟件包中。 (見前提條件)

相關文章
相關標籤/搜索