Une comparaison approfondie des API Gateways, Kubernetes Gateways et Service Meshes

Navendu Pottekkat

Navendu Pottekkat

June 9, 2023

Technology

Il existe encore beaucoup de confusion autour des API gateways, des Kubernetes gateways et des service meshes. Une grande partie de cette confusion provient des raisons suivantes :

  1. Les gens mentionnent souvent ces technologies avec les mêmes mots-clés, comme les déploiements canaris, la limitation de débit et la découverte de services.
  2. Toutes ces technologies utilisent des reverse proxies.
  3. Certains API gateways ont leurs propres Kubernetes gateways et service meshes, et vice versa.
  4. Il existe de nombreux articles/vidéos qui comparent ces trois technologies et concluent pourquoi l'une est meilleure que l'autre.

Dans cet article, je vais essayer d'expliquer ces technologies et de partager en quoi elles diffèrent fondamentalement et répondent à des cas d'utilisation différents.

API Gateways

Un API gateway se situe entre vos applications clientes et vos APIs. Il accepte toutes les requêtes des clients, les transmet aux APIs nécessaires et renvoie la réponse aux clients dans un package combiné.

Il s'agit essentiellement d'un reverse proxy avec de nombreuses fonctionnalités.

API gateway

En plus de cela, un API gateway peut également avoir des fonctionnalités comme l'authentification, la sécurité, le contrôle fin du trafic et la surveillance, permettant aux développeurs d'API de se concentrer uniquement sur les besoins métier.

Il existe de nombreuses solutions d'API gateway disponibles. Parmi les solutions populaires gratuites et open source, on trouve :

  • Apache APISIX : Un API gateway haute performance, extensible et cloud native, construit sur Nginx.
  • Gloo Edge : Un API gateway construit sur le proxy Envoy.
  • Kong : Un API gateway pluggable également construit sur Nginx.
  • Tyk : Un API gateway écrit en Go prenant en charge les protocoles REST, GraphQL, TCP et gRPC.

Les plateformes cloud comme GCP, AWS et Azure ont également leurs propres API gateways propriétaires.

Les API gateways, les Kubernetes gateways et les service meshes prennent en charge les déploiements canaris — déployer progressivement une nouvelle version de logiciel à un petit sous-ensemble d'utilisateurs avant de la rendre généralement disponible.

L'exemple ci-dessous montre comment configurer un déploiement canari dans Apache APISIX.

Déploiements canaris avec un API gateway

Vous pouvez envoyer une requête à l'API Admin d'APISIX avec la configuration suivante :

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 va maintenant router 95 % du trafic vers le service api-v1 et 5 % vers le service api-v2.

Kubernetes Gateways

Les Kubernetes gateways sont simplement des API gateways natifs de Kubernetes. C'est-à-dire que vous pouvez gérer ces API gateways avec l'API Kubernetes, de la même manière qu'un pod, un service ou un déploiement Kubernetes.

Dans Kubernetes, vos APIs sont des pods et des services déployés dans un cluster. Vous utilisez ensuite un Kubernetes gateway pour diriger le trafic externe vers votre cluster.

Kubernetes fournit deux API pour y parvenir, l'API Ingress et l'API Gateway.

Kubernetes gateway

API Ingress de Kubernetes

L'API Ingress a été créée pour surmonter les limitations des types de services par défaut, NodePort et LoadBalancer, en introduisant des fonctionnalités comme le routage et la terminaison SSL. Elle a également standardisé la manière dont vous exposez les services Kubernetes au trafic externe.

Elle comprend deux composants, l'Ingress et le Ingress controller.

L'objet natif Kubernetes Ingress définit un ensemble de règles sur la manière dont le trafic externe peut accéder à vos services.

Cet exemple de configuration montre le routage du trafic en fonction du chemin URI avec l'objet Kubernetes Ingress :

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

Un Ingress controller implémente ces règles et route le trafic vers votre cluster en utilisant un reverse proxy.

Il existe plus de 20 implémentations d'Ingress controllers. APISIX a un Ingress controller qui encapsule l'API gateway APISIX pour fonctionner comme un Ingress Kubernetes.

APISIX Ingress

Le Ingress controller d'APISIX convertit l'objet Kubernetes Ingress en configuration APISIX.

