滄州網(wǎng)站設(shè)計公司價格必應(yīng)搜索引擎網(wǎng)站
系列文章目錄
iptables基礎(chǔ)知識
文章目錄
- 系列文章目錄
- 前言
- 一、kube-proxy介紹
- 1、kube-proxy三種工作模式
- 2、iptables中k8s相關(guān)的鏈
- 二、kube-proxy的iptables模式剖析
- 1.集群內(nèi)部通過clusterIP訪問到pod的流程
- 1.1.流程分析
- 2.從外部訪問內(nèi)部service clusterIP后端pod的流程
- 2.1. 流程分析
- 3、外部通過nodeport訪問后端pod的流程
- 3.1.當(dāng)externalTrafficPolicy默認為cluster配置時且從本機訪問后端pod流程
- 3.2.當(dāng)externalTrafficPolicy為Local配置時且從本機訪問后端pod流程
- 三、iptables與ipvs區(qū)別
前言
在一個k8s集群中,微服務(wù)以 Pod形式 運行在我們的集群中,這些 Pod 的副本通過Service 服務(wù)暴露,當(dāng)一個外部請求到達 Service 的虛擬 IP 時,如何將請求轉(zhuǎn)發(fā)到其中一個底層 Pod?這便是本篇文章的核心思想。
一、kube-proxy介紹
kube-proxy是k8s網(wǎng)絡(luò)代理核心組件,部署在每個Node節(jié)點上,主要維護節(jié)點上的網(wǎng)絡(luò)規(guī)則。它是實現(xiàn)service的通信與負載均衡機制的重要組件
kube-proxy負責(zé)為pod創(chuàng)建代理服務(wù),通過watch機制會根據(jù) service 和 endpoints,node資源對象的改變來實時刷新iptables或者ipvs規(guī)則
使發(fā)往 Service 的流量(通過ClusterIP和NodePort)負載均衡到正確的后端Pod。
1、kube-proxy三種工作模式
userspace(目前已經(jīng)棄用)請求是從用戶態(tài)-->內(nèi)核態(tài)-->用戶態(tài),轉(zhuǎn)發(fā)是在用戶態(tài)進行的,效率不高且容易丟包
iptables(默認工作模式)相比于userspace免去了一次內(nèi)核態(tài)-->用戶態(tài)的切換1、kube-proxy通過Api-server的watch接口實時監(jiān)測service和endpoint對象的變化,當(dāng)有service創(chuàng)建時,kube-proxy在iptables中追加新的規(guī)則2、在該模式下,kube-proxy為service后端的每個pod創(chuàng)建對應(yīng)的iptables規(guī)則,直接將發(fā)向cluster ip的請求重定向到一個pod ip3、在該模式下,kube-proxy不承擔(dān)四層代理的角色,只負責(zé)創(chuàng)建iptables規(guī)則補充:在iptables模式下,會根據(jù)service以及endpoints對象的改變來實時刷新規(guī)則,kube-proxy使用了iptables的filter表和nat表,并對 iptables 的鏈進行了擴充,自定義了 KUBE-SERVICES、KUBE-EXTERNAL-SERVICES、KUBE-NODEPORTS、KUBE-POSTROUTING、KUBE-MARK-MASQ、KUBE-MARK-DROP、KUBE-FORWARD 七條鏈。另外還新增了以“KUBE-SVC-xxx”和“KUBE-SEP-xxx”開頭的數(shù)個鏈,除了創(chuàng)建自定義的鏈以外還將自定義鏈插入到已有鏈的后面以便劫持數(shù)據(jù)包。
ipvs1、kube-proxy ipvs模式是基于NAT實現(xiàn)的,對訪問k8s service的請求進行虛擬ip到pod ip的轉(zhuǎn)發(fā)工作原理:當(dāng)創(chuàng)建一個svc后,ipvs模式的kube-proxy會做以下三件事:1、確保kube-ipvs0網(wǎng)卡的存在。因為ipvs的netfilter鉤子掛載input鏈.需要把svc的訪問IP綁定在該網(wǎng)卡上讓內(nèi)核覺得虛IP就是本機IP,從而進入input鏈。2、把svc的訪問ip綁定在該網(wǎng)卡上3、通過socket調(diào)用,創(chuàng)建ipvs的虛擬服務(wù)和真實服務(wù),分別對應(yīng)svc和endpoints注意事項:ipvs用于流量轉(zhuǎn)發(fā),無法處理kube-proxy中的其他問題,例如把包過濾、SNAT等。因此在以下四種情況下kube-proxy依賴iptables:1、kube-proxy配置啟動參數(shù)masquerade-all=true,即集群中所有經(jīng)過kube-proxy的包都做一次SNAT;2、kube-proxy啟動參數(shù)指定集群IP地址范圍;3、支持loadbalance類型的服務(wù)4、支持nodeport類型的服務(wù)
2、iptables中k8s相關(guān)的鏈
名稱 | 含義 |
---|---|
KUBE-SERVICES | 是服務(wù)數(shù)據(jù)包的入口點。它的作用是匹配 目標 IP:port 并將數(shù)據(jù)包分派到對應(yīng)的 KUBE-SVC-* 鏈 |
KUBE-SVC-* | 充當(dāng)負載均衡器,將數(shù)據(jù)包分發(fā)到 KUBE-SEP-* 鏈。KUBE-SEP-* 的數(shù)量等于后面的端點數(shù)量 服務(wù)。選擇哪個 KUBE-SEP-* 是隨機決定的 |
KUBE-SEP-* | 表示 Service EndPoint。它只是執(zhí)行 DNAT,將 服務(wù) IP:端口,以及 Pod 的端點 IP:端口 |
KUBE-MARK-MASQ | 將 Netfilter 標記添加到發(fā)往該服務(wù)的數(shù)據(jù)包中,該標記 源自集群網(wǎng)絡(luò)之外。帶有此標記的數(shù)據(jù)包將被更改 在 POSTROUTING 規(guī)則中使用源網(wǎng)絡(luò)地址轉(zhuǎn)換 (SNAT) 和 node 的 IP 地址作為其源 IP 地址 |
KUBE-MARK-DROP | 為沒有目的地的數(shù)據(jù)包添加 Netfilter 標記 此時已啟用 NAT。這些數(shù)據(jù)包將在 KUBE-FIREWALL 中被丟棄 鏈 |
KUBE-FW-* | chain 在 service 部署時執(zhí)行 LoadBalancer 類型,則 將目標 IP 與服務(wù)的負載均衡器 IP 匹配,并分配 數(shù)據(jù)包到對應(yīng)的 KUBE-SVC-* 鏈或 KUBE-XLB-* 鏈的 KEY-XLB-* 鏈 |
KUBE-NODEPORTS | 發(fā)生在服務(wù)部署在 NodePort 和 LoadBalancer 的 LoadPort 共享 LoadPort 和 LoadBalancer 的有了它,外部源可以訪問該服務(wù) 按 Node Port 的 NODE 端口。它匹配節(jié)點端口并分發(fā) 數(shù)據(jù)包到對應(yīng)的 KUBE-SVC-* 鏈或 KUBE-XLB-* 鏈 的 KEY-XLB-* 鏈 的 |
KUBE-XLB-* | 在 externalTrafficPolicy 設(shè)置為 Local 時工作。有了這個 鏈式編程,如果節(jié)點沒有相關(guān)端點,則數(shù)據(jù)包將被丟棄 保留 |
二、kube-proxy的iptables模式剖析
首先請查看頂部文章鏈接iptables基本知識,對出入棧、四表五鏈有個認知,然后再看下文
包含整改service模式的流程圖
只包含cluster IP、NodePort模式的流程圖
流程圖結(jié)合iptables示例圖
結(jié)合上述流程圖,主要分兩部分對kube-proxy的iptables模式進行剖析
1.集群內(nèi)部通過clusterIP訪問到pod的流程
資源準備,如下圖所示
需求: 當(dāng)在集群pod1訪問curl http://10.102.172.63:8088時,請求是怎么到達后端pod2的?
1.1.流程分析
確定kube-proxy的工作模式兩種方式
[root@master ~]# curl http://127.0.0.1:10249/proxyMode
iptables[root@master ~]# kubectl get configmaps -n kube-system kube-proxy -oyaml |grep modemode: "" #默認為空就是iptables模式
a、進入到pod1,執(zhí)行curl請求
[root@master ~]# kubectl exec -it -n xx xx-xx-6c57d9ddc6-2495v bash
bash-4.2$ curl http://10.102.172.63:8088
xshell多開一個窗口,登錄到pod1宿主機,查看iptables規(guī)則
b、因為從上述iptables流程圖可知,當(dāng)請求從集群內(nèi)部發(fā)出時,先進入的是NAT表中的OUTPUT鏈---->到達KUBE-SERVICE自定義鏈
那么在pod1宿主機中查看output鏈規(guī)則如下所示
[root@xmhl-std12 ~]# iptables -t nat -S |grep -i output
-P OUTPUT ACCEPT
-A OUTPUT -m comment --comment "kubernetes service portals" -j KUBE-SERVICES #此鏈就是入口鏈
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
c、因為是clusterIP模式,因此在KUBE-SERVICES鏈查找到ClusterIP-10.102.172.63,然后根據(jù)結(jié)果將其轉(zhuǎn)發(fā)到KUBE-SVC-*鏈
判斷是否發(fā)生IP偽裝(masquerade all)
從下面可以看到當(dāng)數(shù)據(jù)包來自內(nèi)部 Pod 時,即源 IP 仍然是pod ip。因此未發(fā)生轉(zhuǎn)換,則直接到kube-svc-*鏈
bash-4.2$ curl -s 10.102.172.63:8088 | grep client
bash-4.2$ client_address=10.244.193.194#查看kube-svc-*鏈是否存在
[root@master ~]# iptables -nv -t nat -L KUBE-SERVICES |grep 'zz-trace'0 0 KUBE-SVC-LWBZJHXSVINAPFYY tcp -- * * 0.0.0.0/0 10.102.172.63 /* xos/zz-trace-analyze:web cluster IP */ tcp dpt:8088
d、訪問 KUBE-SVC*鏈 使用隨機數(shù)負載均衡,將請求轉(zhuǎn)發(fā)到kube-sep-*鏈中
#注意事項假如這個KUBE-SVC-LWBZJHXSVINAPFYY鏈里面定義了3條規(guī)則第一條規(guī)則有0.33333333349的概率匹配,也就是1/3的概率命中,第一條沒命中的話第二條規(guī)則有1/2的概率命中,也就是2/3 * 1/2 = 1/3,第二條沒命中的話就去第3條了。很明顯,這里是在做負載均衡,那我們可以確認這3條規(guī)則后面的target就是這個service代理的3個pod相關(guān)的規(guī)則了[root@master ~]# iptables -nv -t nat -L KUBE-SVC-LWBZJHXSVINAPFYY
Chain KUBE-SVC-LWBZJHXSVINAPFYY (1 references)pkts bytes target prot opt in out source destination 0 0 KUBE-SEP-SU7QRQC2MJZZVHTR all -- * * 0.0.0.0/0 0.0.0.0/0 /* xos/zz-trace-analyze:web */
e、每個 KUBE-SEP-* 鏈分別代表一個 Pod 或終端節(jié)點
重點
它包括兩個操作:1) 從 Pod 轉(zhuǎn)義的數(shù)據(jù)包是使用主機的 docker0 IP 進行源 NAT 處理的。 2) 進入 Pod 的數(shù)據(jù)包使用 Pod 的 IP 進行 DNAT 處理,然后路由到后端 Pod
查詢?nèi)缦滤? 從結(jié)果可以清晰的看到 pod1請求pod2的svc后,進入到pod2的數(shù)據(jù)包使用 Pod 的 IP 進行了 DNAT 處理,直接到達了pod2的目標pod
[root@master ~]# iptables -nv -t nat -L KUBE-SEP-SU7QRQC2MJZZVHTR
Chain KUBE-SEP-SU7QRQC2MJZZVHTR (1 references)pkts bytes target prot opt in out source destination 0 0 KUBE-MARK-MASQ all -- * * 10.244.8.182 0.0.0.0/0 /* xos/zz-trace-analyze:web */0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* xityos/zz-trace-analyze:web */ tcp to:10.244.8.182:18080
f、之后nat表的OUTPUT鏈中的規(guī)則結(jié)束,進入filter的OUTPUT鏈
[root@master ~]# iptables -t filter -S |grep OUTPUT
-P OUTPUT ACCEPT
-A OUTPUT -m conntrack --ctstate NEW -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A OUTPUT -j KUBE-FIREWALL #即nat表的OUTPUT鏈完成后進入到filter表中的OUTPUT鏈
g、可以看到所有新建的連接(ctstate NEW)都會匹配第一條規(guī)則KUBE-SERVICES,而當(dāng)查看filter表中的KUBE-SERVICES鏈時,會發(fā)現(xiàn)這是一條空鏈。所以重點看第二條規(guī)則KUBE-FIREWALL
[root@master ~]# iptables -nv -t filter -L KUBE-FIREWALL
Chain KUBE-FIREWALL (2 references)pkts bytes target prot opt in out source destination 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes firewall for dropping marked packets */ mark match 0x8000/0x80000 0 DROP all -- * * !127.0.0.0/8 127.0.0.0/8 /* block incoming localnet connections */ ! ctstate RELATED,ESTABLISHED,DNAT可以看到,所有被標記了0x8000/0x8000的數(shù)據(jù)包都會被直接DROP掉,而我們的數(shù)據(jù)包一路走過來沒有被標記,所以不會被DROP。
這樣一來filter的OUTPUT規(guī)則也走完了,終于進入了下一個階段 -- POSTROUTRING鏈
h、POSTROUTING鏈涉及到2個表:mangle和nat,mangle表一般不使用,所以只需要關(guān)注nat表的POSTROUTING規(guī)則
[root@master ~]# iptables -nv -t nat -L |grep POSTROUTING
Chain POSTROUTING (policy ACCEPT 26679 packets, 2287K bytes)11M 982M KUBE-POSTROUTING all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes postrouting rules */
Chain KUBE-POSTROUTING (1 references)
i、先進入target,KUBE-POSTROUTING
[root@master ~]# iptables -nv -t nat -L KUBE-POSTROUTING
Chain KUBE-POSTROUTING (1 references)pkts bytes target prot opt in out source destination
27635 2364K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 mark match ! 0x4000/0x400047 2820 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MARK xor 0x400047 2820 MASQUERADE all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service traffic requiring SNAT */此時會發(fā)現(xiàn)這條規(guī)則會把所有標記了0x4000/0x4000的數(shù)據(jù)包全部MASQUERADE SNAT,由于我們的數(shù)據(jù)包沒有被標記過,所以不匹配這條規(guī)則。
當(dāng)數(shù)據(jù)包匹配到MASQUERADE的話,當(dāng)前表的剩余規(guī)則將不再匹配。
至此,集群內(nèi)部通過clusterIP訪問到pod的鏈路流程剖析完成,整理一下整個過程
數(shù)據(jù)包經(jīng)歷的鏈路:數(shù)據(jù)包 --> nat的OUTPUT--> nat的KUBE-SERVICES --> nat的KUBE-SVC-LWBZJHXSVINAPFYY--> nat的KUBE-SEP-SU7QRQC2MJZZVHTR(多選1,隨機負載均衡,被DNAT)--> filter的OUTPUT --> filter的KUBE-SERVICES -->filter的KUBE-FIREWALL --> nat的POSTROUTING --> nat的KUBE-POSTROUTING --> 沒有被NAT
語言描述:0、當(dāng)集群內(nèi)部通過clusterIP訪問到pod時,會發(fā)生以下過程1、對于進入 NAT表的OUTPUT 鏈的都轉(zhuǎn)到 KUBE-SERVICES 鏈進行處理2、在 KUBE-SERVICES 鏈,對于訪問 clusterIP 為 10.102.172.63 的轉(zhuǎn)發(fā)到 KUBE-SVC-LWBZJHXSVINAPFYY3、訪問 KUBE-SVC-LWBZJHXSVINAPFYY 的使用隨機數(shù)負載均衡,并轉(zhuǎn)發(fā)到 KUBE-SEP-SU7QRQC2MJZZVHTR上4、KUBE-SEP-SU7QRQC2MJZZVHTR對應(yīng) endpoint 中的 pod 10.244.8.182,設(shè)置 mark 標記,進行 DNAT 并轉(zhuǎn)發(fā)到具體的 pod 上5、當(dāng)nat表中的output鏈完成后,會進入filter表中OUTPUT鏈中的KUBE-FIREWALL自定義鏈,可以看到,所有被標記了0x8000/0x8000的數(shù)據(jù)包都會被直接DROP掉,反之則不會被drop6、最后進入到NAT表中的POSTROUTING鏈,此時會發(fā)現(xiàn)這條規(guī)則會把所有標記了0x4000/0x4000的數(shù)據(jù)包全部MASQUERADE SNAT,由于我們的數(shù)據(jù)包沒有被標記過,所以不匹配這條規(guī)則。當(dāng)數(shù)據(jù)包匹配到MASQUERADE的話,當(dāng)前表的剩余規(guī)則將不再匹配7、至此,剖析結(jié)束
2.從外部訪問內(nèi)部service clusterIP后端pod的流程
2.1. 流程分析
需求: 從外部機器中訪問http://10.102.172.63:8088 這個clusterip svc的后端pod
a、因為從上述iptables流程圖可知,當(dāng)請求從外部發(fā)出時,先進入的是NAT表中的PREROUTING鏈---->到達KUBE-SERVICE自定義鏈
[root@master ~]# iptables -t nat -S |grep PREROUTING
-P PREROUTING ACCEPT
-A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
b、因為是clusterIP模式,因此在KUBE-SERVICES鏈查找到ClusterIP-10.102.172.63,然后根據(jù)結(jié)果將其轉(zhuǎn)發(fā)到KUBE-SVC-*鏈
判斷是否發(fā)生IP偽裝(masquerade all)
從下面我們可以看到,當(dāng)從外部(而不是從 pod)訪問服務(wù)時,源 IP 替換為 nodeIP;
cactus@master01:~$ curl --interface 外部地址 -s 10.102.172.63:8088 | grep client
client_address=10.244.1.0
[root@master ~]# conntrack -L -d 10.102.172.63
tcp 6 56 TIME_WAIT src=10.8.21.231 dst=10.102.172.63 sport=56688 dport=8088 src=10.244.8.182 dst=10.244.1.0 sport=18080 dport=50534 [ASSURED] mark=0 use=1#查看kube-svc-*鏈是否存在
[root@xmhl-std24 ~]# iptables -nvL -t nat |egrep -i 'kube-mark-masq' |grep zz-trace0 0 KUBE-MARK-MASQ all -- * * 10.244.8.182 0.0.0.0/0 /* cityos/zz-trace-analyze:web */[root@master ~]# iptables -nv -t nat -L KUBE-SERVICES |grep 'zz-trace'0 0 KUBE-SVC-LWBZJHXSVINAPFYY tcp -- * * 0.0.0.0/0 10.102.172.63 /* xos/zz-trace-analyze:web cluster IP */ tcp dpt:8088
接下來的分析步驟和集群內(nèi)部通過clusterIP訪問到pod的流程中c-i過程一致,在此不做過多描述
至此,集群內(nèi)部通過clusterIP訪問到pod的鏈路流程剖析完成,整理一下整個過程
數(shù)據(jù)包經(jīng)歷的鏈路:數(shù)據(jù)包 --> nat的PREROUTING--> nat的KUBE-SERVICES --> nat的KUBE-SVC-LWBZJHXSVINAPFYY--> nat的KUBE-SEP-SU7QRQC2MJZZVHTR(多選1,隨機負載均衡,被DNAT)--> filter的OUTPUT --> filter的KUBE-SERVICES -->filter的KUBE-FIREWALL --> nat的POSTROUTING --> nat的KUBE-POSTROUTING --> 沒有被NAT
語言描述:0、當(dāng)集群內(nèi)部通過clusterIP訪問到pod時,會發(fā)生以下過程1、對于進入 NAT表的PREROUTING 鏈的都轉(zhuǎn)到 KUBE-SERVICES 鏈進行處理2、在 KUBE-SERVICES 鏈,對于訪問 clusterIP 為 10.102.172.63 的轉(zhuǎn)發(fā)到 KUBE-SVC-LWBZJHXSVINAPFYY3、訪問 KUBE-SVC-LWBZJHXSVINAPFYY 的使用隨機數(shù)負載均衡,并轉(zhuǎn)發(fā)到 KUBE-SEP-SU7QRQC2MJZZVHTR上4、KUBE-SEP-SU7QRQC2MJZZVHTR對應(yīng) endpoint 中的 pod 10.244.8.182,設(shè)置 mark 標記,進行 DNAT 并轉(zhuǎn)發(fā)到具體的 pod 上5、當(dāng)nat表中的output鏈完成后,會進入filter表中OUTPUT鏈中的KUBE-FIREWALL自定義鏈,可以看到,所有被標記了0x8000/0x8000的數(shù)據(jù)包都會被直接DROP掉,反之則不會被drop6、最后進入到NAT表中的POSTROUTING鏈,此時會發(fā)現(xiàn)這條規(guī)則會把所有標記了0x4000/0x4000的數(shù)據(jù)包全部MASQUERADE SNAT,由于我們的數(shù)據(jù)包沒有被標記過,所以不匹配這條規(guī)則。當(dāng)數(shù)據(jù)包匹配到MASQUERADE的話,當(dāng)前表的剩余規(guī)則將不再匹配7、至此,剖析結(jié)束
3、外部通過nodeport訪問后端pod的流程
將根據(jù)上述圖1分析兩種類型的 NodePort 服務(wù):1、默認服務(wù) (externalTrafficPolicy: Cluster)2、externalTrafficPolicy:local
3.1.當(dāng)externalTrafficPolicy默認為cluster配置時且從本機訪問后端pod流程
a、從本機訪問首先進入NAT表的OUTPUT鏈,然后進入到kube-nodeports鏈
所有訪問端口 64438的數(shù)據(jù)包,首先要進行 SNAT 處理,然后才能進行kube-svc-*鏈進行負載均衡
[root@master ~]# iptables -t nat -S |grep OUTPUT
-P OUTPUT ACCEPT
-A OUTPUT -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER[root@master ~]# iptables -nv -t nat -L KUBE-NODEPORTS |grep 'xx-flow'0 0 KUBE-MARK-MASQ tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* xos/xx-flow:debug-port */ tcp dpt:644380 0 KUBE-SVC-UFDICDG36KRBVVWD tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* xos/xx-flow:debug-port */ tcp dpt:64438
b、可以看到數(shù)據(jù)包先會命中第一條規(guī)則KUBE-MARK-MASQ,然后是第二條規(guī)則到達
[root@master ~]# iptables -t nat -L KUBE-MARK-MASQ
Chain KUBE-MARK-MASQ (165 references)
target prot opt source destination
MARK all -- anywhere anywhere MARK or 0x4000在這里數(shù)據(jù)包會被標記上0x4000標記,然后回到KUBE-NODEPORTS鏈中繼續(xù)匹配下一條規(guī)則,下一條規(guī)則就是KUBE-SVC-UFDICDG36KRBVVWD[root@master ~]# iptables -t nat -L KUBE-SVC-BCUGWLTE6RKBKCZT
Chain KUBE-SVC-BCUGWLTE6RKBKCZT (2 references)
target prot opt source destination
KUBE-SEP-2SQRA2EPJ5ESOFTW all -- anywhere anywhere /* xos/xx-flow:web */ statistic mode random probability 0.50000000000
KUBE-SEP-QUKANZ2W6FTD6P23 all -- anywhere anywhere /* xos/xx-flow:web */
c、接下來一路到nat的POSTROUTING為止都與ClusterIP模式相同,但在接下來的nat的KUBE-POSTROUTING階段,由于我們的數(shù)據(jù)包在KUBE-MARK-MASQ被打上了0x4000標記,在這里會命中這條規(guī)則,從而被MASQUERADE(SNAT)
[root@xmhl-std11 ~]# iptables -nv -t nat -L KUBE-POSTROUTING
Chain KUBE-POSTROUTING (1 references)pkts bytes target prot opt in out source destination
41065 3455K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 mark match ! 0x4000/0x400022 1320 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MARK xor 0x400022 1320 MASQUERADE all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service traffic requiring SNAT */
至此,當(dāng)externalTrafficPolicy默認為cluster配置時且從本機訪問后端pod流程剖析完成
數(shù)據(jù)包經(jīng)歷的鏈路:
數(shù)據(jù)包 --> nat的OUTPUT --> nat的KUBE-SERVICES --> nat的KUBE-NODEPORTS --> nat的KUBE-MARK-MASQ (被標記) --> nat的KUBE-SVC-GKN7Y2BSGW4NJTYL--> nat的KUBE-SEP-ISPQE3VESBAFO225(3選1,被DNAT)--> filter的OUTPUT --> filter的KUBE-SERVICES -->filter的KUBE-FIREWALL --> nat的POSTROUTING --> nat的KUBE-POSTROUTING --> 被SNAT