如何理解 Istio Ingress, 它與 API Gateway 有什麼區別?

語言: CN / TW / HK

API 閘道器作為客戶端訪問後端的入口,已經存在很長時間了,它主要是用來管理”南北向“的流量;近幾年服務網格開始流行,它主要是管理系統內部,即“東西向”流量,而像 Istio 這樣的服務網格還內建了閘道器,從而將系統內外部的流量納入了統一管控。這經常給初次接觸 Istio 的人帶來困惑——服務網格與 API 閘道器之間是什麼關係?是不是使用了 Istio 就可以替代了 API 閘道器?Istio 的 API 閘道器是如何運作的?有哪些方式暴露 Istio mesh 中的服務?這篇文章給為你解答。

主要觀點

  • 服務網格誕生的初衷是為了解決分散式應用的內部流量的管理問題,而在此之前 API 閘道器已存在很久了。
  • 雖然 Istio 中內建了Gateway,但是你仍可以使用自定義的 Ingress Controller 來代理外部流量。
  • API 閘道器和服務網格正朝著融合的方向發展。

如何暴露 Istio mesh 中的服務?

下圖展示了使用 Istio Gateway、Kubernetes Ingress、API Gateway 及 NodePort/LB 暴露 Istio mesh 中服務的四種方式。

其中陰影表示的是 Istio mesh,mesh 中的的流量屬於叢集內部(東西向)流量,而客戶端訪問 Kubernetes 叢集內服務的流量屬於外部(南北向)流量。不過因為 Ingress、Gateway 也是部署在 Kubernetes 叢集內的,這些節點訪問叢集內其他服務的流量就難以歸屬了。

方式 控制器 功能
NodePort/LoadBalancer Kubernetes 負載均衡
Kubernetes Ingress Ingress Controller 負載均衡、TLS、虛擬主機、流量路由
Istio Gateway Istio 負載均衡、TLS、虛擬主機、高階流量路由、其他 Istio 的高階功能
API 閘道器 API Gateway 負載均衡、TLS、虛擬主機、流量路由、API 生命週期管理、許可權認證、資料聚合、賬單和速率限制

由於 NodePort/LoadBalancer 是 Kubernetes 內建的基本的暴露服務的方式,本文就不討論這種方式了。下文將對其他三種方式分別作出說明。

使用 Kubernetes Ingress 暴露服務

我們都知道 Kubernetes 叢集的客戶端是無法直接訪問 Pod 的 IP 地址的,因為 Pod 是處於 Kubernetes 內建的一個網路平面中。我們可以將 Kubernetes 內的服務使用 NodePort 或者 LoadBlancer 的方式暴露到叢集以外。同時為了支援虛擬主機、隱藏和節省 IP 地址,可以使用 Ingress 來暴露 Kubernetes 中的服務。Kubernetes Ingress 原理如下圖所示。

簡單的說,Ingress 就是從 Kubernetes 叢集外訪問叢集的入口,將使用者的 URL 請求轉發到不同的服務上。Ingress 相當於 Nginx、Apache 等負載均衡方向代理伺服器,其中還包括規則定義,即 URL 的路由資訊,路由資訊得的重新整理由 Ingress controller 來提供。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: istio
  name: ingress
spec:
  rules:
  - host: httpbin.example.com
    http:
      paths:
      - path: /status/*
        backend:
          serviceName: httpbin
          servicePort: 8000

上面的例子中的 kubernetes.io/ingress.class: istio 註解表明該 Ingress 使用的 Istio Ingress Controller。

使用 Istio Gateway 暴露服務

我們都知道 Istio 是繼承 Kubernetes 之後發展出來的一個流行的服務網格實現,它實現了 Kubernetes 沒有的一些功能,請參考 什麼是 Istio?為什麼 Kubernetes 需要 Istio? 簡要來說,正是因為 Istio 補足了 Kubernetes 對於雲原生應用的流量管理、可觀察性和安全方面的短板,使得流量管理變得對應用程式透明,使這部分功能從應用程式中轉移到了平臺層,成為了雲原生基礎設施。

Istio 0.8 以前版本中使用 Kubernetes Ingress 來作為流量入口,其中使用 Envoy 作為 Ingress Controller。在 Istio 0.8 及以後的版本中,Istio 建立了 Gateway 物件。Gateway 和 VirtualService 用於表示 Istio Ingress 的配置模型,Istio Ingress 的預設實現則採用了和 sidecar 相同的 Envoy 代理。通過該方式,Istio 控制面用一致的配置模型同時控制了入口閘道器和內部的 sidecar 代理。這些配置包括路由規則,策略檢查、遙測收集以及其他服務管控功能。

Istio Gateway 的功能與 Kubernetes Ingress 類似,它負責進出叢集的南北流量。Istio Gateway 描述了一個負載均衡器,用於承載進出服務網格邊緣的連線。該規範描述了一組開放埠和這些埠所使用的協議,以及用於負載均衡的 SNI 配置等。

Istio Gateway 資源本身只能配置L4到L6的功能,例如暴露的埠、TLS 設定等;但 Gateway 可與 VirtualService 繫結,在VirtualService 中可以配置七層路由規則,例如按比例和版本的流量路由,故障注入,HTTP 重定向,HTTP 重寫等所有Mesh內部支援的路由規則。

下面是一個 Gateway 與 VirtualService 繫結的示例。擁有 istio: ingressgateway 標籤的 pod 將作為 Ingress Gateway 並路由對 httpbin.example.com 虛擬主機的 80 埠的 HTTP 訪問,這相當於給 Kubernetes 敞開了一個外部訪問的入口。這與使用 Kubernetes Ingress 最大的區別就是,需要我們手動將VirtualService與Gateway 繫結,並指定 Gateway 所在的 pod。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "httpbin.example.com"

下面這個 VirtualService 通過 gateways 與上面的閘道器繫結在了一起,以接受來自該閘道器的流量。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - "httpbin.example.com"
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /status
    route:
    - destination:
        port:
          number: 8000
        host: httpbin

使用 API 閘道器暴露服務

API 閘道器是位於客戶端和後端服務之間的 API 管理工具,一種將客戶端介面與後端實現分離的方式,在微服務中得到了廣泛的應用。當客戶端發出請求時,API 閘道器會將其分解為多個請求,然後將它們路由到正確的位置,生成響應,並跟蹤所有內容。

API Gateway 是微服務架構體系中的一型別特殊服務,它是所有微服務的入口,它的職責是執行路由請求、協議轉換、聚合資料、認證、限流、熔斷等。大多數企業 API 都是通過 API 閘道器部署的。API 閘道器通常會處理跨 API 服務系統的常見任務,例如使用者身份驗證、速率限制和統計資訊。

在網格中可以有一個或多個 API Gateway。API 閘道器的職責有:

  • 請求路由和版本控制
  • 方便單體應用到微服務的過渡
  • 許可權認證
  • 資料聚合:監控和計費
  • 協議轉換
  • 訊息和快取
  • 安全和報警

以上很多基本功能比如路由和許可權認證通過 Istio Gateway 也可以實現,只是在功能的豐富度和擴充套件性方面有些成熟的 API Gateway 可能更佔優勢,不過在 Istio mesh 中再引入 API Gateway 也可能帶來一些弊端。

  • 引入了 API Gateway,需要考慮 API Gateway 本身的部署、運維、負載均衡等場景,增加了後端服務的複雜度
  • API Gateway 中承載了大量的介面適配,導致難以維護
  • 對於部分場景,增加了一跳可能導致效能的降低

總結

在 Istio mesh 中你可以使用多種 Kubernetes Ingress Controller 來充當入口閘道器,當然你還可以直接使用 Istio 內建的 Istio 閘道器,對於策略控制、流量管理和用量監控可以直接通過 Istio 閘道器來完成,這樣做的好處是通過 Istio 的控制平面來直接管理閘道器,而不需要再借助其他工具。但是對於 API 宣告週期管理、複雜的計費、協議轉換和認證等功能,傳統的 API 閘道器可能更適合你。所以,你可以根據自己的需求來選擇,也可以組合使用。

目前有些傳統的反向代理也在向 Service Mesh 方向發展,如 Nginx 構建了 Nginx Service Mesh ,Traefik 構建了 Traefik Mesh 。還有的 API 閘道器產品也向 Service Mesh 方向挺進,比如 Kong 發展出了 Kuma 。在未來,我們會看到更多 API 閘道器、反向代理和服務網格的融合產品出現。

參考