再談基於Traefik 的Kubernetes 入口網路體系
Hello folks,我是Luga,今天我們繼續來聊一下雲原生生態領域相關的技術- 雲原生網關Traefik ,本文將繼續聚焦在針對Kubernetes 入口網絡體系技術進行剖析,使得大家能夠了解為什麼常見的入口訪問以及如何更好地對利用其進行應用及市場開發。
一、關於Kubernetes 入口網路的一點簡單解析
眾所周知,Kubernetes 作為領先的容器編排平台,為建置和管理分散式應用提供了強大的功能。然而,在不同的業務場景下,對網路的需求也存在著差異。為了滿足這些差異化的需求,我們需要建立不同的Kubernetes Cluster 網路模式,以提供客製化的網路解決方案。
通常情況下,Kubernetes 中的叢集網路需要滿足以下幾點核心要求,具體如下所示:
- 服務的安全性和隔離:確保不同服務之間能夠相互隔離,並杜絕惡意存取。
- Pod 的連線、網路和IP:為Pod 提供網路連線和IP 位址分配,並支援動態分配和管理。
- 設定網路以從多個實體叢集部署叢集抽象:將多個實體節點虛擬化為一個統一的網絡,方便應用的部署和管理。
- 跨服務的多個實例的流量負載平衡:將流量均勻分配到多個服務實例,提高系統的負載能力和可靠性。
- 控制對服務的外部存取:限制對服務的存取權限,確保服務的安全性。
在公有和非雲端環境中使用Kubernetes 網路:支援在不同的雲端環境中部署和運行Kubernetes Cluster。
二、Pod 內訪問
針對一個有兩個節點的簡單Kubernetes Cluster,當Kubernetes 建立及執行一個Pod 時,它會為此Pod 建構一個獨立的網路命名空間,提供了網路層面的隔離環境。
在這個隔離環境中,Pod 可以像運作在獨立的伺服器上一樣,擁有獨立的網路棧,包括獨立的網路卡、IP 位址、路由表、iptables 規則等。這種隔離機制確保了不同Pod 之間的網路流量互不干擾,確保了網路通訊的安全性和可靠性。
除了網路隔離之外,Kubernetes 還為每個Pod 分配了一個唯一的IP 位址,使得Cluster 內的所有Pod 都可以透過IP 位址相互存取。這些IP 位址可以是從專門的子網路靜態分配的,也可以透過DHCP 等動態分配方式獲取,並由叢集自動管理。無論採用何種分配方式,Kubernetes 都會確保整個Cluster 內不會出現IP 衝突的情況,從而保證了通訊的順暢和可靠。
具體可參考如下圖所示:
Pod 網路的隔離性雖然保證了服務的安全性,但也為服務的存取帶來了一定的挑戰。由於Pod 內部的IP 位址在Cluster 外部是不可訪問,因此外部用戶端無法直接與該服務通訊。這對服務意味著什麼?服務在Pod 網路中的Pod 內運作。在該Pod 網路上指派的IP 位址(用於服務)在Pod 外部則無法存取。那麼如何存取該服務呢?
三、跨Nodes 訪問
在實際的業務場景中,一個服務通常由多個Pod 執行個體組成,這些Pod 可能分佈在叢集的不同節點上。例如,某個服務由兩個Pod 構成,分別運行在兩個不同的實體節點上。當外部用戶端需要存取服務時,Kubernetes 如何在這兩個Pod 之間進行負載平衡,確保請求能夠公平地分發到每個實例上呢?
Kubernetes 採用了Cluster IP(叢集IP)的抽象機制來解決這個問題。具體來說,Kubernetes 為每個服務分配一個Cluster IP,作為對外統一的入口點。當客戶端發起對該服務的請求時,只需要連線到這個Cluster IP 即可,而不需要關心後端特定的Pod 執行個體。
接下來,Kubernetes 會根據預先設定的負載平衡策略,將存取的請求流量分送到執行該服務的所有Pod 執行個體上。常用的負載平衡演算法包括基於權重的輪詢調度、最少連接調度等,用戶也可以根據自身需求自訂調度演算法。無論採用何種策略,Kubernetes 都能夠確保請求流量在各個Pod 實例之間合理分配,以實現高可用和負載平衡。
值得注意的是,這種負載平衡過程對客戶端來說是完全透明的。用戶端只需連接叢集IP 即可,而無需關心後端Pod 的實際分佈情況。這不僅簡化了客戶端的存取邏輯,也實現了服務的高度抽象化,將客戶端與底層基礎設施解耦。
Cluster IP (叢集IP)是Kubernetes 實現服務發現和負載平衡的核心機制,背後依賴kube-proxy 元件和一系列網路技術的支援。
透過kube-proxy、iptables/IPVS、網路外掛程式等多個元件的緊密配合,Kubernetes 為使用者提供了一個高度抽象且功能強大的服務網路解決方案,既能夠實現高效的流量負載均衡,又支援豐富的網絡策略控制,真正釋放了雲端原生應用的潛力,推動了微服務架構的廣泛應用。
四、Cluster 外部訪問
ClusterIP (叢集IP)提供了一種方便的方式來存取運行在Kubernetes Cluster 內的服務,但它預設只能在叢集內部訪問,對外部流量是不可見。這是出於安全性的考慮,避免服務被外部直接存取而遭受攻擊。
但在某些場景下,我們可能需要將服務暴露給叢集外部的客戶端存取。例如,某些面向公網的Web 服務,或是需要跨群集通訊的微服務等。為了滿足這種需求,Kubernetes 提供了NodePort 類型的服務。
NodePort 服務透過在每個節點上開放一個指定的連接埠,將叢集外部的流量引入到叢集內部,並透過ClusterIP 將這些流量轉送到後端的Pod 執行個體上。具體來說,當客戶端存取任一節點的NodePort 連接埠時,Nodes 會將該請求轉送到對應的ClusterIP ,再由ClusterIP 進行負載平衡,將流量分送到提供該服務的所有Pod 執行個體上。
這種模式相當於在叢集的邊緣設定了一個入口網關,為外部流量提供了一個合法的入口點。與直接暴露服務的ClusterIP 相比,此種方式提供了更好的安全性和靈活性。管理員可以精細化地控制哪些服務可以透過NodePort 對外開放,同時,也可以根據需要調整NodePort 的連接埠對映策略。
值得注意的是,NodePort 服務需要在每個節點上開放一個端口,這意味著該端口在叢集的所有節點上都不可重複使用。為了避免連接埠資源的浪費,Kubernetes 會自動分配一個可用的高位元連接埠(預設範圍為30000-32767)作為NodePort。當然,使用者也可以根據實際需求自訂NodePort 的連接埠號碼。
除了NodePort 之外,Kubernetes 還支援LoadBalancer 和Ingress 等更進階的服務暴露方式。LoadBalancer 服務透過雲端服務商提供的負載平衡器,為服務提供一個外部可存取的IP位址;而I ngress 則允許使用者自訂設定服務的外部存取規則,實現更精細的路由和流量管理。
這裡,我們撇開公有雲不談,只聊私有雲環境下的入口網路...
在私有雲中執行時,建立LoadBalancer 類型的服務需要一個可以設定負載平衡器的Kubernetes 控制器。在目前的解決方案中,一個這樣的實作便是MetalLb 。MetalLB 是裸機Kubernetes 叢集的負載平衡器實現,使用標準路由協定。其基於分配的IP 位址來路由叢集內的外部流量。從本質上來講,MetalLB 旨在透過提供與標準網路設備整合的網路LoadBalancer 實作來糾正這種不平衡,以便使得裸機叢集上的外部服務也盡可能地正常發揮作用。
MetalLB 實作了一個實驗性的FRR 模式,它使用FRR 容器作為處理BGP 會話的後端。它提供了原生BGP 實作所不具備的功能,例如將BGP 會話與BFD 會話配對,以及發布IPV6 位址。
MetalLB 是一種可用於裸機環境的Kubernetes 外部負載平衡器實作。它是Google開發的一個簡單的負載平衡器,具有為負載平衡器類型的Service 分配公共IP 位址(External IP)和向External IP 公開路由資訊等兩個功能。基於MetalLb 設計特性,其主要涉及以下2 種核心功能:
- 位址分配:當建立LoadBalancer Service 時,MetalLB 會為其指派IP 位址。這個IP 位址是從預先設定的IP 位址庫取得的。同樣,當Service 刪除後,已指派的IP 位址會重新回到位址庫。
- 對外廣播:分配了IP 位址之後,需要讓叢集外的網路知道這個位址的存在。MetalLB 使用了標準路由協定實作:ARP、NDP 或BGP。
廣播的方式有兩種,第一種是Layer 2 模式,使用ARP(ipv4)/NDP(ipv6) 協定;第二種是BPG。
我們來看看MetalLB 網路參考示意圖,如下所示:
基於上述參考拓撲結構圖,我們可以看到:當有外部流量請求存取時,路由器和ipvs 會根據設定的路由資訊調整連接目的地。因此,從某個角度而言,MetalLB 本身並非是一種負載平衡組件設施,而是基於負載平衡場景而設計。
那麼,其實,像Traefik 這樣的代理程式可以透過將其作為服務運行並定義此LoadBalancer 類型的服務來接收進入叢集的所有外部流量。這些代理可以使用L7 路由和安全性規則進行設定。這些規則的集合形成了Ingress 規則。
基於Ingress - 將服務置於可透過負載平衡器從外部存取的代理程式後面。可以在服務之前放置一層L7 代理,以應用L7 路由和策略。為此,需要一個入口控制器。Ingress Controller 是Kubernetes 叢集內的服務,配置為LoadBalancer 類型以接收外部流量。
Ingress Controller 使用定義的L7 路由規則和L7 政策將流量路由到服務。具體可參考如下示意圖所示:
其實,從本質上來講,在Ingress 運行Ingress Controller 和執行策略有幾個明顯的優勢,具體:
- Ingress 提供了一種可移轉的機制來在Kubernetes 叢集內執行策略。在叢集內實施的策略更容易跨雲移植。可以使用Kubernetes 服務擴充來水平擴充。
- 多個代理程式可以使用Kubernetes 服務進行水平擴展,L7 結構的彈性使其更易於操作和擴展。
- L7 策略可以與叢集內的服務一起託管,具有叢集原生狀態儲存。
- 讓L7 策略更接近服務可以簡化服務和API 的策略執行和故障排除。
在Kubernetes Cluster 中選擇Ingress 控制器是一個非常重要的決策,直接關係到Cluster 的網路效能、安全性和可擴充性。作為一款備受推崇的開源Ingress 控制器,Traefik憑藉其卓越的設計理念和強大的功能特性,成為了許多用戶的首選之一。
那麼,為什麼要選擇Traefik 作為首選的Kubernetes Ingress 呢?具體如下所示:
1.易於使用和維護
Traefik 的安裝和設定過程極為簡單流暢,使用YAML 或TOML 格式的聲明式設定文件,可讀性和可維護性極佳。同時,Traefik 也提供了基於Web UI 的直覺管理介面,使用者可以在其中即時查看和管理路由規則、中介軟體等配置項,大大降低了維運的複雜度。
2.自動化服務發現能力
Traefik 擁有強大的自動服務發現功能,可自動監測Kubernetes Cluster 中服務的變化,並基於這些變化動態產生相應的路由規則,無需人工介入。這種自動化能力不僅大大簡化了配置流程,還確保了路由規則的即時更新,確保了服務發現的準確性和及時性。此外,Traefik 支援多種服務發現機制,包括Kubernetes Ingress、Docker 等,可適應各種複雜的部署環境。
3.智慧動態負載平衡
Traefik 內建了高效能的負載平衡模組,可根據服務執行個體的即時狀態動態調整後端權重,實現真正意義上的智慧負載平衡。同時,Traefik 也支援會話親和性、熔斷機制、重試策略等高階功能,從而確保了服務的高可用性和可靠性,為應用提供了穩定、高效的運作環境。
4.豐富的中介軟體生態
Traefik 擁有數十種內建的中間件,涵蓋了身份認證、速率限制、熔斷、重試、快取等多個方面,用戶可以根據實際需求,透過簡單的配置即可啟用這些中間件,快速建立出功能強大的邊緣服務。除了內建中間件之外,Traefik還提供了良好的擴展性,支援用戶自行開發和整合客製化的中間件,滿足各種複雜場景的需求。
5.卓越的可擴展性
作為一款生產等級的Ingress 控制器,Traefik 天生具備出色的可擴充性。它支援多種部署模式,包括單一實例、叢集等,在叢集模式下,多個Traefik 實例可以無縫協作,實現高可用和水平擴展。同時,Traefik 也支援多種後端伺服器類型,如HTTP、gRPC 等,能夠滿足各種複雜的應用場景需求。
6.全方位的安全保障
安全性是Traefik 設計時的重中之重,支援HTTPS/TLS、基於角色的存取控制(RBAC )等多種安全特性。Traefik 可以透過Let's Encrypt 等方式自動取得和更新SSL/TLS 憑證,確保資料傳輸的端對端加密。同時,它還提供了完善的身份認證機制,如基本認證、JWT 等,有效保護服務免受未經授權的存取。