本文來自微信公眾號“開源云中文社區(qū)”。
在幾乎每次關(guān)于入口控制器和服務(wù)網(wǎng)格的對話中,我們都會聽到一些不同的問題,“這個工具與API網(wǎng)關(guān)有什么不同?”或“我需要Kubernetes中的API網(wǎng)關(guān)和入口控制器(或服務(wù)網(wǎng)格)嗎?”
這種混淆是可以理解的,原因有兩個:
——入口控制器和服務(wù)網(wǎng)格可以滿足許多API網(wǎng)關(guān)用例。
——一些供應(yīng)商將其API網(wǎng)關(guān)工具定位為使用入口控制器或服務(wù)網(wǎng)格的替代方案,或者將多種功能整合到一個工具中。
在這里,我們將討論這些工具的區(qū)別,以及用于Kubernetes特定API網(wǎng)關(guān)用例的工具。
定義
在其核心,API網(wǎng)關(guān)、入口控制器和服務(wù)網(wǎng)格都是一種代理類型,旨在將流量引入你的環(huán)境及其周圍。
什么是API網(wǎng)關(guān)?
API網(wǎng)關(guān)將API請求從客戶端路由到適當(dāng)?shù)姆?wù)。但對這個簡單定義的一個很大誤解是,API網(wǎng)關(guān)是一種獨(dú)特的技術(shù)。事實(shí)并非如此。相反,“API網(wǎng)關(guān)”描述了一組可以通過不同類型的代理實(shí)現(xiàn)的用例,最常見的是ADC或負(fù)載均衡器和反向代理,越來越多的是入口控制器或服務(wù)網(wǎng)格。事實(shí)上,我們經(jīng)常看到用戶,從初創(chuàng)企業(yè)到企業(yè),將開箱即用的NGINX部署為具有反向代理、web服務(wù)器或負(fù)載均衡器的API網(wǎng)關(guān),并定制配置以滿足其用例需求。
對于工具作為API網(wǎng)關(guān)的“必備”功能,業(yè)界并沒有太多共識。我們通??吹娇蛻粜枰韵履芰Γò从美纸M):
彈性用例:
——A/B測試、金絲雀部署和藍(lán)綠部署
——協(xié)議轉(zhuǎn)換(例如JSON和XML之間)
——速率限制
——服務(wù)發(fā)現(xiàn)
流量管理用例:
——基于方法的路由和匹配
——請求/響應(yīng)頭和主體操作
——第7層的請求路由
——重試和保持
安全使用案例:
——API架構(gòu)強(qiáng)制
——客戶端身份驗(yàn)證和授權(quán)
——自定義響應(yīng)
——細(xì)粒度訪問控制
——TLS終止
幾乎所有這些用例都在Kubernetes中常用。協(xié)議轉(zhuǎn)換、請求/響應(yīng)頭和主體操作不太常見,因?yàn)樗鼈兺ǔEc不太適合Kubernetes和微服務(wù)環(huán)境的遺留API綁定。它們也傾向于指示不太可能在Kubernetes中運(yùn)行的單體應(yīng)用程序。
什么是入口控制器?
入口控制器是一個專門的第4層和第7層代理,它將流量送入Kubernetes、服務(wù),然后再次退出(稱為入口-出口或南北流量)。除了流量管理之外,入口控制器還可以用于可見性和故障排除、安全性和身份,以及除最高級API網(wǎng)關(guān)用例之外的所有其他用途。
什么是服務(wù)網(wǎng)格?
服務(wù)網(wǎng)格處理Kubernetes服務(wù)之間的流量(稱為服務(wù)到服務(wù)或東西向流量)。它通常用于實(shí)現(xiàn)端到端加密(E2EE),并將TLS應(yīng)用于所有流量。服務(wù)網(wǎng)格可以用作與應(yīng)用程序非常接近的分布式(輕量級)API網(wǎng)關(guān),通過服務(wù)網(wǎng)格sidecars可以在數(shù)據(jù)平面級別實(shí)現(xiàn)。
注意:選擇服務(wù)網(wǎng)格是一個值得考慮的過程。
在Kubernetes環(huán)境中使用Kubernetes原生工具
如何決定哪種工具適合你呢?我們將使其變得簡單:如果需要Kubernetes內(nèi)部的API網(wǎng)關(guān)功能,通常最好選擇一個可以使用本地Kubernete配置工具(如YAML)進(jìn)行配置的工具。通常,這是一個入口控制器或服務(wù)網(wǎng)格。但我們聽到你說:“我的API網(wǎng)關(guān)工具比我的入口控制器(或服務(wù)網(wǎng)格)有更多的功能。我錯了嗎?”不!更多的功能并不等于更好的工具,特別是在Kubernetes中,工具的復(fù)雜性可能是一個殺手。
注意:“Kubernetes native”(與Knative不同)是指為Kubernete設(shè)計(jì)和構(gòu)建的工具。通常,它們使用Kubernetes CLI,可以使用Helm安裝并與Kubernete功能集成。
大多數(shù)Kubernetes用戶更喜歡可以以Kubernete原生方式配置的工具,因?yàn)檫@避免了對開發(fā)或GitOps體驗(yàn)的更改。YAML友好的工具提供三大優(yōu)勢:
——YAML是Kubernetes團(tuán)隊(duì)熟悉的語言,因此如果使用現(xiàn)有的Kubernete工具實(shí)現(xiàn)API網(wǎng)關(guān)功能,那么學(xué)習(xí)曲線很低,甚至不存在。這有助于團(tuán)隊(duì)在現(xiàn)有技能范圍內(nèi)工作,而無需學(xué)習(xí)如何配置他們可能偶爾使用的新工具。
——可以以與其他Kubernetes工具相同的方式自動化YAML友好的工具。任何完全適合工作流程的東西都會受到團(tuán)隊(duì)的歡迎,從而增加他們使用它的可能性。
——可以通過使用Kubernetes原生工具來收縮Kubernettes流量管理工具堆棧。每一次額外的跳躍都很重要,沒有理由增加不必要的延遲或單點(diǎn)故障。當(dāng)然,減少Kubernetes中部署的技術(shù)數(shù)量也有利于預(yù)算和總體安全。
南北API網(wǎng)關(guān)用例:使用入口控制器
入口控制器有可能啟用許多API網(wǎng)關(guān)用例。除了定義中概述的那些之外,我們發(fā)現(xiàn)組織最重視能夠?qū)崿F(xiàn)以下功能的入口控制器:
——卸載身份驗(yàn)證和授權(quán)
——基于授權(quán)的路由
——第7層路由和匹配(HTTP、HTTP/S、標(biāo)頭、cookie、方法)
——協(xié)議兼容性(HTTP、HTTP/2、WebSocket、gRPC)
——速率限制
示例場景:方法級路由
你希望使用入口控制器實(shí)現(xiàn)方法級匹配和路由,以拒絕API請求中的POST方法。
一些攻擊者通過發(fā)送不符合API定義的請求類型來查找API中的漏洞,例如,向定義為僅接受GET請求的API發(fā)送POST請求。Web應(yīng)用防火墻(WAF)無法檢測到此類攻擊。它們只檢查請求字符串和主體是否受到攻擊,因此最好在入口層使用API網(wǎng)關(guān)來阻止壞請求。
例如,假設(shè)新的API/coffee//brand剛剛添加到集群中。第一步是使用入口控制器公開API,只需將API添加到upstream字段即可。
apiVersion:k8s.nginx.org/v1
kind:VirtualServer
metadata:
name:cafe
spec:
host:cafe.example.com
tls:
secret:cafe-secret
upstreams:
-name:tea
service:tea-svc
port:80
-name:coffee
service:coffee-svc
port:80
要啟用方法級匹配,請?jiān)趓outes字段中添加/coffee//brand路徑,并添加兩個條件,使用$request_method變量區(qū)分GET和POST請求。使用HTTP GET方法的任何流量都會自動傳遞給coffee服務(wù)。使用POST方法的流量被引導(dǎo)到一個錯誤頁面,并顯示消息“你被拒絕了!”,就這樣,你已經(jīng)保護(hù)了新的API免受不需要的POST流量的影響。
routes:
-path:/coffee//brand
matches:
-conditions:
-variable:$request_method
value:POST
action:
return:
code:403
type:text/plain
body:"You are rejected!"
-conditions:
-variable:$request_method
value:GET
action:
pass:coffee
-path:/tea
action:
pass:tea
東西API網(wǎng)關(guān)用例:使用服務(wù)網(wǎng)格
對于大多數(shù)API網(wǎng)關(guān)用例,服務(wù)網(wǎng)格是不需要的,甚至在最初是沒有幫助的,因?yàn)榭赡芟M瓿傻拇蟛糠止ぷ鞫伎梢远覒?yīng)該發(fā)生在入口層。但隨著架構(gòu)的復(fù)雜性增加,你更有可能從使用服務(wù)網(wǎng)格中獲得價(jià)值。我們發(fā)現(xiàn)最有益的用例與E2EE和流量分割有關(guān),例如A/B測試、金絲雀部署和藍(lán)綠部署。
示例場景:金絲雀部署
你希望在基于HTTP/S標(biāo)準(zhǔn)的有條件路由的服務(wù)之間建立金絲雀部署。
其優(yōu)點(diǎn)是,可以逐步推出API更改(如新功能或版本),而不會影響大部分生產(chǎn)流量。
目前,入口控制器在NGINX服務(wù)網(wǎng)格管理的兩個服務(wù)之間路由流量:Coffee.frontdoor.svc和Tea.frontdoor.sevc。這些服務(wù)從入口控制器接收流量,并將其路由到適當(dāng)?shù)膽?yīng)用程序功能,包括Tea.ream1.svc。你決定重構(gòu)Tea.ream2.svc,調(diào)用新版本Tea.ream2.svc。你希望測試人員提供有關(guān)新功能的反饋,因此根據(jù)測試人員的獨(dú)特會話cookie配置金絲雀流量分割,確保普通用戶只體驗(yàn)Tea.ream1.svc。
使用服務(wù)網(wǎng)格,首先在Tea.frontdoor.svc提供的所有服務(wù)之間創(chuàng)建流量分割,包括Tea.ream1.svc和Tea.ream2.svc。要啟用條件路由,請創(chuàng)建HTTPRouteGroup資源(名為tea-hrg)并將其與流量分割相關(guān)聯(lián),結(jié)果是,只有來自測試版用戶的請求(會話cookie設(shè)置為version=beta的請求)才會從Tea.frontdoor.svc路由到Tea.ream2.svc。普通用戶仍然只能體驗(yàn)Tea.fromtdoor.svc之后的版本1服務(wù)。
apiVersion:split.smi-spec.io/v1alpha3
kind:TrafficSplit
metadata:
name:tea-svc
spec:
service:tea.1
backends:
-service:tea.1
weight:0
-service:tea.2
weight:100
matches:
-kind:HTTPRouteGroup
name:tea-hrg
apiVersion:specs.smi-spec.io/v1alpha3
kind:HTTPRouteGroup
metadata:
name:tea-hrg
namespace:default
spec:
matches:
-name:beta-session-cookie
headers:
-cookie:"version=beta"
這個示例以0-100分割開始金絲雀部署,這意味著所有測試人員都會體驗(yàn)Tea.ream2.svc,但當(dāng)然,你可以從符合測試策略的任何比率開始。測試完成后,可以使用一個簡單的金絲雀部署(沒有cookie路由)來測試Tea.ream2.svc的彈性。
何時(以及如何)為Kubernetes應(yīng)用程序使用API網(wǎng)關(guān)工具
盡管Kubernetes的大多數(shù)API網(wǎng)關(guān)用例可以(也應(yīng)該)通過入口控制器或服務(wù)網(wǎng)格來解決,但在某些特殊情況下,API網(wǎng)關(guān)工具是合適的。
業(yè)務(wù)要求
在Kubernetes內(nèi)部同時使用入口控制器和API網(wǎng)關(guān)可以為組織實(shí)現(xiàn)業(yè)務(wù)需求提供靈活性。一些場景包括:
——API網(wǎng)關(guān)團(tuán)隊(duì)不熟悉Kubernetes,也不使用YAML。例如,如果他們對NGINX配置感到滿意,那么如果他們將NGINX部署為Kubernetes中的API網(wǎng)關(guān),則可以減少摩擦并減少學(xué)習(xí)曲線。
——平臺運(yùn)維團(tuán)隊(duì)傾向于將入口控制器解決方案僅用于應(yīng)用流量管理。
——有一個API網(wǎng)關(guān)用例,它只適用于集群中的一個服務(wù)。你可以部署API網(wǎng)關(guān),僅在需要時應(yīng)用策略,而不是使用入口控制器將策略應(yīng)用于所有的南北通信。
將API遷移到Kubernetes環(huán)境
當(dāng)將現(xiàn)有API遷移到Kubernetes環(huán)境中時,你可以將這些API發(fā)布到部署在Kubernete外部的API網(wǎng)關(guān)工具中。在這種情況下,API流量通常通過外部負(fù)載均衡器(用于集群之間的負(fù)載均衡),然后路由到配置為充當(dāng)API網(wǎng)關(guān)的負(fù)載均衡器,最后路由到Kubernetes集群內(nèi)的入口控制器或網(wǎng)關(guān)API模塊。
API網(wǎng)關(guān)用例的網(wǎng)關(guān)API的未來
如果沒有對Kubernetes網(wǎng)關(guān)API(與API網(wǎng)關(guān)不同)的簡要討論,本文將是不完整的。網(wǎng)關(guān)API通常被視為Ingress API的繼承者,可用于南北和東西交通。這意味著實(shí)現(xiàn)可以執(zhí)行入口控制器功能、服務(wù)網(wǎng)格功能或兩者。最終,網(wǎng)關(guān)API實(shí)現(xiàn)有可能充當(dāng)所有Kubernetes流量的API網(wǎng)關(guān)。
網(wǎng)關(guān)API處于測試階段,包括NGINX在內(nèi)的許多供應(yīng)商都在嘗試實(shí)現(xiàn)。值得密切關(guān)注這個領(lǐng)域的創(chuàng)新,甚至可以自己嘗試測試版。
結(jié)論:正確用例的正確工具
對于Kubernetes新手,甚至對于有大量經(jīng)驗(yàn)的人來說,API可能會令人痛苦地困惑。我們希望這些規(guī)則能夠?yàn)槿绾胃咝У貥?gòu)建Kubernetes架構(gòu)提供指導(dǎo)。
當(dāng)然,你的經(jīng)驗(yàn)可能有所不同,用例或情況可能是獨(dú)特的。但是,如果堅(jiān)持使用Kubernetes原生工具來簡化工具堆棧,并且只考慮在上面概述的非常特定的情況下使用單獨(dú)的API網(wǎng)關(guān)(特別是在Kubernete之外),那么旅程應(yīng)該會更加順暢。