API Gateway vs Service Mesh


一、API Gateway

網關,就是指一個流量的集中式出入口。而 API Gateway,顧名思義,就是在 Gateway 上再添加了一些 API 相關的功能后得到的東西。
具體而言,API Gateway 就是比普通的網關多干了一些以前我們在應用內部實現的事:身份認證,權限控制,基於來源的流量控制,日志服務等,甚至是直接在第七層魔改 HTTP 請求的內容。好處有:

  1. API Gateway 把這些功能都從微服務層抽離到了網關層,降低了應用層的復雜度。
  2. API Gateway 可以將后端微服務的 API 進一步封裝成粗粒度 API,降低客戶端的請求次數。
  3. API Gateway 可以將后端 API 封裝成更通用的格式,保證后端 API 變動不會影響客戶端。
  4. 等等

Kubernetes 的網關 Ingress 就是一個普通的網關,官方的 Ingress 定義只能進行簡單的七層轉發配置,第四層轉發都不支持。沒有 API 層面的東西。
因此很多社區的 Ingerss 實現都通過添加 Annotation 或者 CRDs 來添加額外的特性。

而作為一個 API Gateway,Kong 要比官方的 Ingress Controller 強大很多,它首先兼容了 K8s 的 Ingress 定義,然后又通過 CRDs 添加了一些額外的功能/特性。所有參數都以 K8s yaml 的形式保存與配置。
可以說 Kong 的 “K8s 本地化”是做得非常好了,使用體驗上也很不錯。

另外服務網格 Istio 為了提升自己對入口網關的掌控力,統一網關層和服務網格的配置,完全拋棄了 Ingress 定義,自己做了一套獨立的入口網關,叫 Ingress Gateway.
這個 IngerssGateway 本身就是一個 Envoy,能和 Istio 服務網格無縫融合。這樣 Istio 的 Policy/Security 等配置就能直接應用在網關上,不需要在服務網格內部處理(個人猜測)。

API 網關使用 JWT 進行身份驗證時,只需要 JWK 公鑰(登錄時才需要私鑰生成 JWT),在 API Gateway 里設置好公鑰,就能統一進行身份認證。

選擇 API 網關

首先看一下 API Gateway - CNCF LandScape

其中最著名的應該就是 Kong 了,試用后發現 kong 和 kubernetes 的兼容層 Kong/kubernetes-ingress-controller 做得還是比較好的,
通過 Annotation 和 CRDs(k8s 自定義資源)對 Kong 進行配置,Annotation 只用於簡單的配置綁定,大部分配置都通過 CRDs 的 yaml 配置實現。體驗上比一些純粹使用 Annotaion 的應用要好不少。
Kong 目前也在積極向服務網格靠攏,不僅自己實現了一套新服務網格 Kuma,也做了 Kong API Gateway 和 Istio 的兼容(雖然說還完全沒搜到 Kong+Istio 的落地項目)。

另外國內近期開源了一個新興的 API Gateway —— APISIX,這同樣是一個基於 Openresty,使用 lua 編寫的 API Gateway。
不過相比 Kong,它目前對 Kubernetes 的支持還比較弱,近期才添加了通過 yaml 文件進行配置的功能,而和 k8s ingress 的結合現在連 alpha 都算不上。
如果要放在 k8s 里跑,目前只能以 configmap 的方式將 yaml 配置映射到容器中,apisix 自己會輪詢該 yaml 的修改。

二、服務網格

Gateway 是控制集群流量的出入,被稱作南北向流量管理。
而 Service Mesh 目前主要被用於集群內部微服務之間的流量管控,被稱作東西向流量的管理。(目前已經出現了 Service Mesh 和 API Gateway 相互融合的趨勢)

Gateway 只需要在集群入口處設置一個「關卡」,而 Service Mesh 為了管理服務之間的流量,它需要在每個微服務旁邊都設置一個網絡「關卡」,這被稱為 SideCar 模式。

選擇服務網格

主流的服務網格目前就兩個:Linkerd2 和 Istio,功能方面現在 Linkerd2 正在追趕 Istio。

Istio 現在比 Linkerd2 多很多的功能,其中的 Policy 策略限制和認證授權(Authentication/Authorization)其實屬於 API Gateway 的范疇。可見服務網格正在吸收 API Gateway 的一些長處。
兩個服務網格在其他方面的區別都大同小異,如流量切分、故障注入、鏈路追蹤/流量拓撲、mTLS 等,只是這些功能 Linkerd2 遠沒有 Istio 成熟。

Istio 的優勢在於功能豐富,而且比較穩定,缺點是性能差,配置復雜。
Linkerd2 優勢在於性能優越,配置也可能會更簡單些,但是重構后穩定性還需要考察,功能上也沒有 Istio 強。

API Gateway 與 Service Mesh(服務網格)

這兩個東西並不是非常的涇渭分明,比如 Istio 作為一個服務網格,也搞了一套自己的 IngressGateway 和 EgressGateway,而且 Istio 本身也通過 Policy 和 Authentication/Authorization 實現了一部分 API Gateway 的功能。

現在問題就來了:Istio 弄了一套自己的路由規則,Kong 又是以 k8s Ingress 為基礎實現的 k8s 集成。那如果為了使用一部分 Kong 支持而 Istio 沒有的特性,我們要同時在 K8s 中用這兩個東西呢?該怎么辦?我的配置到底是用 Istio IngressGateway 還是 Ingress?Kong 和 Istio 要如何交互?

Kong-Ingress-Controller 在去年 9 月發布的 0.6 版本中,給出的解決方案是:

  1. 入口網關的規則使用 Kong Ingress 配置,也就是拋棄掉 Istio 的 IngressGateway
  2. Kong-Ingress-Controller 通過 Envoy SideCar 將流量導入到 Istio 服務網格中。

官方給的示意圖如下,可和 Istio 部署示意圖 對比查看:
kong-ingress-controller + istio

如何為服務網格選擇入口網關? 里詳細說明了上述集成方案的由來,他給出的圖比 Kong 官方的更清楚些:

Kong 使用 k8s Ingerss 和自己的 CRDs 替換掉了 Istio 官方的 Gateway,Istio 服務網格層的 VirtualService 等不變。

這樣的一個方案,顯然存在性能損耗,Gateway 那里多了一跳(Proxy)。以后的前進方向肯定是 API Gateway 和 Service Mesh 相互融合,待觀察了。

Istio

Kong 和 Istio 的集成方式不能令人滿意。

一番搜索發現 Istio 本身也支持 jwt 驗證,試用之下感覺還行。使用方式參見 使用 Istio 進行 JWT 身份驗證(充當 API 網關)

另外 Istio 之前通過 Mixer 提供了 rate limiting 等功能,但是這個 Mixer 由於性能問題現在已經被閹割掉了。官方給出的方案是編寫 Envoey 的 WASM 插件來實現這個功能。這個有待考察。

總結

目前沒有什么好用的方案,等社區發展吧。。

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM