Un bref aperçu de l'API Kubernetes Gateway
September 7, 2022
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
- 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.
La définition ci-dessus mentionne également une préoccupation organisationnelle : différents rôles devraient gérer un ensemble différent d'objets.
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
- Sans l'option
--devel
, Helm installe la version la plus récente, qui ne fonctionne pas avec l'API Gateway - La Gateway doit être accessible depuis l'extérieur du cluster de toute façon
- La magie opère ici !
- 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
- Apache APISIX lui-même
- 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 - Contrôleur Apache APISIX : un contrôleur Kubernetes est une boucle de contrôle qui fait évoluer l'état existant vers l'état souhaité
- 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
- Nous n'utilisons pas la dernière version à dessein, car Apache APISIX utilise cette version. Soyez conscient qu'elle évoluera dans un avenir (proche)
- Objet
GatewayClass
- Nommez-le comme vous voulez ; cependant, nous l'utiliserons plus tard pour référencer la classe de gateway
- 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
- Même espace de noms que ci-dessus
- Objet
Gateway
- Référencez la classe de gateway déclarée précédemment
- 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
- Même espace de noms que ci-dessus
- Objet
HTTPRoute
- Référencez la
Gateway
créée ci-dessus - 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.
- 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 :