Un bref aperçu de l'API Kubernetes Gateway

Nicolas Fränkel

Nicolas Fränkel

September 7, 2022

Ecosystem

Dans un de mes récents articles de blog, j'ai décrit plusieurs façons d'accéder aux pods Kubernetes. On peut accéder à un pod via son IP, mais les pods sont naturellement éphémères. La manière nominale est de configurer un Service : son IP est stable, et le travail de Kubernetes est de maintenir à jour la correspondance entre un Service et les pods sous-jacents. Différents types de services sont disponibles : internes uniquement, NodePort pour permettre finalement l'accès depuis l'extérieur du cluster, et LoadBalancer qui repose sur un composant tiers - en général, un fournisseur de cloud. Enfin, j'ai mentionné l'objet Ingress, qui permet également le routage.

J'ai délibérément laissé de côté le nouveau venu, l'API Gateway. C'est le sujet de cet article.

De l'Ingress à l'API Gateway

L'accès externe aux pods Kubernetes a traversé plusieurs étapes évolutives, par exemple, Ingress est la réponse au problème du manque de routage dans LoadBalancer. Le plus gros problème de Ingress est sa dépendance à des objets "propriétaires". Pour rappel, voici l'extrait pour créer un routage en utilisant Apache APISIX :

apiVersion: apisix.apache.org/v2beta3 #1
kind: ApisixRoute #1
metadata:
  name: apisix-route
spec:
  http:
    - name: left
      match:
        paths:
          - "/left"
      backends:
        - serviceName: left
          servicePort: 80
    - name: right
      match:
        paths:
          - "/right"
      backends:
        - serviceName: right
          servicePort: 80
  1. Objets propriétaires

Les objets propriétaires posent problème lors de la migration. Bien que la migration d'un fournisseur à un autre soit probablement rare, elle devrait être aussi transparente que possible. Lorsque vous utilisez des objets propriétaires, vous devez d'abord mapper les anciens objets aux nouveaux. Il est probable que ce ne soit pas une correspondance un à un. Ensuite, vous devez traduire la spécification dans le nouveau modèle : cela risque d'être un projet à part entière.

L'idée derrière l'API Gateway est d'avoir une séparation claire entre les objets standard et l'implémentation propriétaire.

L'API Gateway

L'API Gateway est un projet open source géré par la communauté SIG-NETWORK. C'est une collection de ressources qui modélisent le réseau de services dans Kubernetes. Ces ressources - GatewayClass, Gateway, HTTPRoute, TCPRoute, Service, etc - visent à faire évoluer le réseau de services Kubernetes grâce à des interfaces expressives, extensibles et orientées rôle qui sont implémentées par de nombreux fournisseurs et bénéficient d'un large soutien de l'industrie.

-- https://gateway-api.sigs.k8s.io

La définition ci-dessus mentionne également une préoccupation organisationnelle : différents rôles devraient gérer un ensemble différent d'objets.

Modèle de l'API Gateway

Image de gateway-api.sigs.k8s.io

En effet, les préoccupations d'un opérateur de cluster et d'un développeur sont assez différentes. C'est assez similaire aux anciens serveurs d'applications Java EE, qui offraient une spécification organisée autour des rôles : développeurs, déployeurs et opérateurs. À mon avis, la plus grande différence est que la spécification était principalement axée sur l'expérience du développeur ; le reste était à la charge des implémenteurs. L'API Gateway semble se soucier de tous les profils.

Configurer l'accès aux pods via l'API Gateway

Remplaçons l'Ingress que nous avons configuré précédemment par l'API Gateway. Plusieurs étapes sont nécessaires.

Installer les nouvelles CRDs de Gateway

k apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.5.0/standard-install.yaml

Installer une implémentation

J'utiliserai Apache APISIX. Alternativement, le site SIG maintient une liste d'implémentations.

helm install apisix apisix/apisix \
  --namespace ingress-apisix \
  --create-namespace \
  --devel \                                                                #1
  --set gateway.type=NodePort \                                            #2
  --set gateway.http.nodePort=30800 \                                      #2
  --set ingress-controller.enabled=true \                                  #2
  --set ingress-controller.config.kubernetes.enableApiGateway=true \       #3
  --set ingressPublishService="ingress-apisix/apisix-gateway"              #4
  1. Sans l'option --devel, Helm installe la version la plus récente, qui ne fonctionne pas avec l'API Gateway
  2. La Gateway doit être accessible depuis l'extérieur du cluster de toute façon
  3. La magie opère ici !
  4. J'y reviendrai plus tard

Vérifions que tout fonctionne :

k get all -n ingress-apisix
NAME                                             READY   STATUS    RESTARTS   AGE
pod/apisix-5fc9b45c69-cf42m                      1/1     Running   0          14m    #1
pod/apisix-etcd-0                                1/1     Running   0          14m    #2
pod/apisix-etcd-1                                1/1     Running   0          14m    #2
pod/apisix-etcd-2                                1/1     Running   0          14m    #2
pod/apisix-ingress-controller-6f8bd94d9d-wkzfn   1/1     Running   0          14m    #3

