儲備知識:四表五鏈,表里有鏈,鏈里有規則
四表:raw>mangle>nat>filter
五鏈:input、output、forward、prerouting、postrouting
https://www.cnblogs.com/linhaifeng/p/15979888.html
概念
kube-proxy 實際上並不起一個 proxy 的作用,而是 watch 變更並更新 iptables,也就是說,client 的請求直接通過 iptables 路由。
如果kube-proxy通過iptables 轉發。會修改filter和nat表
filter表
filter表通過OUTPUT鏈規定所有的出報文都要經過KUBE-SERVICES,如果一個Service沒有對應的endpoint,則拒絕將報文發出。
例如,創建一個service,下圖的frontend,沒有對應的endPoint
查看filter:iptables -L -n -t filter
filter表中會將訪問172.18.13.31的請求拒絕。
nat表
nat表中設置的規則比較多,查看nat表命令:iptables -L -n -t nat
1、在PREROUTING階段,將所有報文轉發到KUBE-SERVICES
2、在OUTPUT階段,將所有報文轉發到KUBE-SERVICES
3、在POSTROUTING階段,將所有報文轉發到KUBE-POSTROUTING
nat表中主要增加了如下幾個鏈-規則
1)KUBE-SERVICES
每個Service的每個服務端口都會在Chain KUBE-SERVICES中有一條對應的規則,發送到clusterIP的報文,將會轉發到對應的Service的規則鏈,沒有命中ClusterIP的,轉發到KUBE-NODEPORTS。
只有發送到被kubernetes占用的端口的報文才會進入KUBE-MARK-MASQ打上標記,並轉發到對應的服務規則鏈。例如第一條划線的KUBE-MARK-MASQ這里分配給SERVICE的端口是3306,該端口的包由kuberentes管理.
2)KUBE-SVC-YG65S75AKNCDZRSF (2 references) 
而每一個SERVICE,又將報文提交到了各自的KUBE-SEP-XXX。
3)KUBE-SEP-VFIT54JSXZ4WRSH5 (1 references)
最后在KUBE-SEP-XX中完整了最終的DNAT,將目的地址轉換成了POD的IP和端口。
這里的KUBE-MARK-MASQ為報文打上了標記,表示這個報文是由kubernetes管理的,Kuberntes將會對它進行NAT轉換。
4)KUBE-NODEPORTS (1 references)
KUBE-NODEPORT中,根據目的端口,將報文轉發到對應的Service的規則鏈,然后就如同在“Chain KUBE-SERVICES”中的過程,將報文轉發到了對應的POD。
5)KUBE-POSTROUTING (1 references)
這里表示k8s管理的報文(也就是被標記了0x4000的報文),在離開Node(物理機)的時候需要進行SNAT轉換。
也就是POD發出的報文。
報文處理流程圖
集群內部通過clusterIP訪問到pod的流程
(KUBE-SVC@nat) (KUBE-SERVICES +->SVC1 OUTPUT @filter,nat) | (KUBE-SEP@nat) PKT ----->命中ClusterIP ----------+->SVC2 -->SEP1,Mark0x0400,DNAT | | | | +->SVC3 | | | | | | +-----------------+ | +------------> | POSTROUTING | <----------+ +--------+--------+ | | match 0x0400,SNAT@nat | | 網卡 ————————————————
也可以理解為從Node發出的報文的處理過程。因為這個數據包是通過本地協議發出的,然后需要更改NAT表,那么k8s就在OUTPUT這個鏈上來動手。
例1:在集群內部通過ClusterIP:pod端口訪問相應的pod
本例子中ClusterIP為172.18.13.113,對應的pod容器的端口為8080,對應兩個pod。
訪問命令為curl 172.18.13.113:8082
1、經過OUTPUT鏈時指出報文要經過KUBE-SERVICES
2、在KUBE-SERVICES鏈查找到ClusterIP-172.18.13.113,於是轉發到鏈KUBE-SVC-YG65S75AKNCDZRSF
3、在KUBE-SVC-YG65S75AKNCDZRSF鏈中,因為該clusterIP對應兩個pod,所有該鏈下有兩條規則,同時實現第一條規則的概率為0.5。
4、假設我們轉到了鏈KUBE-SEP-3BN22EQZG75AYFUY,在該鏈中對這個包進行了一次DNAT轉換,轉到172.17.9.2中,即pod的ip地址。
通過外部nodeport訪問后端pod的流程
(KUBE-SVC@nat) +->SVC1 (KUBE-SERVICES@nat) | (KUBE-SEP@nat) +--->命中ClusterIP --------------------+->SVC2 -->SEP1,Mark0x0400,DNAT PREROUTING | ^ | | PKT -->| | +->SVC3 | | | | +--->未命中ClusterIP --->命中服務端口 | | | +->未命中服務端口 | | | | | +-----------------------------+ | INPUT |--> END +-----------------------------+
也可以理解為發送到Node的報文的處理過程
例2:我們在集群外的機器通過pod暴露的端口30002訪問相應的pod.
其中集群外機器IP為172.18.52.170,pod所在機器為192.168.204.144,暴露在該機器的端口為30002。
訪問命令為curl 192.168.204.144:30002
1、集群外機器172.18.52.170根據路由規則將數據包發送到pod所在機器192.168.204.144。
2、數據包進入了pod所在的機器,所以k8s對該機器nat表的PREROUTING鏈做規則。鏈時指出報文要經過KUBE-SERVICES。
3、把數據包轉到KUBE-SERVICES這個鏈之后,因為我們是通過nodeport訪問的,所有沒有匹配到clusterIP,轉到KUBE-NODEPORTS鏈上。
4、KUBE-NODEPORTS還是將數據包轉到KUBE-SVC-VZEERQ5BHBSZ5PRL上,打上標簽。再轉到KUBE-SVC-YG65S75AKNCDZRSF鏈中,DNAT轉換。
轉載:https://blog.csdn.net/qq_36183935/article/details/90734847