Kubernetes Gateway API 深入解讀和落地指南

Rainbond發表於2023-05-06

背景

Kubernetes Gateway API 是 Kubernetes 1.18 版本引入的一種新的 API 規範,是 Kubernetes 官方正在開發的新的 API,Ingress 是 Kubernetes 已有的 API。Gateway API 會成為 Ingress 的下一代替代方案。Gateway API 提供更豐富的功能,支援 TCP、UDP、TLS 等,不僅僅是 HTTP。Ingress 主要面向 HTTP 流量。 Gateway API 具有更強的擴充套件性,透過 CRD 可以輕易新增特定的 Gateway 型別,比如 AWS Gateway 等。Ingress 的擴充套件相對較難。Gateway API 支援更細粒度的流量路由規則,可以精確到服務級別。Ingress 的最小路由單元是路徑。

Gateway API 的意義和價值:

  • 作為 Kubernetes 官方專案,Gateway API 能夠更好地與 Kubernetes 本身整合,有更強的可靠性和穩定性。
  • 支援更豐富的流量協議,適用於服務網格等更復雜的場景,不僅限於 HTTP。可以作為 Kubernetes 的流量入口 API 進行統一。
  • 具有更好的擴充套件性,透過 CRD 可以輕鬆地支援各種 Gateway 的自定義型別,更靈活。
  • 可以實現細粒度的流量控制,精確到服務級別的路由,提供更強大的流量管理能力。

綜上,Gateway API 作為新一代的 Kubernetes 入口 API,有更廣泛的應用場景、更強大的功能、以及更好的可靠性和擴充套件性。對於生產級的 Kubernetes 環境,Gateway API 是一個更好的選擇。本篇文章將深入解讀 Kubernetes Gateway API 的概念、特性和用法,幫助讀者深入理解並實際應用 Kubernetes Gateway API,發揮其在 Kubernetes 網路流量管理中的優勢。

發展現狀

版本現狀

Gateway API 目前還處於開發階段,尚未釋出正式版本。其版本發展現狀如下:

  • v1beta1: 當前的主要迭代版本,Gateway API 進入了beta 版本,這意味著我們可以在生產中使用 Gateway API 能力了,目前 beta 版本僅支援 HTTP 協議, TCP 協議、UDP 協議、gRPC 協議、TLS 協議均為 alpha 版本。
  • v1.0: 首個正式GA版本,API穩定,可以用於生產環境。但功能還會持續完善。

可用場景

下面簡單整理了一下 HTTPRoute 的一些可用場景:

  • 多版本部署:如果您的應用程式有多個版本,您可以使用 HTTPRoute 來將流量路由到不同的版本,以便測試和逐步升級。例如,您可以將一部分流量路由到新版本進行測試,同時保持舊版本的執行。
  • A/B 測試:HTTPRoute 可以透過權重分配來實現 A/B 測試。您可以將流量路由到不同的後端服務,併為每個服務指定一個權重,以便測試不同版本的功能和效能。
  • 動態路由:HTTPRoute 支援基於路徑、請求頭、請求引數和請求體等條件的動態路由。這使得您可以根據請求的不同屬性將流量路由到不同的後端服務,以滿足不同的需求。
  • 重定向:HTTPRoute 支援重定向,您可以將某些請求重定向到另一個 URL 上,例如將舊的 URL 重定向到新的 URL。

周邊生態

目前,儘管 Gateway API 還處於開發階段,但已經有部分專案表示支援或計劃支援Gateway API。主要包括:

  • Istio 是最流行的服務網格專案之一,Istio 1.9 版本計劃引入實驗性的 Gateway API 支援。使用者可以透過 Gateway 和 HTTPRoute 資源來配置 Istio 的 Envoy 代理。
  • Linkerd 是另一個流行的服務網格專案,Linkerd 2.10 版本新增了 Gateway API 支援。使用者可以使用 Gateway API 資源來配置 Linkerd 的代理。
  • Contour 是一個Kubernetes Ingress Controller,Contour 1.14.0 版本新增 Gateway API 支援,可以使用 Gateway 和 HTTPRoute 來配置 Contour。
  • Flagger 是一款 Kubernetes 的藍綠部署和 A/B 測試工具,Flagger 0.25版本新增了對Gateway API的支援,可以使用Gateway和HTTPRoute構建Flagger的流量路由。
  • HAProxy Ingress Controller支援Gateway API,可以使用Gateway和HTTPRoute構建HAProxy的配置。
  • Traefik是著名的開源邊緣路由器,Traefik 2.5版本開始支援Gateway API並逐步淘汰Ingress支援。

