API 閘道器 vs. Ingress Controller vs. Service Mesh,該怎麼選?

語言: CN / TW / HK

原文作者:Owen Garrett of F5

原文連結: API 閘道器 vs. Ingress Controller vs. Service Mesh,該怎麼選? - NGINX

轉載來源:NGINX 官方網站


我們在 2021 年舉辦的 Ingress Controller 和 Service Mesh 網路研討會中,幾乎每場都會聽到以下類似的問題:“這個工具與 API 閘道器有什麼不同?”,或者,“我需要在 Kubernetes 中同時使用 API 閘道器和 Ingress Controller(或 Service Mesh)嗎?”

我們完全可以理解這些困惑,原因有二:

  • Ingress Controller 和 Service Mesh 適用於多種 API 閘道器用例。
  • 一些廠商將他們的 API 閘道器工具定位為 Ingress Controller 或 Service Mesh 的替代方案,或者將這三種功能全部整合到一個工具中。

本文將探討這些工具的不同之處,以及針對不同的 Kubernetes API 閘道器用例該選用哪種工具。有關詳細內容(包括演示),請觀看網路研討會:“Kubernetes 的 API 閘道器用例”。

定義

API 閘道器、Ingress Controller 和 Service Mesh 本質上都是一種代理,旨在管理您多種環境內的流量進入和流動。

什麼是 API 閘道器?

API 閘道器將 API 請求從客戶端路由到適當的服務,但人們卻對這個簡單定義存在很大的誤解,認為 API 閘道器是一種獨特的技術,實則不然。“API 閘道器”描述了一組可以通過不同型別的代理(ADC 或負載均衡器和反向代理最為常見,Ingress Controller 和 Service Mesh 日漸興起)實現的用例。

對於一個工具必須具備哪些功能才能充當 API 閘道器,業界尚未達成共識。我們發現,客戶通常需要以下能力(按用例分):

彈性用例

  • A/B 測試、灰度部署和和藍綠部署
  • 協議轉換(例如在 JSON 和 XML 之間轉換)
  • 速率限制
  • 服務發現

流量管理用例

  • 基於方法(method-based)的路由和匹配
  • 請求/響應標頭和正文操作
  • 在七層請求路由

安全用例

  • API 模式實施
  • 客戶端身份驗證和授權
  • 自定義響應
  • 細粒度訪問控制
  • TLS 終止

幾乎上述所有用例在 Kubernetes 中都很常見。協議轉換以及請求/響應標頭和正文操作相對少見一些,因為它們通常與不太適合 Kubernetes 和微服務環境的傳統 API 相關聯。

如欲瞭解有關 API 閘道器用例的更多資訊,請參閱我們的博文“將 NGINX 部署為 API 閘道器(第 1 部分)” 。

什麼是 Ingress Controller?

Ingress controller(也叫 Kubernetes Ingress Controller,簡稱 KIC)是一個專用的四層和七層代理,用於管理進出 Kubernetes 環境和服務的流量(稱為出入向流量或南北向流量)。除了流量管理之外,Ingress Controller 還可提供視覺化和故障排除、安全防護和身份驗證,並且幾乎可以實現最高階的 API 閘道器用例。

如欲瞭解關於 Ingress Controller 基本流量管理之外的功能,請參閱我們的博文“Ingress Controller 選購指南,第 1 部分:確定您的需求”。

什麼是 Service Mesh?

Service Mesh負責處理 Kubernetes service 之間的流量(簡稱 service 到 service 流量或東西向流量),通常用於實現端到端加密 (E2EE)。隨著越來越多的企業開啟高階部署或產生 E2EE 需求,原本應用較少的 Service Mesh 正日益受到更多關注。Service Mesh 能夠在非常靠近應用的地方用作分散式(輕量級)API 閘道器,這可以通過 Service Meshsidecar在資料平面上實現。

