本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

使用 Gateway API 演進 Kubernetes 網路

Ingress 資源是 Kubernetes 眾多成功案例之一。它建立了一個多樣化的 Ingress 控制器生態系統,這些控制器以標準化和一致的方式在數十萬個叢集中使用。這種標準化幫助使用者採用了 Kubernetes。然而,在 Ingress 建立五年後,出現了碎片化的跡象,分裂成不同但驚人相似的 CRD過載的註解。Ingress 普及的同樣的可移植性也限制了它的未來。

在 2019 年聖地亞哥 Kubecon 大會上,一群熱情的貢獻者齊聚一堂,討論Ingress 的演變。討論一直持續到街對面的酒店大堂,由此產生的內容後來被稱為 Gateway API。這次討論基於幾個關鍵假設:

  1. 路由匹配、流量管理和服務暴露的基礎 API 標準已經商品化,作為自定義 API,它們對實現者和使用者幾乎沒有價值
  2. 可以透過通用核心 API 資源表示 L4/L7 路由和流量管理
  3. 可以以不犧牲核心 API 使用者體驗的方式提供更復雜能力的擴充套件性

引入 Gateway API

這導致了設計原則,使得 Gateway API 能夠在 Ingress 的基礎上進行改進:

  • 表達能力 - 除了 HTTP 主機/路徑匹配和 TLS,Gateway API 還可以表達 HTTP 頭操作、流量權重和映象、TCP/UDP 路由等能力,這些能力在 Ingress 中只能透過自定義註解實現。
  • 面向角色的設計 - API 資源模型反映了路由和 Kubernetes 服務網路中常見的職責分離。
  • 可擴充套件性 - 資源允許在 API 中的各個層附加任意配置。這使得在最合適的位置進行細粒度定製成為可能。
  • 靈活的一致性 - Gateway API 定義了不同的一致性級別——核心(強制支援)、擴充套件(如果支援則可移植)和自定義(不保證可移植性),統稱為靈活的一致性。這促進了一個高度可移植的核心 API(如 Ingress),同時為 Gateway 控制器實現者提供了靈活性。

Gateway API 是什麼樣的?

Gateway API 引入了一些新的資源型別:

  • GatewayClasses 是叢集範圍的資源,充當模板,明確定義從它們派生的 Gateways 的行為。這在概念上類似於 StorageClasses,但用於網路資料平面。
  • Gateways 是 GatewayClasses 的已部署例項。它們是執行路由的資料平面的邏輯表示,可以是叢集內代理、硬體負載均衡器或雲負載均衡器。
  • 路由 (Routes) 不是單一資源,而是代表許多不同的協議特定路由資源。HTTPRoute 具有匹配、過濾和路由規則,適用於可以處理 HTTP 和 HTTPS 流量的 Gateway。類似地,還有 TCPRoutesUDPRoutesTLSRoutes,它們也具有協議特定的語義。該模型還允許 Gateway API 在未來逐步擴充套件其協議支援。

The resources of the Gateway API

Gateway 控制器實現

好訊息是,儘管 Gateway 處於 Alpha 階段,但已經有幾個Gateway 控制器實現可以執行。由於它是標準化的規範,以下示例可以在其中任何一個上執行,並且功能應該完全相同。請檢視入門指南,瞭解如何安裝和使用這些 Gateway 控制器之一。

動手使用 Gateway API

在下面的示例中,我們將演示不同 API 資源之間的關係,並引導您完成一個常見用例:

  • foo 團隊將其應用程式部署在 foo 名稱空間中。他們需要控制其應用程式不同頁面的路由邏輯。
  • bar 團隊在 bar 名稱空間中執行。他們希望能夠對其應用程式進行藍綠髮布以降低風險。
  • 平臺團隊負責管理 Kubernetes 叢集中所有應用程式的負載均衡器和網路安全。

