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