除此之外,Apisix、Envoy gateway、Higress等開源專案也支援或打算支援Gateway API,各大雲服務商都在積極跟進Gateway API進展,預計未來會在相應的服務中提供Gateway API支援。可以看出,儘管Gateway API還不算成熟和穩定,但由於其強大的功能和作為Kubernetes官方專案的影響力,已經獲得大量專案的支援和相容。服務網格、API閘道器以及各大雲服務商都將是Gateway API的重點生態。

未來規劃

  • 完善功能和穩定性:繼續完善 Gateway API 的功能和穩定性,以確保其能夠應對不同場景的需求。
  • 管理規模:針對大規模 Kubernetes 叢集的需求,最佳化 Gateway API 的效能和擴充套件性,使其能夠管理更多的閘道器和路由規則。
  • 增強安全性:加強 Gateway API 的安全性,包括在傳輸過程中的加密、身份驗證等方面,以確保網路流量的安全性。
  • 完善文件和社群支援:完善 Gateway API 的文件和社群支援,以幫助使用者更好地使用和了解該專案。

Gateway API 規範解讀

基礎概念

Kubernetes Gateway API 定義了三種基本資源型別:GatewayClass、Gateway、Route 。

  • Gatewayclass: 一組共享通用配置和行為的 Gateway 集合,與 IngressClass、StorageClass 類似,需要知道 Gateway API 並不會建立真正的閘道器,真正的閘道器是由一些支援 Gateway API 的社群(基礎裝置提供商)所提供的 Controller 所建立,如 Envoy 、Istio、Nginx。GatewayClass, Gatewayclass 的作用就是繫結一個 Controller 定義一種閘道器型別。
  • Gateway: 可以說成 GatewayClass 的具體實現,宣告後由 GatewayClass 的基礎裝置提供商提供一個具體存在的 Pod,充當了進入 Kubernetes 叢集的流量的入口,負責流量接入以及往後轉發,同時還可以起到一個初步過濾的效果。
  • Route: 真實的路由,定義了特定協議的規則,用於將請求從 Gateway 對映到 Kubernetes 服務。目前只有 HTTPRoute 進入了v1beta 版本,是比較穩定的版本,後續 TCPRoute、UDPRoute、GRPCRoute、TLSRoute 等也會陸續進入 beta 版本達到生產可用,這裡將只對 HTTPRoute 進行介紹。

關於他們三者之間的關係,官方文件也給了一幅非常清晰的結構圖,如下圖所示,在我看來,圖片主要強調了面向角色的特點,官方想表達意思是 GatewayClass 由基礎設施供應商提供,Gateway 資源由叢集工程師建立,基本環境搭建完成後,開發者便可以輕鬆建立 HTTPRoute 將自己的業務代理出來。

工作原理

結構圖

GatewayClass

透過部署 GatewayClass 繫結下游實現提供的 Controller,為叢集提供一種閘道器能力,這裡可以看作是一種註冊宣告吧,將你的下游實現註冊到叢集中供 Gateway 繫結使用。Controller 可以看作監聽 Gateway 資源的 Operator。

spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller #繫結的 Controller 名稱

Gateway

Gateway 資源是一箇中間層,需要定義所要監聽的埠、協議、TLS 配置等資訊,可以將網路流量的管理和控制集中到一箇中心化的位置,提高叢集的可用性和安全性。配置完成後,由 GatewayClass 繫結的 Controller 為我們提供一個具體存在 Pod 作為流量入口,需要注意的是,各家實現在此處還是略有不同,比如說 Envoy 當你建立 Gateway 資源後,Envoy Controller 會建立一個 Deployment 資源為你提供入口流量 Pod ,然而 Nginx 則是自己本身就是流量入口 Pod 不會建立新的。

spec:
  gatewayClassName: envoy #繫結的 GatewayClass 名稱。
  listeners: # 定義了一些監聽項,供 Route 進行繫結
  - allowedRoutes: #定義流量轉發範圍
      namespaces:
        from: All #允許 Gateway 往所有的 Namespace 的 Pod 轉發流量。
    name: http #監聽項名稱。
    port: 8088 #監聽項所佔用的埠
    hostname: www.gateway.*.com #定義一個域名,一般為泛域名、匹配來自該域名的流量。
    protocol: HTTP #定義協議,HTTP或者HTTPS 
  - allowedRoutes:
      namespaces:
        from: All
    name: https
    port: 8443
    protocol: HTTPS
    tls:  #為 HTTPS 配置加密協議
      mode: Terminate #加密協議型別,Terminate 或 Passthrough
      certificateRefs:
      - kind: Secret
        name: cafe-secret
        namespace: default