以下 foo-route 對 foo 名稱空間中的各種服務進行路徑匹配,並有一個指向 404 伺服器的預設路由。這透過 foo.example.com/loginfoo.example.com/home 分別暴露 foo-auth 和 foo-home 服務。

kind: HTTPRoute
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
  name: foo-route
  namespace: foo
  labels:
    gateway: external-https-prod
spec:
  hostnames:
  - "foo.example.com"
  rules:
  - matches:
    - path:
        type: Prefix
        value: /login
    forwardTo:
    - serviceName: foo-auth
      port: 8080
  - matches:
    - path:
        type: Prefix
        value: /home
    forwardTo:
    - serviceName: foo-home
      port: 8080
  - matches:
    - path:
        type: Prefix
        value: /
    forwardTo:
    - serviceName: foo-404
      port: 8080

在同一個 Kubernetes 叢集的 bar 名稱空間中執行的 bar 團隊也希望將其應用程式暴露到網際網路,但他們也希望控制自己的金絲雀和藍綠髮布。以下 HTTPRoute 配置了以下行為:

  • 對於發往 bar.example.com 的流量

    • 將 90% 的流量傳送到 bar-v1
    • 將 10% 的流量傳送到 bar-v2
  • 對於發往 bar.example.com 且 HTTP 頭為 env: canary 的流量

    • 將所有流量傳送到 bar-v2

The routing rules configured for the bar-v1 and bar-v2 Services

kind: HTTPRoute
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
  name: bar-route
  namespace: bar
  labels:
    gateway: external-https-prod
spec:
  hostnames:
  - "bar.example.com"
  rules:
  - forwardTo:
    - serviceName: bar-v1
      port: 8080
      weight: 90
    - serviceName: bar-v2
      port: 8080
      weight: 10
  - matches:
    - headers:
        values:
          env: canary
    forwardTo:
    - serviceName: bar-v2
      port: 8080

路由和 Gateway 繫結

因此,我們有兩個 HTTPRoute 匹配並將流量路由到不同的服務。您可能想知道,這些服務在何處可訪問?它們透過哪些網路或 IP 暴露?

路由如何暴露給客戶端由路由繫結管理,它描述了路由和 Gateway 如何在彼此之間建立雙向關係。當路由繫結到 Gateway 時,意味著它們的集體路由規則已在底層負載均衡器或代理上配置,並且可以透過 Gateway 訪問路由。因此,Gateway 是可透過路由配置的網路資料平面的邏輯表示。

How Routes bind with Gateways

管理委託

Gateway 和 Route 資源之間的分離允許叢集管理員將部分路由配置委託給各個團隊,同時仍保留集中控制。以下 Gateway 資源在埠 443 上暴露 HTTPS,並使用叢集管理員控制的證書終止該埠上的所有流量。

kind: Gateway
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
  name: prod-web
spec:
  gatewayClassName: acme-lb
  listeners:  
  - protocol: HTTPS
    port: 443
    routes:
      kind: HTTPRoute
      selector:
        matchLabels:
          gateway: external-https-prod
      namespaces:
        from: All
    tls:
      certificateRef:
        name: admin-controlled-cert

以下 HTTPRoute 展示了路由如何透過其 kind (HTTPRoute) 和資源標籤 (gateway=external-https-prod) 確保其匹配 Gateway 的選擇器。

# Matches the required kind selector on the Gateway
kind: HTTPRoute
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
  name: foo-route
  namespace: foo-ns
  labels:

    # Matches the required label selector on the Gateway
    gateway: external-https-prod
...

面向角色的設計

當您將所有這些結合在一起時,您將擁有一個可以安全地由多個團隊共享的負載均衡基礎設施。Gateway API 不僅是用於高階路由的更具表達力的 API,而且還是面向角色的 API,專為多租戶基礎設施而設計。其可擴充套件性確保它將隨著未來的用例而演變,同時保持可移植性。最終,這些特性將使 Gateway API 很好地適應不同的組織模型和未來的實現。

嘗試並參與

有許多資源可供查閱以瞭解更多資訊。