如欲瞭解有關 Service Mesh 以及使用場景的更多資訊,或準備使用 Service Mesh 請參閱我們的博文“如何選擇 Service Mesh”。

為 Kubernetes 環境使用 Kubernetes 原生工具

Mark Church 在 NGINX Sprint 2.0 主旨演講“Kubernetes 和應用網路的未來”中說道,“未來,API 閘道器、負載均衡器和 Service Mesh 的特徵和功能將會變得越來越相近”。我們完全同意這種說法,但我們的側重點是如何根據工具的使用位置(或方式)選擇合適的工具。畢竟合適的才是好用的。

那麼如何確定哪種工具適合您呢?我們有個簡單的辦法:如果您需要在 Kubernetes 內使用 API 閘道器功能,通常來說最好選擇可以使用 Kubernetes 原生配置工具(例如 YAML)進行配置的工具,也就是 Ingress Controller 或 Service Mesh。但有人疑惑:“我的 API 閘道器工具的功能比 Ingress Controller(或 Service Mesh)多很多,是我忽略了什麼嗎?”不是!功能越多不等於工具越好,尤其在 Kubernetes 中,工具太過複雜反而會成為一大致命因素。

注:“Kubernetes 原生”(不同於Knative)指專門為 Kubernetes 設計和構建的工具。通常,它們與 Kubernetes CLI 一起使用,可以使用 Helm 安裝,並與 Kubernetes 功能整合。

大多數 Kubernetes 使用者更喜歡以 Kubernetes 原生方式配置的工具,因為這樣可以避免調整開發或 GitOps 體驗。YAML 友好型工具有三大優勢:

  • 由於 Kubernetes 團隊都熟悉 YAML 語言,如果您使用現有 Kubernetes 工具實現 API 閘道器功能,他們的學習難度就會大大降低甚至為零。您的團隊可以運用現有技能完成工作,而無需費心學習如何配置那些可能只是偶爾用到的新工具。
  • 與其他 Kubernetes 工具一樣,YAML 友好型工具也能夠以同樣的方式實現自動化。只要是可以乾淨利索地融入工作流程的工具,就都會受到團隊的歡迎,使用率也會因此增加。
  • 您可以使用 Ingress Controller 或 Service Mesh 或同時使用兩者來壓縮您的 Kubernetes 流量管理工具堆疊。畢竟,每一次額外的跳轉都很重要,我們沒有理由增加不必要的延遲或單點故障。當然,減少 Kubernetes 中的技術部署數量也有利於降低預算和提高整體安全性。

南北向 API 閘道器用例:使用 Ingress Controller

Ingress Controller 能夠支援多種 API 閘道器用例。除了上文“定義”中所述的用例之外,我們發現企業最看重可以實現以下功能的 Ingress Controller:

  • 解除安裝身份驗證和授權
  • 基於授權的路由
  • 7 層路由和匹配(HTTP、HTTP/S、標頭、cookie、方法)
  • 協議相容性(HTTP、HTTP/2、WebSocket、gRPC)
  • 速率限制

示例場景:方法級路由

若您想要實現方法級的匹配和路由,您需要使用 Ingress Controller 來拒絕 API 請求中的POST方法。

一些攻擊者會通過傳送不符合 API 定義的請求型別來尋找 API 中的漏洞,例如向定義為只接收GET請求的 API 傳送POST請求。Web 應用防火牆 (WAF) 無法檢測到這些型別的攻擊(它們只檢查攻擊的請求字串和正文),因此最好在 Ingress 層中使用 API 閘道器,以阻止惡意請求。

舉例來說,假設您的叢集剛剛添加了新的 API/coffee/{coffee-store}/brand。第一步是使用 NGINX Ingress Controller 暴露 API(只需將 API 新增到upstreams欄位)。

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

要啟用方法級匹配(method-level matching),您應在routes欄位中新增/coffee/{coffee-store}/brand路徑,並新增兩個使用$request_method變數的conditions,以區分GETPOST請求。任何使用 HTTPGET方法的流量都會自動傳遞到coffee服務。使用POST方法的流量將被定向到一個錯誤頁面,並提示"You``are``rejected!"這樣,您就可以保護新 API 不受非法POST流量的影響。

routes:
  - path: /coffee/{coffee-store}/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

有關如何使用方法級路由和匹配並彈出錯誤頁面的更多資訊,請參閱NGINX Ingress Controller 文件。有關使用 Ingress Controller 實現 API 閘道器功能的安全性相關的示例,請閱讀我們博文“藉助 Okta 和 NGINX Ingress Controller 實現 Kubernetes 的 OpenID Connect 身份驗證”。

東西向 API 閘道器用例:使用 Service Mesh

對於大多數 API 閘道器用例來說,Service Mesh 不是必需的,甚至一開始也不會提供任何幫助,因為您想做的大多數事情都可以在 Ingress 層完成,也理應在這裡完成。但隨著架構複雜性的增加,Service Mesh 的價值也將日益彰顯。我們發現,E2EE 和流量分割用例(例如 A/B 測試、灰度部署和藍綠部署)最能體現 Service Mesh 的價值。

示例場景:灰度部署

您希望使用基於 HTTP/S 標準的條件路由在服務之間設定灰度部署。

這樣做的好處是,您可以逐步實施 API 變更(例如新功能或新版本),而不會影響大部分的生產流量。

目前,您的 NGINX Ingress Controller 能夠路由 NGINX Service Mesh 託管的兩個服務(Coffee.frontdoor.svcTea.frontdoor.svc)之間的流量。這些服務接收來自 NGINX Ingress Controller 的流量,並將其路由到適當的應用功能,包括Tea.cream1.svc。您決定重構Tea.cream1.svc,並呼叫新版本Tea.cream2.svc。您希望 Beta 測試人員提供有關新功能的反饋,因此您根據 Beta 測試人員的唯一會話 cookie 配置灰度流量分割,從而確保您的普通使用者僅體驗Tea.cream1.svc

要使用 NGINX Service Mesh,您首先需要在Tea.frontdoor.svc(包括Tea.cream1.svcTea.cream2.svc)前端的所有服務之間建立一個流量分割。要啟用條件路由,您需要建立一個HTTPRouteGroup資源(名為tea-hrg),並將其與流量分割相關聯,確保只有來自 Beta 使用者的請求(會話 cookie 設定為version=beta的請求)可以從Tea.frontdoor.svc路由到Tea.cream2.svc。您的普通使用者仍然只體驗Tea.frontdoor.svc後端的版本 1 服務。

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 分割,這意味著您的所有 Beta 測試人員都將體驗Tea.cream2.svc,當然,您也可以根據您的 Beta 測試策略選擇合適的比例。Beta 測試完成後,您可以使用一個簡單的灰度部署(不包含 cookie 路由)來測試Tea.cream2.svc的彈性。

有關 NGINX Service Mesh 流量分割的更多資訊,請參閱我們的文件。上面的流量分割配置是自引用的,因為根服務也被列為後端服務。Service Mesh 介面規範(smi-spec) 目前不支援此配置,但是該規範目前處於 alpha 階段,可能會進行修改。

何時(以及如何)為 Kubernetes 應用部署 API 閘道器工具

雖然 Kubernetes 的大多數 API 閘道器用例可以(並且應該)用 Ingress Controller 或 Service Mesh 解決,但在一些特殊情況下 API 閘道器工具(例如 NGINX Plus)也適用。

業務要求