Le Ingress controller d'APISIX traduit la configuration

APISIX implémente ensuite cette configuration.

Déploiements canaris avec l'API Ingress de Kubernetes

Vous pouvez remplacer APISIX par n'importe quel autre Ingress controller, car l'API Ingress n'est pas liée à une implémentation spécifique.

Cette neutralité vis-à-vis des fournisseurs fonctionne bien pour des configurations simples. Mais si vous souhaitez effectuer un routage complexe comme un déploiement canari, vous devez vous appuyer sur des annotations spécifiques au fournisseur.

L'exemple ci-dessous montre comment configurer un déploiement canari en utilisant Nginx Ingress. Les annotations personnalisées utilisées ici sont spécifiques à 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: /

La configuration ci-dessus routera 5 % du trafic vers le service api-v2.

En plus des annotations, les Ingress controllers comme APISIX ont des CRDs Kubernetes personnalisés pour surmonter les limitations de l'API Ingress.

L'exemple ci-dessous utilise le CRD d'APISIX, ApisixRoute, pour configurer un déploiement canari :

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

Ces CRDs personnalisés ont rendu beaucoup plus facile la configuration de l'Ingress et l'exploitation des capacités complètes de l'API gateway sous-jacent, mais au détriment de la portabilité.

API Gateway de Kubernetes

L'API Gateway est un nouvel objet Kubernetes qui vise à "corriger" l'API Ingress.

Elle s'inspire des CRDs personnalisés développés par les Ingress controllers pour ajouter des fonctionnalités comme la correspondance basée sur les en-têtes HTTP, la répartition pondérée du trafic et d'autres fonctionnalités qui nécessitent des annotations propriétaires personnalisées avec l'API Ingress.

L'exemple ci-dessous montre la configuration d'un déploiement canari avec l'API Gateway de Kubernetes :

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

