目錄
- Pod
- Kubernetes 網絡模型
- 同一Pod上的容器之間進行通信
- 同一Node上的不同Pod之間進行通信
- 不同Node上的Pod之間進行通信
- Service
- 參考
Pod
首先來回顧一下Pod:
Pod 是用于構建應用程序的最小可部署對象。單個 Pod 代表集群中正在運行的工作負載,并封裝一個或多個 Docker 容器、任何所需的存儲以及唯一的 IP 地址。
Kubernetes 網絡模型
集群中每一個 Pod 都會獲得自己的、 獨一無二的 IP 地址。一個Pod里的一組容器共享相同的IP地址。
Kubernetes 強制要求所有網絡設施都滿足以下基本要求(從而排除了有意隔離網絡的策略):
- Pod 能夠與所有其他節點上的 Pod 通信, 且不需要網絡地址轉譯(NAT)
- 節點上的代理(比如:系統守護進程、kubelet)可以和節點上的所有 Pod 通信。
考慮到這些限制,我們剩下四個不同的網絡問題需要解決:
- 容器到容器網絡
- Pod 到 Pod 網絡
- Pod 到服務網絡
- 互聯網到服務網絡
同一Pod上的容器之間進行通信
通常,我們將虛擬機中的網絡通信視為直接與以太網設備交互。默認情況下,Linux 將每個進程分配給根網絡命名空間,以提供對外部世界的訪問。如下圖所示:
Pod 被建模為一組共享網絡命名空間的 Docker 容器。Pod 中的容器都具有通過分配給 Pod 的網絡命名空間分配的相同 IP 地址和端口空間,并且可以通過 localhost 找到彼此,因為它們駐留在同一命名空間中。
根本原因是使用Docker的一種網絡模型:–net=container 能夠讓同一個Pod內的多個docker容器相互通信。
container模式指定新創建的Docker容器和已經存在的一個容器共享一個網絡命名空間,也就是說新創建的Docker容器不會創建自己的網卡,配置自己的 IP,而是和一個指定的容器共享 IP、端口范圍等。
在k8s中每個Pod容器有一個pause容器,它擁有獨立的網絡命名空間,在Pod內啟動Docker容器時候使用 –net=container就可以讓當前Docker容器加入到Pod容器擁有的網絡命名空間(pause容器)。
同一Node上的不同Pod之間進行通信
從 Pod 的角度來看,它存在于自己的以太網命名空間中。不同的Pod存在于不同的網絡命名空間里。
但是可以使用Linux虛擬以太網設備或由兩個虛擬接口組成的veth對 將兩個網絡命名空間進行連接 。要連接 Pod 命名空間,我們可以將 veth 對的一側分配給根網絡命名空間,將另一側分配給 Pod 的網絡命名空間。然后使用網橋把兩個虛擬網絡組成為一個以太網。如下圖所示:
在上面這個網絡模型下,Pod之間是如何通信的呢?
- Pod 1 向其自己的以太網設備發送數據包eth0,該設備可作為 Pod 的默認設備。對于 Pod 1,eth0通過虛擬以太網設備連接到根命名空間veth0
- 網橋cbr0配置有veth0連接到它的網段。一旦數據包到達網橋,網橋就會使用 ARP 協議解析將數據包發送到的正確網段
- 當數據包到達虛擬設備veth1時,它會直接轉發到 Pod 2 的命名空間以及該命名空間內的設備eth0
不同Node上的Pod之間進行通信
同樣會用到虛擬接口和網橋。
- 數據包首先通過 Pod 1 的以太網設備發送,該設備與根命名空間 中的虛擬以太網設備配對。最終,數據包到達根命名空間的網橋
- ARP 將在網橋處失敗,因為沒有設備連接到具有數據包正確 MAC 地址的網橋。發生故障時,網橋將數據包從默認路由(根命名空間的eth0設備)發送出去。此時,路由離開節點并進入網絡
- 我們現在假設網絡可以根據分配給節點 的 CIDR 塊將數據包路由到正確的節點。數據包進入目標節點(在 VM 2 上)的根命名空間eth0,并通過網橋路由到正確的虛擬以太網設備
- 最后,路由通過駐留在 Pod 4 命名空間內的虛擬以太網設備對完成
一般來說,每個節點都知道如何將數據包傳遞到在其內運行的 Pod。一旦數據包到達目標節點,數據包的流動方式與在同一節點上的 Pod 之間路由流量的方式相同。
Service
我們要知道,Pod的IP地址不持久,會隨著擴展或縮小、應用程序崩潰或節點重啟而出現和消失。哪怕重啟一個Pod,它的IP也可能和前一次不一樣。
所以Kubernetes 里使用Service來管理一組 Pod 的狀態,允許我們跟蹤一組隨時間動態變化的 Pod 的IP 地址。Service充當 Pod 的抽象,并將單個虛擬 IP 地址分配給一組 Pod 的IP 地址。
任何發送到服務虛擬 IP 的流量都將被路由到與該虛擬 IP 關聯的 Pod 集。這允許與 Service 關聯的 Pod 集隨時更改 ,只要虛擬IP不改,客戶端就感覺不到Pod的變化。
創建新的 Kubernetes Service時,系統會創建一個新的虛擬 IP(也稱為集群 IP)。集群內的任何位置,尋址到虛擬 IP 的流量都將負載均衡到與Service關聯的一組Pod。實際上,Kubernetes 會自動創建并維護一個分布式集群內負載均衡器,該均衡器將流量分配到Service關聯的健康 Pod。
參考
https://sookocheff.com/post/kubernetes/understanding-kubernetes-networking-model/
https://kubernetes.io/zh-cn/docs/concepts/services-networking/