K8S网络策略总结
目錄
1、K8S網絡要求
2、網絡鏈路
(1)Internet與Service之間的網絡
1)node到internet的網絡
2)Internet到node的網絡
(2)Service與Pod之間的網絡
2)service到pod包的流轉
(3)Pod與Pod之間的網絡
1)同一臺node節點上pod和pod通信
2)不同node節點上pod和pod通信
(4)容器和容器之間的網絡
1、K8S網絡要求
(1)Pods與Pods之間、Nodes與Nodes之間可以在不使用NAT網絡地址轉換的情況下相互通信。
(2)每個Pod都擁有一個獨立的 IP地址,且每個Pod自己看到的自己的ip和其他Pod看到的一致,即Pod內部的應用程序看到的自己的IP地址和端口與集群內其他Pod看到的一樣。
(3)不論Pod是否運行在同一個Node中,他們都可以同歸對方IP進行訪問。
2、網絡鏈路
(1)Internet與Service之間的網絡
(2)Service與Pod之間的網絡
(3)Pod與Pod之間的網絡
(4)容器和容器之間的網絡
(1)Internet與Service之間的網絡
1)node到internet的網絡
數據包源自pod1網絡命名空間,通過veth對連接到root網絡命名空間,緊接著,轉發表里沒有IP對應的mac,會發送到默認路由,到達root網絡命名空間的eth0那么在到達root網絡明明空間之前,iptables會修改數據包,現在數據包源ip是pod1的,繼續傳輸會被Internet網關拒絕掉,因為網關NAT僅轉發node的ip,解決方案:使iptables執行源NAT更改數據包源ip,讓數據包看起來是來自于node而不是pod,iptables修改完源ip之后,數據包離開node,根據轉發規則發給Internet網關,Internet網關執行另一個NAT,內網ip轉為公網ip,在Internet上傳輸。
流程見下圖:
2)Internet到node的網絡
讓Internet流量進入k8s集群,這特定于配置的網絡,可以在網絡堆棧的不同層來實現:NodePort、Service LoadBalancer、Ingress控制器。
客戶端現針對www.1234.com執行dns解析,DNS服務器返回ingress控制器的ip,客戶端拿到ip后,向ingress控制器發送http的get請求,將域名加在host頭部發送。控制器接收到請求后,從host頭部就知道了該訪問哪一個服務,通過與該service關聯的endpoint對象查詢podIP地址,將請求進行轉發。
(2)Service與Pod之間的網絡
分析:
當集群中pod的規模縮減或者pod故障或者node故障重啟后,新的pod的ip就可能與之前的不一樣的,所以k8s中用Service來解決這個問題。Service管理了多個Pods,每個Service有一個虛擬的ip,要訪問service管理的Pod上的服務只需要訪問你這個虛擬ip就可以了,這個虛擬ip是固定的,當service下的pod規模改變、故障重啟、node重啟時候,對使用service的用戶來說是無感知的,因為他們使用的service的ip沒有變。
原理:
當數據包到達Service虛擬ip后,數據包會通過k8s給servcie自動創建的負載均衡器路由到背后的pod容器。在k8s里,iptables規則是由kube-proxy配置,kube-proxy監視APIserver的更改,因為集群中所有service(iptables)更改都會發送到APIserver上,所以每臺kubelet-proxy監視APIserver,當對service或pod虛擬IP進行修改時,kube-proxy就會在本地更新,以便正確發送給后端pod
1)pod到service包的流轉
數據包從pod1所在eth0離開,通過veth對的另一端veth0傳給網橋cbr0,網橋找不到service的ip對應的mac,交給了默認路由,到達了root命名空間的eth0。 root命名空間的eth0接受數據包之前會經過iptables進行過濾,iptables接受數據包后使用kube-proxy在node上配置的規則響應service, 然后數據包的目的ip重寫為service后端指定的pod的ip。
流程如下圖:
2)service到pod包的流轉
收到包的pod會回應數據包到源pod,源ip是發送方ip,目標IP是接收方,數據包進行回復時經過iptables,iptables使用內核機制conntrack記住它之前做的選擇,又將數據包源ip重新為service的ip,目標ip不變,然后原路返回至pod1的eth0
(3)Pod與Pod之間的網絡
pod自身擁有一個IP地址,不同pod之間直接使用IP地址進行通信。
1)同一臺node節點上pod和pod通信
同一臺node節點上,不同pod(不同網絡命名空間)之間如何通信?veth對是一個成對的端口,所有從這對端口一端進入的數據包,都將從另一端出來。為了讓多個Pod的網絡命名空間鏈接起來,我們可以讓veth對的一端鏈接到root網絡命名空間(宿主機的),另一端鏈接到Pod的網絡命名空間。
?另外,需要用到一個Linux以太網橋,它是一個虛擬的二層網絡設備,目的就是把多個以太網段連接起來,它維護一個轉發表,通過查看每個設備mac地址決定轉發,還是丟棄數據。
流程如下圖:
描述:pod1-->pod2(同一臺node上),pod1通過自身eth0網卡發送數據,eth0連接著veth0,網橋把veth0和veth1組成了一個以太網,然后數據到達veth0之后,網橋通過轉發表,發送給veth1,veth1直接把數據傳給pod2的eth0。
2)不同node節點上pod和pod通信
k8s集群中,每個node節點都會被分配一個CIDR塊(把網絡前綴都相同的連續地址組成地址組稱為CIDR地址塊)用來給node上的pod分配IP地址,另外還需要把pod的ip和所在nodeip進行關聯。
流程如下圖:
描述:比如node1上pod1和node2上的pod4進行通信。首先,pod1上網卡eth0將數據發送給已經管理到root命名空間的veth0上,被虛擬網橋收到,查看自己轉發表之后,并沒有pod4的mac地址。然后,把包轉發到默認路由,root命名空間的eth0上,也就是已經到了node節點的往卡上,通過eth0發送到網絡中。最后,尋址轉發后包來到了node2,先被root命名空間的eth0設備接受,查看目標地址是發往pod4的,交給虛擬網橋路由到veth1,最終傳給pod4的eth0上。
(4)容器和容器之間的網絡
pod有多個容器,它們之間怎么通信?pod中每個docker容器和pod在一個網絡命名空間內,所以ip和端口等等網絡配置都和pod一樣。通過docker的一種網絡模式使新創建的Docker容器不會創建自己的網卡和IP,而是和一個指定的容器共享IP、端口等配置。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結