雖然多個團隊或專案可以使用同一套 Ingress Controller,也可以在不同的環境中使用不同的 Ingress Controller,但出於各種原因,您可能會選擇在 Kubernetes 內部部署專用的 API 閘道器,而不是利用現有的 Ingress Controller。在 Kubernetes 中同時使用 Ingress Controller 和 API 閘道器可以為企業提供出色的靈活性以滿足業務需求。部分場景包括:

  • 您的 API 閘道器團隊不熟悉 Kubernetes,也不使用 YAML。例如,如果他們不熟悉 NGINX 配置——那麼在 Kubernetes 中將 NGINX Plus 部署為 API 閘道器後可以減少團隊間衝突和並減緩學習曲線。
  • 您的平臺運營團隊更喜歡只使用 Ingress Controller 管理應用流量。
  • 您有一個只適用於叢集中某一服務的 API 閘道器用例。與其使用 Incress Controller 為所有南北向流量應用某種策略,不如部署 API 閘道器,只在需要的地方應用該策略。

將 API 遷移到 Kubernetes 環境中

在將現有 API 遷移到 Kubernetes 環境中時,您可以將這些 API 釋出到部署在 Kubernetes 外部的 API 閘道器工具上。在這種情況下,API 流量通常通過外部負載均衡器(用於叢集之間的負載均衡)進行路由,然後進入被配置為 API 閘道器的負載均衡器,最後進入 Kubernetes 叢集中的 Ingress Controller。

支援 Kubernetes 中的 SOAP API

雖然大多數現代 API 都是使用 REST 建立的(部分原因是 RESTful 或 gRPC 服務和 API 能夠充分利用 Kubernetes 平臺),但您可能仍有一些 SOAP API 沒有進行重新架構。雖然我們不建議在 Kubernetes 中使用 SOAP API(因為它沒有針對微服務進行優化),但是在還沒有重新生成架構前您可能還是需要在 Kubernetes 中部署它的。API 有可能需要與基於 REST 的 API 客戶端通訊,在這種情況下,您需要一種在 SOAP 和 REST 協議之間進行轉換的方法。雖然您可以使用 Ingress Controller 執行此功能,但我們不建議您這樣做,因為這種做法非常耗費資源。我們建議您按 pod 或按服務將 API 閘道器工具部署為代理,以便在 SOAP 和 REST 之間進行轉換。

Kubernetes 內外的 API 流量管理

我們還有一小部分客戶比較關注 Kubernetes 內外的 API 流量管理。如果 API 管理策略的優先順序高於選擇 Kubernetes 原生工具,那麼部署在 Kubernetes 中的“Kubernetes 友好型”API 閘道器(可以與 API 管理解決方案整合)可能是您正確的選擇。

**注:**與 Kubernetes 原生工具不同,_Kubernetes 友好型_工具(有時也稱為_Kubernetes 適應型_工具)不是專為 Kubernetes 設計的,不能使用 Kubernetes 配置來管理。但是,它們輕巧便捷,便於在 Kubernetes 中執行,既不會顯著增加延遲,也無需進行大量的變通。

開始使用 NGINX

NGINX 為上述三種部署場景提供了選項。

Kubernetes 原生工具:

  • NGINX Ingress Controller—— 面向 Kubernetes 的基於 NGINX Plus 的 Ingress Controller ,可實現高階的流量控制和整形、監控和視覺化、身份驗證和單點登入 (SSO)。
  • NGINX Service Mesh—— 一種對開發人員友好的輕量級、可立即使用的 Service Mesh,能夠將 NGINX Plus 用作企業級 sidecar。

歡迎申請 NGINX Ingress Controller(帶有 NGINX App Protect WAF 和 DoS)30 天免費試用版,並下載永久免費的 NGINX Service Mesh。

對於 Kubernetes 環境內外的 Kubernetes 友好型 API 閘道器:

  • NGINX Plus—— 可用作一體化負載均衡器、反向代理、Web 伺服器和 API 閘道器,並具有高可用性、主動健康檢查、DNS 系統發現、會話持久化和 RESTful API 等企業級特性。可與NGINX Controller相整合,打造 API 全生命週期解決方案。

更多資源

想要更及時全面地獲取 NGINX 相關的技術乾貨、互動問答、系列課程、活動資源?

請前往 NGINX 開源社群: