k8s中service 的iptables


首先調整kubeproxy 的模式為iptables

kubectl edit configmap kube-proxy -n kube-system
修改

kind: KubeProxyConfiguration
metricsBindAddress: 127.0.0.1:10249
mode: "ipvs"                          ##### 修改這一行留空則為iptables
nodePortAddresses: null

然后殺掉kubeproxy的pod ,讓deployment 自動拉起來新配置pod

輸出kubeproxy的pod 日志,看是否采用了iptables
kubectl logs kube-proxy-xxx -n kube-system

已經修改模式為iptables了。

目前集群已有svc

NAMESPACE              NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                   AGE
default                go-web-service              NodePort    10.96.97.253    <none>        3009:30009/TCP            20d
kube-system            kube-dns                    ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP    72d

觀察啟動go-web-service這條的iptables 脈絡

[root@ebs-76642 ~]# iptables -t nat -L KUBE-SERVICES |egrep 'go-web-service'
target     prot opt source               destination
KUBE-MARK-MASQ  tcp  -- !ebs-76642/16         ebs-76642            /* default/go-web-service:http cluster IP */ tcp dpt:pxc-ntfy
KUBE-SVC-KG4IN6CR36NHNLPD  tcp  --  anywhere             ebs-76642            /* default/go-web-service:http cluster IP */ tcp dpt:pxc-ntfy

[root@ebs-76642 ~]# iptables -t nat -L KUBE-SVC-KG4IN6CR36NHNLPD
Chain KUBE-SVC-KG4IN6CR36NHNLPD (2 references)
target     prot opt source               destination
KUBE-SEP-TKPLZBGAW27QFDLO  all  --  anywhere             anywhere             statistic mode random probability 0.50000000000
KUBE-SEP-LEFZ7V5H5GEG5L4O  all  --  anywhere             anywhere

[root@ebs-76642 ~]# iptables -t nat -L KUBE-SEP-TKPLZBGAW27QFDLO
Chain KUBE-SEP-TKPLZBGAW27QFDLO (1 references)
target     prot opt source               destination
KUBE-MARK-MASQ  all  --  172.16.1.43          anywhere
DNAT       tcp  --  anywhere             anywhere             tcp to:172.16.1.43:3009

[root@ebs-76642 ~]# k get pods -A -o wide|grep '172.16.1.43'
default                go-web-app-68797989b8-2vctz                 1/1     Running   3          20d   172.16.1.43      ebs-82413   <none>           <none>

觀察kube-dns這條iptables 脈絡,這里暴露了三個ports(dns-tcp,dns,metrics)

[root@ebs-76642 ~]# iptables -t nat -L KUBE-SERVICES |egrep 'kube-dns'
KUBE-MARK-MASQ  tcp  -- !ebs-76642/16         ebs-76642            /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:domain
KUBE-SVC-ERIFXISQEP7F7OF4  tcp  --  anywhere             ebs-76642            /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:domain
KUBE-MARK-MASQ  udp  -- !ebs-76642/16         ebs-76642            /* kube-system/kube-dns:dns cluster IP */ udp dpt:domain
KUBE-SVC-TCOU7JCQXEZGVUNU  udp  --  anywhere             ebs-76642            /* kube-system/kube-dns:dns cluster IP */ udp dpt:domain
KUBE-MARK-MASQ  tcp  -- !ebs-76642/16         ebs-76642            /* kube-system/kube-dns:metrics cluster IP */ tcp dpt:9153
KUBE-SVC-JD5MR3NA4I4DYORP  tcp  --  anywhere             ebs-76642            /* kube-system/kube-dns:metrics cluster IP */ tcp dpt:9153

- 先看ports name為dns-tcp 這個的
[root@ebs-76642 ~]# iptables -t nat -L KUBE-SVC-ERIFXISQEP7F7OF4
Chain KUBE-SVC-ERIFXISQEP7F7OF4 (1 references)
target     prot opt source               destination
KUBE-SEP-7LK5TTMYU3GPSJJW  all  --  anywhere             anywhere             statistic mode random probability 0.50000000000
KUBE-SEP-3NE7D5ZQGKE4MF2Z  all  --  anywhere             anywhere

