天天看點

API 網關、Kubernetes 網關和 Service Mesh 綜合指南

作者:大資料與人工智能分享

摘要:本文介紹了API網關、Kubernetes網關和服務網格的綜合指南。API網關和Kubernetes網關解決了邊緣問題和API抽象化,而服務網格解決了服務之間的通信挑戰。文章還介紹了如何在不同的網關中配置金絲雀部署,并讨論了Kubernetes Gateway API的發展和服務網格接口(SMI)規範。最後,文章提供了一些關于何時使用哪種網關的建議。

簡介

本文将介紹三種技術,它們分别是 API 網關、Kubernetes 網關和 Service Mesh,以及它們之間的差別,以及如何應用它們。

API 網關

API 網關是一個連接配接用戶端和 API 的中介,它接收所有用戶端請求,将它們轉發到所需的 API,并将響應傳回給用戶端。

它基本上是一個具有許多功能的反向代理。

除此之外,API 網關還可以具有諸如身份驗證、安全性、細粒度流量控制和監控等功能,使 API 開發人員隻需專注于業務需求。

有許多 API 網關解決方案可供選擇。一些受歡迎的免費和開源解決方案包括:

  • Apache APISIX:一個高性能、可擴充、雲原生 API 網關,建構于 Nginx 之上。
  • Gloo Edge:一個基于 Envoy 代理建構的 API 網關。
  • Kong:一個可插拔的 API 網關,也是基于 Nginx 建構的。
  • Tyk:一個使用 Go 編寫的 API 網關,支援 REST、GraphQL、TCP 和 gRPC 協定。
  • Envoy Gateway:一個基于 Envoy 代理建構的 API 網關。

雲平台如 GCP,AWS 和 Azure 也有其自己的專有 API 網關。

API 網關、Kubernetes 網關和 Service Mesh 支援金絲雀部署,即在向大多數使用者推出新軟體版本之前,逐漸将其推向一小部分使用者。

以下示例顯示如何在 Apache APISIX 中配置金絲雀部署。

使用 API 網關進行金絲雀部署

您可以使用以下配置向 APISIX 管理 API 發送請求:

curl <http://127.0.0.1:9180/apisix/admin/routes/1> \\
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
  "uri":"/*",
  "plugins":{
    "traffic-split":{
      "rules":[
        {
          "weighted_upstreams":[
            {
              "upstream":{
                "name":"api-v1",
                "type":"roundrobin",
                "nodes":{
                  "api-v1:8080":1
                }
              },
              "weight":95
            },
            {
              "weight":5
            }
          ]
        }
      ]
    }
  },
  "upstream":{
    "type":"roundrobin",
    "nodes":{
      "api-v2:8080":1
    }
  }
}'
           

APISIX 将把 95% 的流量路由到 api-v1 服務,5% 的流量路由到 api-v2 服務。

Kubernetes Gateway

在 Kubernetes 中,您的 API 是在叢集中部署的 pod 和 service。然後您使用 Kubernetes 網關将外部流量定向到您的叢集。

Kubernetes 為此提供了兩個 API,即 Ingress API 和 Gateway API。

API 網關、Kubernetes 網關和 Service Mesh 綜合指南

Kubernetes 網關

Kubernetes Ingress API

Ingress API 的建立是為了克服預設服務類型(NodePort 和 LoadBalancer)的限制,引入了路由和 SSL 終止等功能。它還标準化了如何将 Kubernetes 服務公開給外部流量。

它由 Ingress 和 Ingress 控制器 兩個元件組成。

Ingress Kubernetes 本地對象定義了一組規則,用于外部流量通路您的服務。

以下示例配置示範了如何在 Kubernetes Ingress 對象中基于 URI 路徑路由流量:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-routes
spec:
  ingressClassName: apisix
  rules:
    - http:
        paths:
          - backend:
              service:
                name: api-v1
                port:
                  number: 8080
            path: /v1
            pathType: Exact
          - backend:
              service:
                name: api-v2
                port:
                  number: 8080
            path: /v2
            pathType: Exact
           

Ingress 控制器實作這些規則,并使用反向代理将流量路由到叢集中。

有超過 20 個 Ingress 控制器實作。APISIX 有一個 Ingress 控制器,它包裝在 APISIX API 網關周圍,作為 Kubernetes Ingress 工作。

API 網關、Kubernetes 網關和 Service Mesh 綜合指南

APISIX Ingress

APISIX Ingress 控制器将 Kubernetes Ingress 對象轉換為 APISIX 配置。

API 網關、Kubernetes 網關和 Service Mesh 綜合指南

APISIX Ingress 控制器翻譯配置

然後,APISIX 實作此配置。

API 網關、Kubernetes 網關和 Service Mesh 綜合指南

使用 Kubernetes Ingress API 的金絲雀釋出

您可以将 APISIX 與任何其他 Ingress 控制器交換,因為 Ingress API 與任何特定實作無關。這種廠商中立性對于簡單的配置非常有效。但是,如果您想要進行像金絲雀部署之類的複雜路由,則必須依賴廠商特定的注釋。

以下示例顯示了如何使用 Nginx Ingress 配置金絲雀部署。此處使用的 自定義注釋 是特定于 Nginx 的:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "5"
  name: api-canary
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: api-v2
          servicePort: 8080
        path: /
           

以上配置将 5% 的流量路由到 api-v2 服務。

除了注釋之外,像 APISIX 這樣的 Ingress 控制器還具有自定義的 Kubernetes CRD,以克服 Ingress API 的限制。

以下示例使用 APISIX CRD ApisixRoute 配置金絲雀部署:

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: api-canary
spec:
  http:
    - name: route
      match:
        paths:
          - /*
      backends:
        - serviceName: api-v1
          servicePort: 8080
          weight: 95
        - serviceName: api-v2
          servicePort: 8080
          weight: 5
           

這些自定義 CRD 使配置 Ingress 更容易,并利用了 API 網關底層的全部功能,但代價是可移植性。

Kubernetes Gateway API

Gateway API 是一個新的 Kubernetes 對象,旨在“修複” Ingress API。

它借鑒了 Ingress 控制器開發的自定義 CRD,以添加基于 HTTP 标頭的比對、權重流量拆分和其他功能,這些功能需要使用 Ingress API 的自定義專有注釋。

以下示例顯示了如何使用 Kubernetes Gateway API 配置金絲雀部署:

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
  name: api-canary
spec:
  rules:
  - backendRefs:
    - name: api-v1
      port: 8080
      weight: 95
    - name: api-v2
      port: 8080
      weight: 5
           

現在,任何 Ingress 控制器(實作了 Gateway API)都可以實作此配置。

Gateway API 還對 Ingress API 進行了許多改進,但它仍處于 alpha 階段,Gateway API 實作經常會出現問題。

服務網格

API 網關和 Kubernetes 網關在解決邊緣問題并抽象化您的 API 時跨應用程式邊界工作。

服務網格解決了不同的挑戰。

服務網格更關注服務之間的通信(東西流量),而不是服務-用戶端通信(南北流量)。

通常,這是通過使用 API/服務的 sidecar 代理來實作的。

API 網關、Kubernetes 網關和 Service Mesh 綜合指南

服務網格

在這裡,sidecar 代理處理服務之間的通信,而不是開發人員必須将網絡邏輯編碼到服務中。

有很多服務網格可用。一些流行的如下:

  • Istio:迄今為止最受歡迎的服務網格。它建構在 Envoy proxy 之上,許多服務網格使用它。
  • Linkerd:一種輕量級的服務網格,使用專門為 Linkerd 編寫的 Rust 的 linkerd2-proxy。
  • Consul Connect:強調安全性和可觀察性的服務網格。它可以使用内置代理或 Envoy。

新的服務網格提供了與通過 eBPF 直接使用核心的網絡功能的 sidecar-based 服務網格的替代方案,如 Cilium。

API 網關、Kubernetes 網關和 Service Mesh 綜合指南

一個典型的服務網格需要8個代理來代表8個服務,而像Cilium這樣基于ebpf的服務網格則不需要。

服務網格還具有基本的入口/出口網關,用于處理與服務之間的南北流量。入口網關是外部流量進入服務網格的入口點,出口網關允許網格内的服務通路外部服務。

API 網關、Kubernetes 網關和 Service Mesh 綜合指南

服務網格的入口和出口網關

Apache APISIX 也有一個名為 Amesh 的服務網格實作。它與 Istio 的控制平面一起使用 xDS 協定,替換 Sidecar 中的預設 Envoy 代理。

服務網格使您可以配置金絲雀部署。例如,您可以将來自一個服務的請求拆分為另一個服務的兩個版本。

API 網關、Kubernetes 網關和 Service Mesh 綜合指南

使用服務網格進行金絲雀部署

以下示例顯示了如何在 Istio 服務網格中配置金絲雀部署:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: api-virtual-service
spec:
  hosts:
    - api
  http:
    - route:
        - destination:
            host: api
            subset: v1
          weight: 80
        - destination:
            host: api
            subset: v2
          weight: 20
           
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: api-destination-rule
spec:
  host: api
  subsets:
    - name: v1
      labels:
        version: "1.0"
    - name: v2
      labels:
        version: "2.0"
           

這些配置是特定于Istio的。要切換到不同的服務網格,您必須建立一個不同但類似于供應商依賴的配置。

服務網格接口(SMI)規範是為解決此可移植性問題而建立的。

SMI 規範是一組Kubernetes CRD,服務網格使用者可以使用它來定義應用程式,而無需綁定到服務網格實作。

标準化嘗試隻有當所有項目都參與其中時才能起作用。但是,SMI規範沒有發生這種情況,隻有少數項目積極參與。

最近,Kubernetes SIG Network一直在發展Gateway API以支援服務網格。

GAMMA(網關API用于網格管理和監管)倡議是一個專門的團隊,擁有Gateway API項目的目标是“調查,設計和跟蹤與服務網格技術和用例相關的網關API資源,語義和其他工件。”

Gateway API是Ingress API的自然下一步,但我們必須等待看看它如何适用于服務網格。Istio 已宣布其打算将Gateway API用作所有流量管理的預設API,并繼續推動該項目的發展。

下面的示例顯示了如何使用Gateway API在Istio中配置金絲雀部署。其基本思想是使用parentRefs附加到其他服務而不是網關:

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: api-canary
spec:
  parentRefs:
  - kind: Service
    name: api-a
    port: 8080
  rules:
  - backendRefs:
    - name: api-b-v1
      port: 8080
      weight: 95
    - name: api-b-v2
      port: 8080
      weight: 5
           

有一些擔憂,即GAMMA項目可能會變得偏向于為一個特定項目的需求服務,而不是更大的社群,最終會導緻其他項目使用自己的API,類似于Kubernetes Ingress API之後的自定義CRD場景。

但是,Gateway API項目是标準化服務網格流量管理的最佳嘗試。SMI項目也加入了GAMMA倡議,具有共享願景,并将幫助倡導服務網格項目對Gateway API的一緻實作。

其他項目,例如Flagger和Argo Rollouts也已與Gateway API內建。

應該使用什麼?

這個問題隻有一個正确的答案,“看你自己”。

如果您正在開發API并需要身份驗證、安全、路由或度量标準,那麼最好使用API網關,而不是在您的API中自己建構。

如果您想在Kubernetes環境中進行類似操作,那麼您應該使用Kubernetes網關,而不是嘗試在Kubernetes上使用API網關。值得慶幸的是,許多API網關也可以使用Kubernetes原生配置。

但有時,API網關+Ingress控制器提供的功能可能對于Kubernetes環境來說過于複雜,您可能希望切換回簡單的流量管理。

另一方面,服務網格解決了完全不同的一組問題。它們還帶有自己的網關來處理南北流量(通常足夠),但還可以讓您使用具有更多功能的自己的網關。

通過Kubernetes Gateway API将API網關和服務網格的融合應該使應用程式開發人員更容易專注于解決問題,而不必擔心底層實作。

像Apache APISIX這樣的項目使用相同的技術來建構API網關和服務網格,與這些規範很好地內建,激勵廠商中立選擇。

您也可能不需要這些。您甚至可能不需要微服務或分布式架構,但是當您需要它們時,網關和網格可以使您的生活變得更加輕松。

繼續閱讀