協議型別:

  • Terminate:將加密的流量解密並將明文流量轉發到後端服務。這種模式需要在閘道器處配置證書和金鑰,以便對客戶端和伺服器之間的流量進行加密和解密,確保資料安全性。
  • Passthrough:將加密的流量原樣轉發到後端服務。這種模式不需要在閘道器處配置證書和金鑰,因為 TLS 連線只在後端服務處終止。這種模式適用於需要將 TLS 流量直接傳遞到後端服務的場景,如需要對後端服務進行更細粒度的訪問控制或流量監控的情況。

HTTPRoute

HTTPRoute 便跟你的業務密切相關了,在這裡定義詳細的規則,將流量代理到對應的業務服務上。

#HTTPRoute A
spec:
  parentRefs: #繫結 Gateway 監聽項
  - name: gateway #Gateway 資源名稱
    namespace: envoy #Gateway所在名稱空間
    sectionName: http #監聽項名稱
  hostnames:  #為路由配置域名
  - "www.gateway.example.com" #可配置泛域名,可配置多個
  rules: #配置詳細的路由規則,可配置多個,下面有對各種規則型別的詳細解析
  - matches: #匹配條件
    - path:  #路徑匹配
        type: PathPrefix #路徑型別:Exact 完全匹配/PathPrefix 字首匹配/RegularExpression 正則匹配
        value: /gateway 
    filters: #高階設定
    - type: requestHeaderModifier #加工請求頭
      requestHeaderModifier: #支援 set 覆蓋/add 新增/remove 刪除
        set:
        - name: service
          value: goodrain
    - type: RequestRedirect #請求重定向
      requestRedirect: 
        scheme: https # 重定向所使用的協議,http/https
        hostname: www.baidu.com #重定向的域名
        port: 8443 #重定向所使用的埠
        statusCode: 301 #重定向狀態碼:301 永久的重定向/302 臨時重定向
-----------------
#HTTPRoute B
spec:
  parentRefs: 
  - name: gateway 
    namespace: envoy 
    sectionName: https
  hostnames:  
  - "www.gateway.example.com" 
  rules: 
  - matches: 
    - headers: #請求頭匹配
      - name: service 
        value: goodrain
    backendRefs: #後端路由
    - name: goodrain-v1 # service 名稱
      port: 80 #service 埠
      weight: 80 #權重
    - name: goodrain-v2
      port: 80
      weight: 20

規則型別:

  • matches: 由一個或多個匹配條件組成,這些匹配條件可以基於HTTP請求的各種屬性(如請求方法、路徑、頭部、查詢引數等)進行匹配,從而確定哪些請求應該被路由到該規則對應的後端服務。
  • filters: 對傳入請求進行更細粒度的控制,例如修改請求的頭部、轉發請求到其他服務、將請求重定向到不同的URL等。它們由一組規則組成,每個規則都包含一個或多個過濾器。這些過濾器可以在請求被路由到後端服務之前或之後進行處理,以實現各種不同的功能。
  • backendRefs: 用來指定後端服務的引用,它包含一個後端服務的列表,每個服務由名稱和埠號組成,可以使用不同的負載均衡演算法,將請求路由到後端服務的其中一個例項中,實現負載均衡。

深入瞭解以後,我們可以看出來 HTTPRoute 的用法非常的靈活,可以透過將不同的規則組合搭配,來建立一條適合我們業務的路由,就拿上面的 yaml 為例,整體流量走向如下圖所示,當 http 協議的請求流量進入後,按照規則匹配,流量會向下轉發到 HTTPRoute A 的路由上,HTTPRoute A 按照規則順序,先對請求進行加工處理新增請求頭,之後將請求重定向到 HTTPRoute B上,再由 HTTPRoute 將流量按照權重比例路由到對應的後端服務。

需要注意的是,規則集有優先順序,當同時存在多個規則(rule)的時候,流量會從上往下進行匹配,只要有匹配上流量會直接代理到其對應的後端或重定向到對應的路由。

Gateway API 快速上手

整理一下部署思路,如果在業務中使用 Gateway API 我們都需要做什麼。

  • Kubernetes Gateway API 基礎 CRD。安裝閘道器 API CRD地址
  • Gateway API 下游實現,即基礎裝置供應商。(包含 GatewayClass 資源)下游實現地址
  • 建立 Gateway ,定義基礎的路由方式供 HTTPRoute 選擇。根據上面的欄位解釋自行編寫。
  • 建立 HTTPRoute 設定規則繫結自己的業務。根據上面的欄位解釋自行編寫。

下面以 Envoy 提供的 demo 為例,串一下整體流程

安裝Gateway API CRD 和 Envoy Controller

kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v0.3.0/install.yaml

檢視安裝效果

# 檢視安裝的 CRD 資源
kubectl get crd |grep networking.k8s.io

# 檢視安裝的 envoy controller
kubectl get pod -n envoy-gateway-system

安裝 Gateway、HTTPRoute 及示例應用

kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v0.3.0/quickstart.yaml

內部 GatewayClass 資源

資源的 controllerName 屬性欄位配置繫結了 envoy 的 controller

apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
  name: eg
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller

內部 Gateway 資源

資源的 gatewayClassName 屬性欄位配置繫結了 gatewayclass 資源名稱 eg,同時提供了一個 對內監聽埠為 80,協議型別為 http 的監聽項。

apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: eg
spec:
  gatewayClassName: eg
  listeners:
    - name: http
      protocol: HTTP
      port: 80

內部的 HTTPRoute 資源

資源的 parentRefs 屬性欄位配置繫結了 gateway 資源名稱 eg。域名為 www.example.com ,代理的後端服務型別選擇了 service,名稱為 backend ,服務埠為 3000。

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: backend
spec:
  parentRefs:
    - name: eg
  hostnames:
    - "www.example.com"
  rules:
    - backendRefs:
        - group: ""
          kind: Service
          name: backend
          port: 3000
          weight: 1
      matches:
        - path:
            type: PathPrefix
            value: /

檢視安裝效果

# 檢視安裝的 gatewayclass 資源
kubectl get gatewayclass

# 檢視安裝的 gateway 資源
kubectl get gateway

# 檢視安裝的 httproute 資源
kubectl get httproute

#檢視由 Controller 提供的流量入口 Pod。
kubectl get pod -n envoy-gateway-system

#檢視路由解析地址,其中 nodeport 型別的 svc 便是你的解析地址。
kubectl get svc -n envoy-gateway-system|grep LoadBalancer

#訪問
curl --resolve www.example.com:31830:xx.xxx.xx.xxx --header "Host: www.example.com"  http://www.example.com:31830/get                                           

Gateway API 生產指南

Gateway API使用到生產需要考慮易用性、可管理性和穩定性因素:

  • 易用性:Gateway API擴充套件了很多配置內容,如果直接寫yaml上手難度較大,而且容易出錯,所以需要有一個基於UI的管理工具。
  • 可管理性:Gateway API支援分角色管理和使用,跟平臺工程的思路一致,但要用到生產需要有一個分許可權和角色的平臺。
  • 穩定性:Gateway API當前的實現中,Envoy 和 Nginx可以用到生產環境。

基於以上因素,在生產環境需要Gateway API的管理工具,當前相對成熟的工具可以選擇Rainbond,它執行Kubernetes基礎上,它也是平臺工程的設計思路,提供web介面管理Kubernetes的資源,包括Gateway API,對使用者不需要寫Yaml檔案,能區分管理員角色和普通開發者角色,管理員可以透過管理介面安裝相容的Gateway API的實現,比如Envoy和Nginx,安裝好的閘道器,普通開發者只需要配置業務的路由就可以使用,不用關心是哪一種實現。

具體落地過程:

在Kubernetes上安裝Rainbond

參考安裝文件: 基於 Kubernetes 安裝 Rainbond

管理員安裝Gateway API的閘道器實現

透過Rainbond提供的應用市場,搜尋 GatewayAPI會出來三個應用,先安裝GatewayAPI-Base,再安裝GatewayAPI-Envoy或Gateway-Nginx,當然也可以兩個都裝。

管理員配置 Gateway API的資源

平臺管理 / 擴充套件 / 能力 點選對應資源的編輯,配置Gateway 和 GatewayClass資源。

開發者配置業務路由

開發者在自己開發的應用中配置閘道器,如果同時安裝多個閘道器實現,可以先選擇閘道器型別,然後透過介面配置 HTTPRoute 欄位。

補充說明:

  • Rainbond當前版本只支援HTTPRoute,其他型別的Route暫時不支援;
  • 從Rainbond應用市場只能安裝 Envoy和Nginx兩種閘道器實現,要支援更多閘道器實現需要Rainbond先支援或自己製作外掛;
  • 資料參考:Rainbond 的 Gateway API 外掛製作實踐

相關文章