- 對應dns-tcp后端的兩個pods
[root@ebs-76642 ~]# iptables -t nat -L KUBE-SEP-7LK5TTMYU3GPSJJW
Chain KUBE-SEP-7LK5TTMYU3GPSJJW (1 references)
target     prot opt source               destination
KUBE-MARK-MASQ  all  --  172.16.0.15          anywhere
DNAT       tcp  --  anywhere             anywhere             tcp to:172.16.0.15:53
[root@ebs-76642 ~]# iptables -t nat -L KUBE-SEP-3NE7D5ZQGKE4MF2Z
Chain KUBE-SEP-3NE7D5ZQGKE4MF2Z (1 references)
target     prot opt source               destination
KUBE-MARK-MASQ  all  --  172.16.1.44          anywhere
DNAT       tcp  --  anywhere             anywhere             tcp to:172.16.1.44:53

對於iptable方式的service:

流量從pod network namespace(cluster ip類型的service)或者外部(node port類型的service)進入到host netwok namespace之中。

在host netwok namespace的PREROUTING chain中會經過一系列target,KUBE-SERVICES(cluster ip類型的service),KUBE-NODEPORTS (node port類型的service),KUBE-SVC-XXX,KUBE-SEP-XXX。

在這些target里根據iptable內核隨機模塊random來實現匹配endpoint target,實現負載均衡。

在endpoint target(KUBE-SEP-XXX)里實現了DNAT,也就是將目標地址cluster ip轉化為實際的pod的ip。

數據包經過以上修改根據host network namespace的路由表做下一跳路由選擇。

對於ipvs方式的service:

流量從pod network namespace(cluster ip類型的service)或者外部(node port類型的service)進入到host netwok namespace之中。

對於clutser ip類型的service,在host netwok namespace的PREROUTING chain中經過匹配ipset KUBE-CLUSTER-IP做mask標記操作。

對於node port類型的service,在PREROUTING chain中經過匹配ipset KUBE-NODE-PORT-TCP做mask標記操作。

對於clutser ip類型的service,由於host network namespace中有創建網絡設備kube-ipvs0,並且綁定所有cluster ip,這樣從pod發出的數據包目標ip為cluster ip,有kube-ipvs0網絡設備對應,數據進入INPUT chain中。

對於node port類型的service,由於數據包的目標ip是host的ip地址,所以也進入了host network namespace的INPUT chain中。

利用linux內核模塊ipvs,數據在INPUT chain中被ipvs的規則修改(可由ipvsadm查看規則),完成負載均衡和DNAT,然后將數據直接送入POSTROUTING chain。

數據在POSTROUTING chain中,經過KUBE-POSTROUTING target,根據之前的mark操作完成MASQUERADE SNAT。

數據包經過以上修改根據host network namespace的路由表做下一跳路由選擇。

對於iptable和ipvs方式的service:

兩者都是采用linux內核模塊完成負載均衡和endpoint的映射,所有操作都在內核空間完成,沒有在應用程序的用戶空間。

iptable方式依賴於linux netfilter/iptable內核模塊。

ipvs方式依賴linux netfilter/iptable模塊,ipset模塊,ipvs模塊。

iptable方式中,host宿主中ipatble的entry數目會隨着service和對應endpoints的數目增多而增多。舉個例子,比如有10個cluster ip類型的service,每個service有6個endpoints。那么在KUBE-SERVICES target中至少有10個entries(KUBE-SVC-XXX)與10個service對應,每個KUBE-SVC-XXX target中會有6個KUBE-SEP-XXX與6個endpoints來對應,每個KUBE-SEP-XXX會有2個enrties來分別做mark masq和DNAT,這樣算起來至少有1062=120個entries在iptable中。試想如果application中service和endpoints數目巨大,iptable entries也是非常龐大的,在一定情況下有可能帶來性能上的問題。