NAME                                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)
service/apisix-admin                ClusterIP   10.96.69.19     <none>        9180/TCP
service/apisix-etcd                 ClusterIP   10.96.226.79    <none>        2379/TCP,2380/TCP
service/apisix-etcd-headless        ClusterIP   None            <none>        2379/TCP,2380/TCP
service/apisix-gateway              NodePort    10.96.101.224   <none>        80:30800/TCP #4
service/apisix-ingress-controller   ClusterIP   10.96.141.230   <none>        80/TCP
  1. Apache APISIX lui-même
  2. Apache APISIX stocke sa configuration dans etcd. Le chart planifie trois pods par défaut, une bonne pratique pour gérer les pannes dans les systèmes distribués
  3. Contrôleur Apache APISIX : un contrôleur Kubernetes est une boucle de contrôle qui fait évoluer l'état existant vers l'état souhaité
  4. Service Gateway Apache APISIX : c'est le Service NodePort que nous avons installé via le Helm Chart. C'est aussi le nom que nous avons référencé lors de l'installation du Helm Chart - ingressPublishService

À ce stade, l'infrastructure est prête.

Déclarer l'implémentation de la Gateway

Comme mentionné ci-dessus, l'API fait une séparation claire entre la spécification et l'implémentation. Cependant, nous devons la lier d'une manière ou d'une autre. C'est la responsabilité de l'objet GatewayClass :

apiVersion: gateway.networking.k8s.io/v1alpha2 #1
kind: GatewayClass #2
metadata:
  name: apisix-gateway-class #3
spec:
  controllerName: apisix.apache.org/gateway-controller #4
  1. Nous n'utilisons pas la dernière version à dessein, car Apache APISIX utilise cette version. Soyez conscient qu'elle évoluera dans un avenir (proche)
  2. Objet GatewayClass
  3. Nommez-le comme vous voulez ; cependant, nous l'utiliserons plus tard pour référencer la classe de gateway
  4. Le nom du contrôleur dépend de l'implémentation. Ici, nous utilisons celui d'Apache APISIX.

Notez que le GatewayClass a une portée à l'échelle du cluster. Ce modèle nous permet de déclarer différentes implémentations de l'API Gateway et de les utiliser en parallèle dans le même cluster.

Créer la Gateway

Avec Apache APISIX, c'est assez simple :

apiVersion: gateway.networking.k8s.io/v1alpha2 #1
kind: Gateway #2
metadata:
  name: apisix-gateway
spec:
  gatewayClassName: apisix-gateway-class #3
  listeners: #4
    - name: http
      protocol: HTTP
      port: 80
  1. Même espace de noms que ci-dessus
  2. Objet Gateway
  3. Référencez la classe de gateway déclarée précédemment
  4. Permet certaines restrictions à ce niveau afin que l'opérateur de cluster puisse éviter les utilisations non souhaitées

Attention : L'API Gateway spécifie l'option de changer dynamiquement le port côté opérateur. Au moment de la rédaction, l'allocation de port d'Apache APISIX est statique. Le plan est de la rendre dynamique à l'avenir. Veuillez suivre cette issue GitHub pour suivre les progrès.

Routes, routes, routes partout

Jusqu'à présent, tout était infrastructure ; nous pouvons enfin configurer le routage.

Je veux le même routage que dans l'article précédent ; une branche /left et une right. Je vais sauter la dernière par souci de concision.

apiVersion: gateway.networking.k8s.io/v1alpha2 #1
kind: HTTPRoute #2
metadata:
  name: left
spec:
  parentRefs:
    - name: apisix-gateway #3
  rules:
    - matches: #4
        - path: #4
            type: PathPrefix #4
            value: /left
      backendRefs: #5
        - name: left #5
          port: 80 #5
  1. Même espace de noms que ci-dessus
  2. Objet HTTPRoute
  3. Référencez la Gateway créée ci-dessus
  4. Règles de correspondance. Dans notre cas, nous correspondons à un préfixe de chemin, mais de nombreuses règles sont disponibles. Vous pouvez correspondre en fonction d'un paramètre de requête, d'un en-tête, etc.
  5. Le "upstream" vers lequel rediriger. Nous avons défini le Service left dans l'article de blog précédent.

Vérifier que cela fonctionne

Maintenant que nous avons configuré nos routes, nous pouvons vérifier que cela fonctionne.

curl localhost:30800/left

Lorsque nous avons installé le chart Helm, nous avons dit à Apache APISIX de créer un service NodePort sur le port 30800. Par conséquent, nous pouvons utiliser ce port pour accéder au service depuis l'extérieur du cluster.

left

Conclusion

De nombreuses alternatives sont disponibles pour accéder à un pod depuis l'extérieur du cluster. La CNCF en a ajouté la plupart pour améliorer la précédente.

L'API Gateway est la dernière proposition à cet égard. La spécification est un travail en cours et les produits sont à différents stades d'implémentation. Pour cette raison, il est trop tôt pour baser votre production sur cette API. Cependant, vous devriez probablement suivre les progrès car elle est destinée à être une amélioration considérable par rapport aux approches précédentes.

Le code source complet de cet article peut être trouvé sur GitHub.

Pour aller plus loin :

Tags: