從 API 網關到 Service Mesh:雲原生架構中的網關技術解析

本文譯自 A Comprehensive Guide to API Gateways, Kubernetes Gateways, and Service Meshes[1]。

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

簡介

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

API 網關

API 網關是一個連接客戶端和 API 的中介,它接收所有客戶端請求,將它們轉發到所需的 API,並將響應返回給客戶端。

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

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

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

雲平臺如 GCP[7],AWS[8] 和 Azure[9] 也有其自己的專有 API 網關。

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

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

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

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

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[11] 和 Gateway API[12]。

Kubernetes 網關

Kubernetes Ingress API

Ingress API 的創建是爲了克服默認服務類型(NodePort[13] 和 LoadBalancer[14])的限制,引入了路由和 SSL 終止等功能。它還標準化瞭如何將 Kubernetes 服務公開給外部流量。

它由 Ingress[15] 和 Ingress 控制器 [16] 兩個組件組成。

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 控制器實現 [17]。APISIX 有一個 Ingress 控制器 [18],它包裝在 APISIX API 網關周圍,作爲 Kubernetes Ingress 工作。

APISIX Ingress

APISIX Ingress 控制器將 Kubernetes Ingress 對象轉換爲 APISIX 配置。

APISIX Ingress 控制器翻譯配置

然後,APISIX 實現此配置。

使用 Kubernetes Ingress API 的金絲雀發佈

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

以下示例顯示瞭如何使用 Nginx Ingress[19] 配置金絲雀部署。此處使用的 自定義註釋 [20] 是特定於 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[21] 配置金絲雀部署:

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 標頭的匹配、加權流量拆分和其他功能 [22],這些功能需要使用 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 進行了許多改進 [23],但它仍處於 alpha 階段,Gateway API 實現經常會出現問題。

服務網格

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

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

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

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

服務網格

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

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

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

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

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

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

Apache APISIX 也有一個名爲 Amesh[30] 的服務網格實現。它與 Istio 的控制平面一起使用 xDS 協議,替換 Sidecar 中的默認 Envoy 代理。

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

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

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

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 的。要切換到不同的服務網格,您必須創建一個不同但類似於供應商依賴的配置。

服務網格接口 [32](SMI)規範是爲解決此可移植性問題而創建的。

SMI 規範 [33] 是一組 Kubernetes CRD,服務網格用戶可以使用它來定義應用程序,而無需綁定到服務網格實現。

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

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

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

Gateway API 是 Ingress API 的自然下一步,但我們必須等待看看它如何適用於服務網格。Istio 已宣佈 [37] 其打算將 Gateway API 用作所有流量管理的默認 API,並繼續推動該項目的發展。

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

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

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

但是,Gateway API 項目是標準化服務網格流量管理的最佳嘗試。SMI 項目也加入了 GAMMA 倡議 [42],具有共享願景,並將幫助倡導服務網格項目對 Gateway API 的一致實現。

其他項目,例如 Flagger[43] 和 Argo Rollouts[44] 也已與 Gateway API 集成。

應該使用什麼?

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

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

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

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

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

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

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

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

另請參閱

引用鏈接

[1] A Comprehensive Guide to API Gateways, Kubernetes Gateways, and Service Meshes: https://navendu.me/posts/gateway-and-mesh/
[2] Apache APISIX: https://github.com/apache/apisix
[3] Gloo Edge: https://github.com/solo-io/gloo
[4] Kong: https://github.com/kong/kong
[5] Tyk: https://github.com/TykTechnologies/tyk
[6] Envoy Gateway: https://github.com/envoyproxy/gateway
[7] GCP: https://cloud.google.com/api-gateway
[8] AWS: https://aws.amazon.com/api-gateway/
[9] Azure: https://learn.microsoft.com/en-us/azure/api-management/
[10] APISIX 管理 API: https://apisix.apache.org/docs/apisix/admin-api/
[11] Ingress API: https://kubernetes.io/docs/concepts/services-networking/ingress/
[12] Gateway API: https://gateway-api.sigs.k8s.io/
[13] NodePort: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
[14] LoadBalancer: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer
[15] Ingress: https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource
[16] Ingress 控制器: https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
[17] 20 個 Ingress 控制器實現: https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/#additional-controllers
[18] Ingress 控制器: https://apisix.apache.org/docs/ingress-controller/next/getting-started/
[19] Nginx Ingress: https://docs.nginx.com/nginx-ingress-controller/
[20] 自定義註釋: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md#canary
[21] ApisixRoute: https://apisix.apache.org/docs/ingress-controller/concepts/apisix_route/
[22] 其他功能: https://gateway-api.sigs.k8s.io/#gateway-api-concepts
[23] 許多改進: https://navendu.me/posts/gateway-vs-ingress-api/
[24] Istio: https://istio.io/
[25] Envoy proxy: https://www.envoyproxy.io/
[26] Linkerd: https://linkerd.io/
[27] Consul Connect: https://developer.hashicorp.com/consul/docs/connect
[28] eBPF: https://ebpf.io/
[29] Cilium: https://isovalent.com/blog/post/introducing-cilium-mesh/
[30] Amesh: https://github.com/api7/Amesh
[31] 在 Istio 服務網格中配置金絲雀部署: https://istio.io/latest/docs/concepts/traffic-management/
[32] 服務網格接口: https://smi-spec.io/
[33] 規範: https://github.com/servicemeshinterface/smi-spec
[34] 只有少數項目積極參與: https://layer5.io/service-mesh-landscape#smi
[35] Kubernetes SIG Network: https://github.com/kubernetes/community/tree/master/sig-network
[36] GAMMA(網關 API 用於網格管理和監管)倡議: https://gateway-api.sigs.k8s.io/contributing/gamma/
[37] 已宣佈: https://istio.io/latest/blog/2022/gateway-api-beta/
[38] 如何使用 Gateway API 在 Istio 中配置金絲雀部署: https://istio.io/latest/docs/tasks/traffic-management/traffic-shifting/
[39] parentRefs: https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io%2fv1beta1.ParentReference
[40] 一些擔憂: https://thenewstack.io/the-gateway-api-is-in-the-firing-line-of-the-service-mesh-wars/
[41] 自定義 CRD 場景: https://navendu.me/posts/gateway-vs-ingress-api/#custom-crds--ingress-api
[42] SMI 項目也加入了 GAMMA 倡議: https://smi-spec.io/blog/announcing-smi-gateway-api-gamma/
[43] Flagger: https://docs.flagger.app/tutorials/gatewayapi-progressive-delivery
[44] Argo Rollouts: https://github.com/argoproj-labs/rollouts-plugin-trafficrouter-gatewayapi
[45] 不需要微服務: https://blog.frankel.ch/chopping-monolith/
[46] 比較 Kubernetes 網關和 Ingress API: https://navendu.me/posts/gateway-vs-ingress-api/
[47] APISIX Ingress 中的自定義插件: https://navendu.me/posts/custom-plugins-in-apisix-ingress/
[48] Kubernetes Gateway API 和 APISIX Ingress: https://navendu.me/posts/kubernetes-gateway-with-apisix/

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/odS5Jci2aevwM-S-0baYkQ