ipvs方式中host宿主中iptable的entry數目是固定的,因為iptable做匹配的時候會利用ipset(KUBE-CLUSTER-IP或者KUBE-NODE-PORT-TCP)來匹配,service的數目決定了ipset的大小,並不會影響iptable的大小。這樣就解決了iptable模式下,entries隨着service和endpoints的增多而增多的問題。

對於負載均衡,iptable方式采用random模塊來完成負載均衡,ipvs方式支持多種負載均衡,例如round-robin,least connection,source hash等(可參考http://www.linuxvirtualserver.org/),並且由kubelet啟動參數--ipvs-scheduler控制。

對於目標地址的映射,iptable方式采用linux原生的DNAT,ipvs方式則利用ipvs模塊完成。

ipvs方式會在host netwok namespace中創建網絡設備kube-ipvs0,並且綁定了所有的cluster ip,這樣保證了cluster-ip類型的service數據進入INPUT chain,從而讓ipvs來完成負載均衡和目標地址的映射。

iptable方式不會在host netwok namespace中創建額外的網絡設備。

iptable方式數據在host network namespace的chain中的路徑是:PREROUTING-->FORWARDING-->POSTROUTING

在PREROUTING chain中完成負載均衡,mark masq和目標地址映射。

ipvs方式數據在host network namespace的chain中的路徑是:

PREROUTING-->INPUT-->POSTROUTING

在PREROUTING chain中完成mark masq SNAT,在INPUT chain利用ipvs完成負載均衡和目標地址映射。

iptable和ipvs方式在完成負載均衡和目標地址映射后都會根據host network namespace的路由表做下一跳路由選擇。

關於iptable和ipvs方式的選擇並沒有固定答案,要根據項目的需求和實際情況而定。

iptables nat表中的詳細過程

[root@docker3 ~]#  iptables -nL -t nat -v
Chain PREROUTING (policy ACCEPT 2 packets, 1152 bytes)
pkts bytes target     prot opt in     out     source               destination        
10837 3999K KUBE-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */
====》1. 進入的請求,首先匹配PREROUTING 鏈里的該規則,並進入KUBE-SERVICES鏈
  238 27286 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
 
Chain INPUT (policy ACCEPT 2 packets, 1152 bytes)
pkts bytes target     prot opt in     out     source               destination        
 
Chain OUTPUT (policy ACCEPT 8 packets, 480 bytes)
pkts bytes target     prot opt in     out     source               destination        
61563 3722K KUBE-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */
    0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
 
Chain POSTROUTING (policy ACCEPT 8 packets, 480 bytes)
pkts bytes target     prot opt in     out     source               destination        
61840 3742K KUBE-POSTROUTING  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes postrouting rules */
====》6. 需要路由到另一個主機的連接經由POSTROUTING該規則,進入KUBE-POSTROUTING 鏈
   62  4323 MASQUERADE  all  --  *      !docker0  10.2.39.0/24         0.0.0.0/0          
    0     0 MASQUERADE  all  --  *      !docker0  10.1.33.0/24         0.0.0.0/0          
 
Chain DOCKER (2 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0          
 
Chain KUBE-MARK-DROP (0 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK or 0x8000
 
Chain KUBE-MARK-MASQ (6 references)
pkts bytes target     prot opt in     out     source               destination        
    2   128 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK or 0x4000
 
Chain KUBE-NODEPORTS (1 references)
pkts bytes target     prot opt in     out     source               destination        
    2   128 KUBE-MARK-MASQ  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */ tcp dpt:30780
    2   128 KUBE-SVC-2RMP45C4XWDG5BGC  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */ tcp dpt:30780
    ====》3.請求命中上述兩個規則,一個進行進入KUBE-MARK-MASQ 鏈進行標記,一個進入KUBE-SVC-2RMP45C4XWDG5BGC鏈
 
Chain KUBE-POSTROUTING (1 references)
pkts bytes target     prot opt in     out     source               destination        
    1    64 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service traffic requiring SNAT */ mark match 0x4000/0x4000
    ====》7. 執行源地址轉換(在flannel網絡這里轉換的地址是flannel.1即flannel在ifconfig里輸出接口的地址),發往另一個node
 
Chain KUBE-SEP-D5T62RWZFFOCR77Q (1 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.2.39.3            0.0.0.0/0            /* default/k8s-nginx: */
    1    64 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */ tcp to:10.2.39.3:80
    ====》5-2. DNAT到本機,交給INPUT
 
Chain KUBE-SEP-IK3IYR4STYKRJP77 (1 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.2.39.2            0.0.0.0/0            /* kube-system/kube-dns:dns-tcp */
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kube-system/kube-dns:dns-tcp */ tcp to:10.2.39.2:53
 
Chain KUBE-SEP-WV6S37CDULKCYEVE (1 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.2.39.2            0.0.0.0/0            /* kube-system/kube-dns:dns */
    0     0 DNAT       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kube-system/kube-dns:dns */ udp to:10.2.39.2:53
 
Chain KUBE-SEP-X7YOSBI66WAQ7F6X (2 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 KUBE-MARK-MASQ  all  --  *      *       172.16.199.17        0.0.0.0/0            /* default/kubernetes:https */
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/kubernetes:https */ recent: SET name: KUBE-SEP-X7YOSBI66WAQ7F6X side: source mask: 255.255.255.255 tcp to:172.16.199.17:6443
 
Chain KUBE-SEP-YXWG4KEJCDIRMCO5 (1 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.2.4.2             0.0.0.0/0            /* default/k8s-nginx: */
    1    64 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */ tcp to:10.2.4.2:80
    ====》5-1. DNAT到另一個node,隨后執行postrouting
 
Chain KUBE-SERVICES (2 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 KUBE-SVC-2RMP45C4XWDG5BGC  tcp  --  *      *       0.0.0.0/0            169.169.148.143      /* default/k8s-nginx: cluster IP */ tcp dpt:80
    0     0 KUBE-SVC-NPX46M4PTMTKRN6Y  tcp  --  *      *       0.0.0.0/0            169.169.0.1          /* default/kubernetes:https cluster IP */ tcp dpt:443
    0     0 KUBE-SVC-TCOU7JCQXEZGVUNU  udp  --  *      *       0.0.0.0/0            169.169.0.53         /* kube-system/kube-dns:dns cluster IP */ udp dpt:53
    0     0 KUBE-SVC-ERIFXISQEP7F7OF4  tcp  --  *      *       0.0.0.0/0            169.169.0.53         /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:53
    2   128 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
    ====》2.連接隨后並該規則匹配,進入KUBE-NODEPORTS 鏈
 
Chain KUBE-SVC-2RMP45C4XWDG5BGC (2 references)
pkts bytes target     prot opt in     out     source               destination        
    1    64 KUBE-SEP-D5T62RWZFFOCR77Q  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */ statistic mode random probability 0.50000000000
    1    64 KUBE-SEP-YXWG4KEJCDIRMCO5  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */
====》4.請求被該鏈中兩個規則匹配,這里只有兩個規則,按照50% RR規則進行負載均衡分發,兩個目標鏈都是進行DNAT,一個轉到本node的pod IP上,一個轉到另一台宿主機的pod上,因為該service下只有兩個pod
==========》亂入的廣告,www.myf5.net《==================
Chain KUBE-SVC-ERIFXISQEP7F7OF4 (1 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 KUBE-SEP-IK3IYR4STYKRJP77  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kube-system/kube-dns:dns-tcp */
 
Chain KUBE-SVC-NPX46M4PTMTKRN6Y (1 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 KUBE-SEP-X7YOSBI66WAQ7F6X  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/kubernetes:https */ recent: CHECK seconds: 10800 reap name: KUBE-SEP-X7YOSBI66WAQ7F6X side: source mask: 255.255.255.255
    0     0 KUBE-SEP-X7YOSBI66WAQ7F6X  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/kubernetes:https */
 
Chain KUBE-SVC-TCOU7JCQXEZGVUNU (1 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 KUBE-SEP-WV6S37CDULKCYEVE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kube-system/kube-dns:dns */


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM