Kubernetes網路的視覺化指南

danny_2018發表於2022-06-06

  Kubernetes內部的網路與物理世界中的網路沒有太大區別。有了網路基礎知識,你就可以輕鬆實現容器Pod和服務之間的通訊。

  從使用交換機、路由器和乙太網電纜的物理網路轉移到使用軟體定義網路(SDN)和虛擬介面的虛擬網路需要一段輕微的學習曲線。當然,原則保持不變,但有不同的規範和最佳實踐。Kubernetes有自己的一套規則,如果你處理的是容器和雲,這有助於瞭解Kubernetes網路是如何工作的。

  Kubernetes網路模型有一些需要記住的一般規則:

  每個pod都有自己的IP地址:不需要在Pod之間建立連結,也不需要將容器埠對映到主機埠。

  不需要NAT:節點上的Pod應該能夠與沒有NAT的所有節點上的所有Pod通訊。

  代理獲得所有訪問許可權:節點(系統守護程式、Kubelet)上的代理可以與該節點中的所有Pod通訊。

  共享名稱空間:Pod中的容器共享網路名稱空間(IP和MAC地址),因此它們可以使用環回地址相互通訊。

  Kubernetes網路解決了什麼問題

  Kubernetes網路旨在確保Kubernetes中的不同實體型別可以通訊。Kubernetes基礎設施的佈局在設計上有很多分離。名稱空間、容器和Pod旨在保持元件彼此不同,因此高度結構化的通訊計劃非常重要。

  容器到容器的網路

  容器到容器的網路透過Pod網路名稱空間進行。網路名稱空間允許你擁有獨立的網路介面和路由表,這些介面和路由表與系統的其餘部分隔離並獨立執行。每個Pod都有自己的網路名稱空間,其中的容器共享相同的IP地址和埠。這些容器之間的所有通訊都是透過localhost進行的,因為它們都是同一名稱空間的一部分。(由圖中的綠線表示。)

   Pod到Pod的網路

  對於Kubernetes,每個節點都有一個指定的用於Pod的CIDR IP範圍。這確保每個Pod都能收到叢集中其他Pod可以看到的唯一IP地址。建立新Pod時,IP地址從不重疊。與容器到容器的網路不同,Pod到Pod的通訊使用真實的IP進行,無論你是將Pod部署在同一節點上還是叢集中的不同節點上。

  上圖顯示,為了使Pod相互通訊,流量必須在Pod網路名稱空間和根網路名稱空間之間流動。這是透過虛擬乙太網裝置或veth對(圖中veth0到Pod名稱空間1,veth1到Pod名稱空間2)連線Pod名稱空間和根名稱空間來實現的。虛擬網橋連線這些虛擬介面,允許通訊使用地址解析協議(ARP)在它們之間流動。

  當資料從Pod 1傳送到Pod 2時,事件流為:

  ——Pod 1流量透過eth0流向根網路名稱空間的虛擬介面veth0。

  ——然後,流量透過veth0到達連線到veth1的虛擬網橋。

  ——流量透過虛擬網橋到達veth1。

  ——最後,流量透過veth1到達Pod 2的eth0介面。

  Pod到服務的網路

  Pod很動態。它們可能需要根據需求擴大或縮小規模。在應用程式崩潰或節點故障的情況下,可以再次建立它們。這些事件會導致Pod的IP地址發生變化,這將給聯網帶來挑戰。

  Kubernetes透過使用Service功能來解決此問題,該功能執行以下操作:

  在前端分配靜態虛擬IP地址,以連線與服務關聯的任何後端吊艙。

  負載將定址到此虛擬IP的所有流量平衡到後端Pod集。

  跟蹤Pod的IP地址,這樣即使Pod IP地址更改,客戶端也不會有任何問題,因為它們只直接連線到服務本身的靜態虛擬IP地址。

  叢集內負載均衡有兩種方式:

  IPTABLES:在這種模式下,kube-proxy監視API伺服器中的更改。對於每個新服務,它都會安裝iptables規則,這些規則將流量捕獲到Service的clusterIP和埠,然後將流量重定向到服務的後端Pod。Pod是隨機選擇的。此模式可靠,系統開銷較低,因為Linux Netfilter處理流量時不需要在使用者空間和核心空間之間切換。

  IPV:IPV構建在Netfilter之上,並實現傳輸層負載均衡。IPVS使用Netfilter鉤子函式,使用雜湊表作為底層資料結構,並在核心空間中工作。這意味著IPVS模式下的kube代理比iptables模式下的kube代理具有更低的延遲、更高的吞吐量和更好的效能來重定向流量。

  上圖顯示了從Pod 1到Pod 3的包流透過Service到不同節點(以紅色標記)。前往虛擬網橋的包必須使用預設路由(eth0),因為網橋上執行的ARP無法理解該服務。之後,包必須透過iptables進行過濾,iptables使用kube代理在節點中定義的規則。因此,該圖顯示了當前的路徑。

  Internet到服務的網路

  到目前為止,已經討論瞭如何在叢集內路由流量。然而,Kubernetes網路還有另一面,那就是將應用程式暴露於外部網路。

  你可以透過兩種不同的方式將應用程式公開給外部網路。

  出口:當你想要將流量從Kubernetes服務路由到Internet時,請使用此選項。在這種情況下,iptables執行源NAT,因此流量似乎來自節點,而不是Pod。

  入口:這是從外部世界到服務的傳入流量。入口還允許並阻止使用連線規則與服務進行的特定通訊。通常,有兩種入口解決方案在不同的網路堆疊區域上執行:服務負載均衡器和入口控制器。

   發現服務

  Kubernetes發現服務有兩 種方式:

  環境變數:在Pod執行的節點上執行的kubelet服務負責以{SVCNAME}\u service\u HOST和{SVCNAME}\u service\u PORT的格式為每個活動服務設定環境變數。你必須在客戶端Pod出現之前建立服務。否則,這些客戶端Pod將不會填充其環境變數。

  DNS:DNS服務實現為Kubernetes服務,對映到一個或多個DNS伺服器Pod,這些Pod與任何其他Pod一樣進行排程。叢集中的Pod配置為使用DNS服務,DNS搜尋列表包括Pod自己的名稱空間和叢集的預設域。叢集感知DNS伺服器(如CoreDNS)監視Kubernetes API以獲取新服務,併為每個服務建立一組DNS記錄。如果在整個叢集中啟用了DNS,則所有Pod都可以根據其DNS名稱自動解析服務。Kubernetes DNS伺服器是訪問ExternalName服務的唯一方式。

   釋出服務的ServiceTypes:

  Kubernetes服務提供了一種訪問一組Pod的方法,通常透過使用標籤選擇器來定義。這可能是應用程式試圖訪問叢集中的其他應用程式,也可能允許你將叢集中執行的應用程式公開給外部世界。Kubernetes ServiceTypes允許你指定所需的服務型別。

  不同的ServiceTypes包括:

  ClusterIP:這是預設的ServiceType。它使服務只能從叢集內訪問,並允許叢集內的應用程式相互通訊。沒有外部訪問。

  LoadBalancer:此服務型別使用雲提供商的負載均衡器對外公開服務。來自外部負載均衡器的流量被定向到後端POD。雲提供商決定如何實現負載均衡。

  NodePort:這允許外部通訊透過在所有節點上開啟特定埠來訪問服務。然後,傳送到此埠的任何流量都會轉發到該服務。

  ExternalName:這種型別的服務使用ExternalName欄位的內容,透過返回CNAME記錄及其值,將服務對映到DNS名稱。未設定任何型別的代理。

   網路軟體

  只要你瞭解所使用的技術,Kubernetes內部的網路與物理世界中的網路沒有太大區別。好好學習,記住網路基礎知識,就可以輕鬆實現容器、Pod和服務之間的通訊。


來自 “ 開源雲中文社群 ”, 原文作者:開源雲中文社群;原文連結:https://opensource.com/article/22/6/kubernetes-networking-fundamentals,如有侵權,請聯絡管理員刪除。

相關文章