01
網(wǎng)關(guān)基本概念
在微服務(wù)架構(gòu)里,服務(wù)的粒度被進一步細分,各個業(yè)務(wù)服務(wù)可以被獨立的設(shè)計、開發(fā)、測試、部署和管理。這時各個獨立部署單元可以用不同的開發(fā)測試團隊維護,可以使用不同的編程語言和技術(shù)平臺進行設(shè)計,這就要求必須使用一種語言和平臺無關(guān)的服務(wù)協(xié)議作為各個單元間的通訊方式。
網(wǎng)關(guān)的角色是作為一個 API 架構(gòu),用來保護、增強和控制對于 API 服務(wù)的訪問。API 網(wǎng)關(guān)是一個處于應(yīng)用程序或服務(wù)(提供 REST API 接口服務(wù))之前的系統(tǒng),用來管理授權(quán)、訪問控制和流量限制等,這樣 REST API 接口服務(wù)就被 API 網(wǎng)關(guān)保護起來,對所有的調(diào)用者透明。因此隱藏在 API 網(wǎng)關(guān)后面的業(yè)務(wù)系統(tǒng)就可以專注于創(chuàng)建和管理服務(wù),而不用去處理這些策略性的基礎(chǔ)設(shè)施。
API 網(wǎng)關(guān)是位于客戶端和后端服務(wù)之間的 API 管理工具,一種將客戶端接口與后端實現(xiàn)分離的方式,在微服務(wù)中得到了廣泛的應(yīng)用。當(dāng)客戶端發(fā)出請求時,API 網(wǎng)關(guān)會將其分解為多個請求,然后將它們路由到正確的位置,生成響應(yīng),并跟蹤所有內(nèi)容。
API 網(wǎng)關(guān)可看做微服務(wù)架構(gòu)體系中的一類型特殊服務(wù),它是所有微服務(wù)的入口,它的職責(zé)是執(zhí)行路由請求、協(xié)議轉(zhuǎn)換、聚合數(shù)據(jù)、認證、限流、熔斷等。大多數(shù)企業(yè) API 都是通過 API 網(wǎng)關(guān)部署的。API 網(wǎng)關(guān)通常會處理跨 API 服務(wù)系統(tǒng)的常見任務(wù),例如用戶身份驗證、速率限制和統(tǒng)計信息。
對于具體的后端業(yè)務(wù)應(yīng)用或者是服務(wù)和業(yè)務(wù)有一定關(guān)聯(lián)性的策略網(wǎng)關(guān)就是業(yè)務(wù)網(wǎng)關(guān)。 業(yè)務(wù)網(wǎng)關(guān)針對具體的業(yè)務(wù)需要提供特定的流控策略、緩存策略、鑒權(quán)認證策略等等。
與業(yè)務(wù)網(wǎng)關(guān)相反,定義全局性的、跟具體的后端業(yè)務(wù)應(yīng)用和服務(wù)完全無關(guān)的策略網(wǎng)關(guān)是流量網(wǎng)關(guān)。流量網(wǎng)關(guān)通常只專注于全局的Api管理策略,比如全局流量監(jiān)控、日志記錄、全局限流、黑白名單控制、接入請求到業(yè)務(wù)系統(tǒng)的負載均衡等,有點類似防火墻。
需要說明的是,業(yè)務(wù)網(wǎng)關(guān)一般部署在流量網(wǎng)關(guān)之后、業(yè)務(wù)系統(tǒng)之前,比流量網(wǎng)關(guān)更靠近業(yè)務(wù)系統(tǒng)。通常API網(wǎng)指的是業(yè)務(wù)網(wǎng)關(guān)。有時候也會模糊流量網(wǎng)關(guān)和業(yè)務(wù)網(wǎng)關(guān),讓一個網(wǎng)關(guān)承擔(dān)所有的工作,所以這兩者之間并沒有嚴格的界線。
02
云原生網(wǎng)關(guān)作用和規(guī)范
隨著容器化技術(shù)和云原生應(yīng)用的普及,面臨Kubernetes 集群內(nèi)的網(wǎng)絡(luò)環(huán)境與外部隔離, Kubernetes 集群外部的客戶端無法直接訪問到集群內(nèi)部的服務(wù)的問題,需要解決不同網(wǎng)絡(luò)域如何連接的問題。解決跨網(wǎng)絡(luò)域訪問的常規(guī)做法是為目標(biāo)集群引入一個入口點,所有外部請求目標(biāo)集群的流量必須訪問這個入口點,然后由入口點將外部請求轉(zhuǎn)發(fā)至目標(biāo)節(jié)點。
同樣,Kubernetes 社區(qū)也是通過增設(shè)入口點的方案來解決集群內(nèi)部服務(wù)如何對外暴露的問題。Kubernetes 一貫的作風(fēng)是通過定義標(biāo)準來解決同一類問題,在解決集群對外流量管理的問題也不例外。Kubernetes 對集群入口點進行了進一步的統(tǒng)一抽象,提出了 3 種解決方案:NodePort、LoadBalancer 和 Ingress。下圖是這三種方案的對比:
通過對比可以發(fā)現(xiàn),NodePort 和 LoadBalancer 主要工作在四層流量上,只能用于暴露集群中一個服務(wù)。當(dāng)集群中對外暴露的服務(wù)數(shù)量增多時,NodePort 方案最終會因端口耗盡而無法暴露更多的服務(wù),而 LoadBalancer 方案則會引入同等數(shù)量的 SLB,在增加成本的同時也給運維增加負擔(dān)。定位在七層流量上的 Ingress 方案可以通過定義基于虛擬主機域和路徑的路由規(guī)則來完成對集群中服務(wù)的代理,Ingress 與后端服務(wù)是一對多的關(guān)系,有效的降低了機器成本。
此外,因為外部訪問集群中服務(wù)的所有入口流量都先經(jīng)過共享的 Ingress Provider 節(jié)點,所以集群管理者可以在 Ingress Provider 中額外實施訪問控制策略來保證集群中服務(wù)的安全性和穩(wěn)定性,并且可以通過采集監(jiān)控指標(biāo)、記錄訪問日志以及開啟鏈路追蹤來增強可觀測建設(shè)。因此目前 Ingress 方案是主流的選擇。
03
Ingress規(guī)范
簡單講,Ingress是 Kubernetes 處理邊緣入口流量的一種方式。由于 Kubernetes 集群內(nèi)的服務(wù)都是虛擬網(wǎng)絡(luò),外部流量訪問集群內(nèi)部至少需要一個公網(wǎng)ip和端口映射。Ingress 是 Kubernetes 應(yīng)對集群管理外部訪問流量的場景抽象出來一個資源對象,用來描述集群外部如何訪問集群內(nèi)部服務(wù)的方式。
上文所述Kubernetes 有多種暴露邊緣接口的方式,相比而言ingress 通過暴露有限的公網(wǎng) ip,使用反向代理的方式,無疑是一種更加有競爭力的方式。說到反向代理,我們也可以直接搭建一個 Nginx 來做反向代理,但是要在 Nginx 里同步 Kubernetes 中隨時可變的服務(wù)狀態(tài),明顯增加了維護難度。好在 Kubernetes 官方提供并維護了一個 nginx ingress controller,幫助我們解決了反向代理的事情,有了這個 nginx ingress controller,可以幫助我們代理所有想要訪問 Kubernetes 的外部流量,并且將流量正確的指向后端服務(wù)。通過 Ingress 資源來配置不同的轉(zhuǎn)發(fā)規(guī)則,從而達到根據(jù)不同的規(guī)則設(shè)置外部訪問集群內(nèi)不同的 Service 所對應(yīng)的后端 Pod。
Ingress Controller是真實存在的工作負載節(jié)點,是真正意義上 Ingress 規(guī)則的實現(xiàn)者與執(zhí)行者。Kubernetes 提出 Ingress 的規(guī)范,將 Ingress 具體實現(xiàn)方式交給各種 Provider 以及云提供商,有效保證了 Ingress 不會被具體的 Provider 或者云廠商綁定,符合 Kubernetes 一直秉承的開放、標(biāo)準的思想。
在云原生技術(shù)浪潮下,Ingress Provider 產(chǎn)品種類如雨后春筍般涌現(xiàn),其中用戶知名度最高當(dāng)屬 Kubernetes Nginx Ingress。Nginx Ingress Controller 是由 Kubernetes 官方維護的,內(nèi)部由 Controller 和數(shù)據(jù)面 Nginx 組成。Nginx Ingress Controller 由用戶部署在 Kubernetes 集群中,通過訪問集群的 API Server 來實時監(jiān)聽用戶應(yīng)用到集群中的 Ingress 資源,經(jīng) Controller 解析并轉(zhuǎn)化為 Nginx 配置文件(nginx.conf),然后通過 reload 數(shù)據(jù)面 Nginx 的方式使得配置生效。當(dāng)外部請求訪問集群入口點 Nginx Ingress Controller 時,匹配 Nginx Ingress 轉(zhuǎn)發(fā)規(guī)則的流量轉(zhuǎn)發(fā)到后端 Service 所對應(yīng)的 Pod,由 Pod 處理外部請求。
下圖是一個典型的Ingress配置示例,可以基于同一域名提供細分的服務(wù)。
通過基于名稱的虛擬主機支持,可以將針對多個服務(wù)的 HTTP 流量路由到同一 IP 地址上。
04
Gateway API規(guī)范
在 Kubernetes 集群邊緣對外提供網(wǎng)絡(luò)服務(wù)的時候,通常需要借助 Ingress 對象,這個對象提供了暴露 Service 所必須的核心要素,例如基于主機名的路由、對 URL 路徑的適配以及 TLS 配置等。但是在實際開放服務(wù)的時候,往往會有更多的具體需求,這時 Ingress 對象所提供的核心功能就有些力不從心了。
各種 Ingress 控制器往往會使用 metadata.annotations 中的特定注解,來完成對 Ingress 特定行為的控制,完成各自的個性化功能,例如認證、路徑變更、黑白名單等,這就讓 Ingress 對象變成了一個奇怪的東西:結(jié)構(gòu)化的核心結(jié)構(gòu),和非結(jié)構(gòu)化的標(biāo)注結(jié)合起來形成各種 Ingress 方言。并且后期還出現(xiàn)了 各種CRD 配置,客觀上也讓 Ingress 世界更為分裂,這給 Ingress 功能的集中管理造成了一個較大的困擾。另外 Ingress 中可以隨意定制主機名、路徑以及后端服務(wù),也給共享集群的用戶造成了一定的安全隱患。
K8s 官方SIG-Network工作組基于實際現(xiàn)狀和需求,提出了全新的 Gateway API 來作為 Ingress 的繼任者。總體來說,相對于 Ingress,Gateway API 有幾個顯著特點:職責(zé)分離,運維、開發(fā)等不同的角色都能夠在適合的邊界內(nèi)完成工作;擴展核心能力,并使用更結(jié)構(gòu)化的方式進行表達;易于擴展,Gateway API 為各種不同實現(xiàn)的控制器提供了一致的擴展方法。
Gateway API 包含了三層概念:GatewayClass、Gateway 和 Route,其中的 Route 實際是包含了 HTTPRoute、TCPRoute、TLSRoute 和 UDPRoute 在內(nèi)的一組對象。
GatewayClass是一個集群范圍內(nèi)的資源,由云基礎(chǔ)設(shè)施中的 Gateway API 控制器提供,其職責(zé)和原有的 Ingress Controller 類似。
Gateway 對象是命名空間范圍對象,可以視作是 GatewayClass 的一個實例,它通常是由具體機群的運維人員進行維護的,在 Gateway 對象中可以指定該對象負責(zé)的主機名稱范圍,用標(biāo)簽選擇器選擇對應(yīng)的 Service,甚至還可以指定該 Gateway 生效的命名空間。這樣就給具體應(yīng)用的對外開放劃定了一個范圍,防止應(yīng)用隨意占用主機名,并完善命名空間的隔離能力。
Route 對象除了像原有的 Ingress 對象一樣提供 HTTP 服務(wù)的開放能力之外,還提供了 TCP、TLS 和 UDP 的對應(yīng)資源,從而緩解了 Nginx、HAProxy Ingress 控制器使用 Configmap 配置 TCP/UDP 的窘境。HTTPRoute 除了提供基礎(chǔ)的 Ingress 對象能力之外,還提供了一些擴展的功能,例如對流量進行復(fù)制、分流;更重要的是其中還提供了 Filter 能力,這是一個擴展點,除了自帶的核心處理能力之外,底層設(shè)施還可以在這里接入自己的 CRD,對流量進行處理,從而為流量處理能力的擴展提供了一個統(tǒng)一入口。
值得注意的是,當(dāng)前Gateway API規(guī)范還在快速發(fā)展和完善中。
05
云原生網(wǎng)關(guān)選型
標(biāo)準Nginx ingress controller 幫助維護了 Kubernetes 集群與 Nginx 的狀態(tài)同步,并且提供了基本的反向代理能力,為什么還要自己造輪子呢? 隨著云原生技術(shù)持續(xù)演進,云原生應(yīng)用微服務(wù)化不斷深入,Nginx Ingress 在面對復(fù)雜路由規(guī)則配置、支持多種應(yīng)用層協(xié)議(Dubbo 和 QUIC 等)、服務(wù)訪問的安全性以及流量的可觀測性等問題上略顯疲憊。
在使用 Kubernetes 原生 ingress controller 之后,以下幾點比較突出的問題:
1、reload 問題:Kubernetes 原生 ingress 在設(shè)計上,將 YAML 配置文件交由 ingress controller 處理,轉(zhuǎn)換為 nginx.conf,再觸發(fā) reload nginx.conf 使配置生效。日常運維免不了修改 ingress 配置,每一次配置生效,都會觸發(fā)一次 reload,這是不能接受的,尤其在邊緣流量采用?連接時,更容易導(dǎo)致事故。
2、在 annotation 中寫腳本、填充參數(shù):原生 ingress controller 支持在 yaml 中 annotation 定義腳本片段,感覺是為了支持高級功能而實現(xiàn)的一個臨時方案,不好管理。大量的 annotation 腳本給配置人員帶來困擾。
3、缺少對有狀態(tài)負載均衡的支持:高級的負載均衡策略并沒有支持,比如 session persistent 等。
4、動態(tài)調(diào)整權(quán)重:業(yè)務(wù)服務(wù)常常需要按照百分比控制流量,這在 Kubernetes 中卻變成了麻煩。雖然 Kubernetes 在1.8之后支持了 ipvs,無論是 kube-proxy 的啟動參數(shù),還是 kube-route 的 annotation,在使用上都不容易上手。
5、擴展能力薄弱:雖然 ingress 設(shè)計之初為了解決邊緣流量,但人們對于邊緣流量的需求一點都不比內(nèi)部流量少。業(yè)務(wù)級灰度控制、熔斷、流量控制、鑒權(quán)、流量管控等需求在 ingress 上實現(xiàn)的呼聲更高。然而原生 ingress 提供的擴展此時卻捉襟?肘。
業(yè)務(wù)的需求不容忽視,我們對 ingress controller 有更多的期待。好在業(yè)界有多款云原生網(wǎng)關(guān)供選擇,
云原生網(wǎng)關(guān)選型需要綜合考慮以下方面:是否開源,以及開源版本的功能和商業(yè)版區(qū)別,以及是否有特定公司主導(dǎo)還是社區(qū)整體主導(dǎo)。支持的服務(wù)發(fā)現(xiàn)規(guī)范也是重要的考慮因素。底層代理的實現(xiàn)方式是重要考慮因素,當(dāng)前主要有Nginx內(nèi)核,Envoy內(nèi)核和Go語言自主開發(fā)實現(xiàn)幾種方式,內(nèi)核實現(xiàn)方式直接影響網(wǎng)關(guān)性能和可擴展性。另外,流量治理的功能豐富性和命名空間隔離能力也是考慮的重要因素。
下圖是幾種當(dāng)前主流網(wǎng)關(guān)的各項指標(biāo)對比。
需要說明的是Istio內(nèi)置的Istio網(wǎng)關(guān),對于策略控制、流量管理和流量監(jiān)控可以直接通過 Istio 網(wǎng)關(guān)來完成,這樣做的好處是通過 Istio 的控制平面來直接管理網(wǎng)關(guān),而不需要再借助其他工具。
但是對于 API 生命周期管理、復(fù)雜的計費、協(xié)議轉(zhuǎn)換和認證等功能,成熟的 API 網(wǎng)關(guān)如Kong和Apisix可能更適合。Apache APISIX 支持熱配置,隨時可以定義和修改路由,而且不會觸發(fā) nginx reload。在Apache APISIX中,可以通過插件代碼編寫邏輯,暴露出簡單的配置接口,方便配置的維護,避免腳本對配置人員的干擾。
基于 Apache APISIX 可以擴展出符合要求的高級負載均衡需求,Apache APISIX 不僅原生支持了 session persistent 等負載均衡,同時還預(yù)留 balancer 階段的擴展能力。Apache APISIX 內(nèi)部抽象出 route、service、consumer、upstream、plugin 等主要對象,對調(diào)整路由權(quán)重這類操作天然支持,只需簡單的修改upstream 下的 node weight 即可。APISIX 在擴展能力上提供了插件的支持,除了官方提供的插件之外,可以自定義開發(fā)滿足自身業(yè)務(wù)特性的插件。
由于Envoy的復(fù)雜性,雖然該項目在世界各地的大型工程組織中取得了巨大的成功,但在較小和較簡單的用例中,它只被輕度采用,在這些用例中,Nginx 和 HAProxy 仍占主導(dǎo)地位。
新的Envoy Gateway 項目的誕生為了進一步統(tǒng)一基于Envoy的云原生網(wǎng)關(guān):提供一個簡化的部署模型和API 層,旨在滿足輕量級使用。將現(xiàn)有的 CNCF API 網(wǎng)關(guān)項目(Contour 和 Emissary)合并為一個共同的核,基于Gateway API規(guī)范可以提供更好的用戶體驗,同時仍然允許供應(yīng)商在 Envoy Proxy 和 Envoy Gateway 的基礎(chǔ)上建立增值解決方案。
匯聚在單一的以 Envoy 為核心的 API 網(wǎng)關(guān)周圍,將會減少圍繞安全、控制平面技術(shù)細節(jié)和其他共同關(guān)切的重復(fù)工作。允許供應(yīng)商專注于在 Envoy Proxy 和 Envoy Gateway 的基礎(chǔ)上以擴展、管理平面 UI 等形式分層提供增值功能。
讓更多的用戶享受到 Envoy 的好處,無論組織的大小。更多的用戶為更多的潛在客戶提供了良性循環(huán),為 Envoy 的核心項目提供了更多的支持,也為所有人提供了更好的整體體驗。
整體看,當(dāng)前基于Nginx內(nèi)核的網(wǎng)關(guān)如Kong和Apisix由于功能豐富度和成熟度水平較高,可以較好的滿足云原生網(wǎng)關(guān)的功能需求。長期看,基于Envoy的網(wǎng)關(guān)由于技術(shù)的新穎性,在動態(tài)配置管理,可擴展性,以及安全和可觀測性方面的先進性,是未來的技術(shù)趨勢。
工程師是 API 和 API 網(wǎng)關(guān)的使用者和開發(fā)者,工程師關(guān)注和參與的 API 網(wǎng)關(guān)項目,一定程度代表了技術(shù)的趨勢。下圖從 GitHub 代碼貢獻者的維度,選取了 4 個開源網(wǎng)關(guān)產(chǎn)品進行對比:Apache APISIX、Kong、EnvoyGateway和 Istio,可做參考。
除了貢獻者總數(shù)外,貢獻者的月度活躍數(shù)也是重要參考指標(biāo)。下圖展示了以上四個開源 網(wǎng)關(guān)的月度活躍的開發(fā)者數(shù)量??梢钥吹礁骶W(wǎng)關(guān)產(chǎn)品的開發(fā)活躍趨勢。
參考文獻
1.從概念到實踐上手 Apache APISIX Ingress
2.Apache APISIX
3.Introduction - Kubernetes Gateway API
4.Ingress | Kubernetes
5.GitHub Contributor Over Time (git-contributor.com)
6.envoyproxy/gateway
-
網(wǎng)關(guān)
+關(guān)注
關(guān)注
9文章
4568瀏覽量
51335 -
編程語言
+關(guān)注
關(guān)注
10文章
1949瀏覽量
34867 -
微服務(wù)
+關(guān)注
關(guān)注
0文章
141瀏覽量
7375 -
云原生
+關(guān)注
關(guān)注
0文章
251瀏覽量
7962
發(fā)布評論請先 登錄
相關(guān)推薦
評論