天天看點

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

作者:Rainbond開源

背景

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 将自己的業務代理出來。

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

工作原理

結構圖

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

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,當然也可以兩個都裝。

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

管理者配置 Gateway API的資源

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

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

開發者配置業務路由

開發者在自己開發的應用中配置網關,如果同時安裝多個網關實作,可以先選擇網關類型,然後通過界面配置 HTTPRoute 字段。

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

補充說明:

  • Rainbond目前版本隻支援HTTPRoute,其他類型的Route暫時不支援;
  • 從Rainbond應用市場隻能安裝 Envoy和Nginx兩種網關實作,要支援更多網關實作需要Rainbond先支援或自己制作插件;
  • 資料參考:Rainbond 的 Gateway API 插件制作實踐。

繼續閱讀