K8S網絡通信 ---- Kubernetes

1. K8S網絡模型

       Kubernetes 的網絡模型假定了所有Pod 都在一個可以直接連通的扁平的網絡空間中,Kubernetes的扁平化是指所有的 Pod 都可以通過對方的 IP “直接到達”(其實有很多轉換機制,如Flannel)。這在GCE(Google Compute Engine)裏面是現成的網絡模型,Kubernetes 假定這個網絡已經存在。而在私有云裏搭建 Kubernetes 集羣,就不能假定這個網絡已經存在了。我們需要自己實現這個網絡假設,將不同節點上的Docker 容器之間的互相訪問先打通,然後運行Kubernetes。Flannel可以實現這個扁平化的網絡空間

       第一種通信模式:同一個Pod的多個容器之間的訪問通過 lo。同一個Pod 內的多個容器公用pause容器的網絡棧,這些容器之間的訪問走的是這個網絡棧的 IO,不需要網卡,通過 localhost 的方式訪問。第二種通信模式:Pod 與Service 之間的通訊。Pod 與Service 之間的通訊是通過各節點的Iptables 規則,最新版本中已經加入了LVS的機制來實現轉換,轉換效率會更高。第三種通信模式:各 Pod 之間的通訊。各 Pod 之間的通訊採用 Overlay Network,即全覆蓋網絡。

2. K8S網絡解決方案

       Flannel 是 CoreOS 團隊針對Kubernetes 設計的一個網絡規劃服務,符合 CRI,即容器運行時接口。簡單來說,它的功能是讓 集羣中的不同節點主機創建的 Docker 容器都具有全集羣唯一的虛擬IP地址。而且它還能在這些IP 地址之間建立一個覆蓋網絡(Overlay Network)。通過這個覆蓋網絡,將數據包原封不動地傳遞到目標容器內。Docker 容器的 IP 唯一是容易解決的,需要修改 Docker0 分配的網段,那麼容器的 IP 就是不一樣。Docker 中不同容器之間的訪問是比較難實現的,可以看下 Flannel 是如何解決的。
在這裏插入圖片描述
       真實 Node 服務器上會安裝一個 Flanneld 的守護進程,這個進程會監聽一個端口,這個端口用於後期轉發和接收數據包。Flanneld 啓動之後會開啓網橋Flannel0,Flannel0專門收集Docker0轉發出來的數據報文。Docker0會分配自己的IP到對應的Pod上。如果是同一臺主機的不同 Pod 之間訪問走的是 Docker0 的網橋。因爲這些 Pod 都是在在同一個網橋下面的子網中,是可以走 Docker0 的網橋。圖示如下:
在這裏插入圖片描述
       跨主機 通過對方的IP訪問對方,比如 Web app02 訪問 Backend,10.1.15.2/24和10.1.20.3/24不是同一個網段。Web app02 把數據報文發送到投入它的網關 Docker0,Docker0 中會有對應的鉤子函數把數據包抓取到 Flannel0,這裏還會有很多 從ETCD中獲取的路由表記錄被寫入到主機,用來判斷路由到哪臺機器。

       Flannel0 是 Flanneld 開啓的網橋,所以 數據包會到Flanneld,Flanneld會對數據報文進行解封裝,目標寫的是192.168.66.2(圖上的錯了)。Flanneld 使用的是 udb 來轉發數據包,因爲局域網內更快。Payload 是外部數據包實體,解封裝之後數據包被轉發到目標Node主機。目標端口是 Flanneld 的端口,所以這個 數據包會被Flanneld所截獲,然後拆分數據包,再轉發到Flannel0,Flannel0轉發到Docker0,Docker0分配到Backend Pod。這裏是經過二次解封的,第一層信息 Docker0是看不到的,只能看到第二層。這樣就可以實現跨主機的扁平化網絡。圖示如下:
在這裏插入圖片描述
       另外,Flannel 和 ETCD 之間有哪些關聯。① 第一點:存儲管理 Flannel 可分配的 IP 地址段的資源,Flannel 在啓動的時候會向 ETCD 中插入可以被分配的網段,並且記錄把哪個網段分配到哪些機器上,防止已經分配的網段再被Flannel利用,分配到其它的Node節點。第二點:監控 ETCD 中每個 Pod 的實際地址,並在內存中建立維護 Pod 節點路由表。可以利用這個路由表判斷 Pod 對應的主機地址是(192.168.66.2)。

3. K8S網絡通信方式

同一個 Pod 內部通訊:同一個Pod 共享同一個網絡命名空間,共享同一個Linux 協議棧,使用的是 lo,即迴環網卡。

兩個Pod之間的訪問:① Pod1與Pod2不在同一臺主機,Pod 的地址是與 docker0在同一個網段的,但docker0網段與宿主機網卡是兩個完全不同的IP網段,並且不同Node之間的通信只能通過宿主機的物理網卡進行。將Pod的IP和所在Node的IP關聯起來,通過這個關聯讓Pod可以互相訪問;② Pod1與Pod2在同一臺機器,由 Docker0 網橋直接轉發請求至 Pod2,不需要經過Flannel。

Pod 至 Service 的網絡:目前基於性能考慮,全部爲 iptables 維護和轉發,最新版是LVS轉發和維護

Pod 到外網:Pod 向外網發送請求,查找路由表, 轉發數據包到宿主機的網卡,宿主網卡完成路由選擇後,iptables 執行 Masquerade 把源 IP 更改爲宿主網卡的 IP,然後向外網服務器發送請求。這是一種動態轉換

外網訪問 Pod:通過 Service 的**NodePort**方式,雖然是扁平化網絡,但這個扁平化網絡是私有網絡,不能夠在訪問到與物理機器相連網絡的主機。

K8S中三層網絡,如組件通訊示意圖:
在這裏插入圖片描述
真實的物理網絡只有一個就是節點網絡,構建服務器的時候只需要一張網卡就可以實現。Service 網絡和 Pod 網絡是虛擬網絡,屬於內網中。所有的 Pod 都會在扁平化的網絡(Pod)中通信。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章