Tout Ingress controller (qui implémente l'API Gateway) peut maintenant implémenter cette configuration.

L'API Gateway apporte également de nombreuses améliorations par rapport à l'API Ingress, mais elle est encore en alpha, et les implémentations de l'API Gateway sont en constante évolution.

Service Meshes

Les API gateways et les Kubernetes gateways fonctionnent à travers les limites des applications, résolvant les problèmes de bordure tout en abstraisant vos APIs.

Les Service Meshes résolvent un défi différent.

Un service mesh se préoccupe davantage de la communication inter-services (trafic est-ouest) que de la communication service-client (trafic nord-sud).

Typiquement, cela est réalisé en déployant des proxies sidecar avec les APIs/services.

Service mesh

Ici, les proxies sidecar gèrent la communication service-à-service au lieu que le développeur doive coder la logique de réseau dans les services.

Il existe de nombreux service meshes disponibles. Parmi les plus populaires, on trouve :

  • Istio : De loin le service mesh le plus populaire. Il est construit sur le proxy Envoy, que de nombreux service meshes utilisent.
  • Linkerd : Un service mesh léger qui utilise linkerd2-proxy, écrit en Rust spécifiquement pour Linkerd.
  • Consul Connect : Un service mesh mettant l'accent sur la sécurité et l'observabilité. Il peut fonctionner soit avec un proxy intégré, soit avec Envoy.

Les nouvelles offres de service mesh comme Cilium proposent des alternatives aux service meshes basés sur des sidecars en utilisant les capacités réseau directement du noyau via eBPF.

Service mesh sans sidecar

Un service mesh typique nécessite 8 proxies pour 8 services, alors que les service meshes basés sur eBPF comme Cilium n'en nécessitent pas. Adapté de Cilium Service Mesh – Everything You Need to Know.

Les service meshes ont également des gateways d'entrée/sortie de base pour gérer le trafic nord-sud vers et depuis les services. Les gateways d'entrée sont les points d'entrée du trafic externe dans un service mesh, et les gateways de sortie permettent aux services à l'intérieur d'un mesh d'accéder à des services externes.

Gateways d'entrée et de sortie avec un service mesh

Apache APISIX a également une implémentation de service mesh appelée Amesh. Elle fonctionne avec le plan de contrôle d'Istio en utilisant le protocole xDS, remplaçant le proxy Envoy par défaut dans le sidecar.

Un service mesh vous permet de configurer des déploiements canaris. Par exemple, vous pouvez diviser les requêtes d'un service entre deux versions d'un autre service.

Déploiements canaris avec un service mesh

L'exemple ci-dessous montre la configuration d'un déploiement canari avec le 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"

Ces configurations sont spécifiques à Istio. Pour passer à un autre service mesh, vous devez créer une configuration différente mais également dépendante du fournisseur.

La spécification Service Mesh Interface (SMI) a été créée pour résoudre ce problème de portabilité.

La spécification SMI spec est un ensemble de CRDs Kubernetes qu'un utilisateur de service mesh peut utiliser pour définir des applications sans se lier à des implémentations de service mesh.

Une tentative de standardisation ne fonctionnera que si tous les projets sont à bord. Mais cela n'a pas été le cas avec la spécification SMI, et seuls quelques projets ont participé activement.

Plus récemment, le SIG Network de Kubernetes a évolué l'API Gateway pour prendre en charge les service meshes.

L'initiative GAMMA (Gateway API for Mesh Management and Administration) est un groupe dédié au projet Gateway API avec pour objectifs d'"enquêter, concevoir et suivre les ressources de l'API Gateway, les sémantiques et autres artefacts liés à la technologie des service meshes et aux cas d'utilisation."

L'API Gateway est une étape naturelle après l'API Ingress, mais nous devons attendre de voir comment elle fonctionnera pour les service meshes. Istio a annoncé son intention d'utiliser l'API Gateway comme API par défaut pour toute la gestion du trafic et continue de faire avancer le projet.

L'exemple ci-dessous montre la configuration d'un déploiement canari dans Istio avec l'API Gateway. L'idée sous-jacente est d'utiliser parentRefs pour s'attacher à d'autres services au lieu de la gateway :

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

Il existe certaines préoccupations que le projet GAMMA pourrait devenir biaisé pour servir les besoins d'un projet particulier plutôt que la communauté au sens large, ce qui finirait par amener d'autres projets à utiliser leurs propres APIs, similairement au scénario des CRDs personnalisés après l'API Ingress de Kubernetes.

Mais le projet Gateway API a été la meilleure tentative de standardisation de la gestion du trafic dans les service meshes. Le projet SMI a également rejoint l'initiative GAMMA avec une vision partagée et aidera à plaider pour des implémentations cohérentes de l'API Gateway par les projets de service mesh.

D'autres projets comme Flagger et Argo Rollouts ont également intégré l'API Gateway.

Que devriez-vous utiliser ?

Il n'y a qu'une seule réponse correcte à cette question : "cela dépend."

Si vous développez des APIs et avez besoin d'authentification, de sécurité, de routage ou de métriques, il est préférable d'utiliser un API gateway plutôt que de construire cela vous-même dans vos APIs.

Si vous souhaitez faire quelque chose de similaire dans un environnement Kubernetes, vous devriez utiliser un Kubernetes gateway plutôt que d'essayer de faire fonctionner votre API gateway sur Kubernetes. Heureusement, de nombreux API gateways fonctionnent également avec des configurations natives de Kubernetes.

Mais parfois, les fonctionnalités offertes par un API gateway + Ingress controller peuvent être excessives pour un environnement Kubernetes, et vous pourriez vouloir revenir à une gestion simple du trafic.

Les service meshes, quant à eux, résolvent un ensemble de problèmes entièrement différent. Ils apportent également leurs propres gateways pour gérer le trafic nord-sud (généralement suffisants) mais vous permettent également d'utiliser vos propres gateways avec plus de fonctionnalités.

La convergence de l'API gateway et du service mesh via l'API Gateway de Kubernetes devrait faciliter la tâche du développeur d'application en se concentrant sur la résolution des problèmes plutôt que sur l'implémentation sous-jacente.

Des projets comme Apache APISIX utilisent la même technologie pour construire les offres d'API gateway et de service mesh et s'intègrent bien avec ces spécifications, encourageant des choix neutres vis-à-vis des fournisseurs.

Il est également probable que vous n'ayez besoin d'aucun de ces éléments. Vous pourriez ne pas même avoir besoin de microservices ou d'une architecture distribuée, mais lorsque vous en avez besoin, les gateways et les meshes peuvent vous faciliter grandement la vie.

Tags: