L'API Gateway est l'API de routage et d'équilibrage de charge de nouvelle génération pour Kubernetes. Cette rubrique explique comment configurer des routes HTTP, modifier les en-têtes de requête et distribuer les requêtes selon un poids au sein d'un cluster ACK Edge à l'aide du composant Gateway with Inference Extension.
Fonctionnement
Le composant Gateway with Inference Extension repose sur le projet Envoy Gateway et prend en charge toutes les fonctionnalités de base de l'API Gateway ainsi que les ressources d'extension Envoy Gateway.
L'architecture d'Envoy Gateway comprend :
Plan de contrôle : Le plan de contrôle est constitué du composant Envoy Gateway. Il écoute les règles de trafic au sein du cluster, crée et gère dynamiquement les instances de proxy Envoy, et met à jour les règles de transfert en temps réel. Le plan de contrôle ne transfère pas directement le trafic des services.
Plan de données : Le plan de données est constitué des instances de proxy Envoy. Il traite et transfère le trafic des services.
Dans un cluster ACK Edge, la méthode de déploiement d'Envoy Gateway diffère de celle d'un cluster ACK standard :
|
Différences |
ACK standard |
ACK Edge |
|
Méthode d'exposition du service |
LoadBalancer |
NodePort |
|
Déploiement du plan de contrôle |
Niveau du cluster |
Un ensemble déployé par pool de nœuds |
|
Déploiement du plan de données |
Niveau du cluster |
Déployé par pool de nœuds |
|
Plusieurs pools de nœuds |
Partagent une seule passerelle |
Une passerelle distincte doit être créée pour chaque pool de nœuds |
|
Topologie du service |
Aucune configuration requise |
Nécessite l'annotation |
Le déploiement actuel est configuré avec une politique de distribution par pool de nœuds. Vous pouvez ajuster le nombre de réplicas dans la gestion des composants afin de garantir qu'au moins un réplica du plan de contrôle s'exécute dans chaque pool de nœuds.


Prérequis
Vous avez créé un cluster de version 1.30 ou ultérieure.
Le composant Gateway with Inference Extension est installé.
Préparatifs
Étape 1 : Créer une application de test
Enregistrez l'exemple ci-dessous sous le nom backend.yaml et exécutez la commande kubectl apply -f backend.yaml pour créer les applications de test : backend et backend-2.
Pour les scénarios ACK Edge, vous devez configurer la topologie du service. Ajoutez l'annotationopenyurt.io/topologyKeys: openyurt.io/nodepoolau Service afin de garantir que le trafic soit transféré uniquement vers les pods situés dans le même pool de nœuds. Pour plus d'informations, consultez la rubrique Topologie du service pour les pools de nœuds.
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend
---
apiVersion: v1
kind: Service
metadata:
name: backend
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool # Configure the node pool topology
labels:
app: backend
service: backend
spec:
ports:
- name: http
port: 3000
targetPort: 3000
selector:
app: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 1
selector:
matchLabels:
app: backend
version: v1
template:
metadata:
labels:
app: backend
version: v1
spec:
serviceAccountName: backend
containers:
- image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/envoygateway-echo-basic:v20231214-v1.0.0-140-gf544a46e
imagePullPolicy: IfNotPresent
name: backend
ports:
- containerPort: 3000
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend-2
---
apiVersion: v1
kind: Service
metadata:
name: backend-2
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool # Configure the node pool topology
labels:
app: backend-2
service: backend-2
spec:
ports:
- name: http
port: 3000
targetPort: 3000
selector:
app: backend-2
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-2
spec:
replicas: 1
selector:
matchLabels:
app: backend-2
version: v1
template:
metadata:
labels:
app: backend-2
version: v1
spec:
serviceAccountName: backend-2
containers:
- image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/envoygateway-echo-basic:v20231214-v1.0.0-140-gf544a46e
imagePullPolicy: IfNotPresent
name: backend-2
ports:
- containerPort: 3000
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
Étape 2 : Confirmer la GatewayClass
Après avoir installé le composant Gateway with Inference Extension, une GatewayClass est créée par défaut. Exécutez la commande suivante pour le confirmer :
kubectl get gatewayclass
Résultat attendu :
NAME CONTROLLER ACCEPTED AGE
ack-gateway gateway.envoyproxy.io/gatewayclass-controller True 2m31s
Si la ressource GatewayClass est introuvable, vous pouvez la créer manuellement. Enregistrez l'exemple ci-dessous sous le nom gatewayclass.yaml et exécutez la commande kubectl apply -f gatewayclass.yaml pour la créer.
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: ack-gateway
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
Étape 3 : Créer une configuration EnvoyProxy personnalisée
Dans un cluster ACK Edge, vous pouvez créer une configuration EnvoyProxy personnalisée pour chaque pool de nœuds afin de spécifier le pool de nœuds de planification pour les pods du plan de données et la méthode d'exposition du service.
Remplacez NPXXX dans l'exemple suivant par votre ID de pool de nœuds réel. Ensuite, enregistrez la configuration sous le nom gateway-config.yaml et exécutez la commande kubectl apply -f gateway-config.yaml.
Vous pouvez trouver l'ID du pool de nœuds sur la page Node Management > Node Pools de la console ACK.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
spec:
provider:
type: Kubernetes
kubernetes:
envoyDeployment:
pod:
nodeSelector:
alibabacloud.com/nodepool-id: NPXXX # Replace with your actual node pool ID
envoyService:
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool # Configure the service topology
type: NodePort # ACK Edge uses NodePort to expose services
Cette configuration inclut trois paramètres clés pour les scénarios ACK Edge :
|
Élément de configuration |
Description |
|
|
Planifie les pods du plan de données de la passerelle vers le pool de nœuds spécifié |
|
Annotation |
Configure la topologie du service pour garantir que le trafic reste dans le pool de nœuds |
|
|
Utilise NodePort pour exposer le service. LoadBalancer n'est pas utilisé dans les scénarios edge. |
Étape 4 : Créer la ressource Gateway
Enregistrez l'exemple ci-dessous sous le nom gateway.yaml et exécutez la commande kubectl apply -f gateway.yaml.
Le plan de contrôle du composant crée automatiquement un déploiement EnvoyProxy et un service NodePort basés sur la ressource Gateway. Il démarre également un écouteur sur le port spécifié sur le nœud.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: ack-gateway
spec:
gatewayClassName: ack-gateway
listeners:
- name: http
protocol: HTTP
port: 80
infrastructure:
parametersRef:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config # Associate with the custom configuration created in Step 3
Étape 5 : Obtenir le point de terminaison de la passerelle
Le service de passerelle est exposé en tant que NodePort. Le point de terminaison du service correspondant est l'adresse IP de n'importe quel nœud du pool de nœuds et son port de service.
-
Interrogez le port du service.
kubectl get service -n kube-system -l gateway.envoyproxy.io/owning-gateway-name=ack-gatewayRésultat attendu :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE envoy-default-ack-gateway-7452df7d NodePort 192.168.86.174 <none> 80:30364/TCP 19m Définissez la variable d'environnement de l'hôte de la passerelle. Remplacez
NODEIPpar l'adresse IP de n'importe quel nœud du pool de nœuds etNODEPORTpar le numéro de port obtenu à l'étape précédente.export GATEWAY_HOST=NODEIP:NODEPORT
Configurer le routage HTTP basé sur la correspondance du préfixe de chemin
Le fichier YAML d'exemple suivant permet de créer une HTTPRoute qui correspond au préfixe /get.
-
Créez une HTTPRoute. Enregistrez le contenu YAML suivant sous le nom
httproute.yaml. Ensuite, exécutez la commandekubectl apply -f httproute.yamlpour l'appliquer.apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: ack-gateway hostnames: - "www.example.com" rules: - backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 1 matches: - path: type: PathPrefix value: /get -
Accédez à l'application.
curl -H "Host: www.example.com" http://$GATEWAY_HOST/getRésultat attendu :
{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "User-Agent": [ "curl/8.9.1" ], "X-Envoy-External-Address": [ "115.XX.XXX.55" ], "X-Forwarded-For": [ "115.XX.XXX.55" ], "X-Forwarded-Proto": [ "http" ], "X-Request-Id": [ "953b2f8f-26d3-4ba9-93ba-a482b197b1ff" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }
Ajouter un en-tête de requête
Mettez à jour la HTTPRoute en ajoutant un en-tête à la requête.
-
Mettez à jour la ressource
HTTPRoute. Enregistrez le contenu YAML suivant sous le nomhttproute.yaml. Ensuite, exécutez la commandekubectl apply -f httproute.yamlpour l'appliquer.apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: ack-gateway hostnames: - "www.example.com" rules: - matches: - path: type: PathPrefix value: /get backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 1 filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: "added-header" value: "foo" -
Accédez à l'application.
curl -H "Host: www.example.com" http://$GATEWAY_HOST/getRésultat attendu :
{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "Added-Header": [ "foo" ], "User-Agent": [ "curl/8.9.1" ], "X-Envoy-External-Address": [ "115.XX.XXX.55" ], "X-Forwarded-For": [ "115.XX.XXX.55" ], "X-Forwarded-Proto": [ "http" ], "X-Request-Id": [ "d37f19e5-25c1-45cf-90e5-51453e7ae3ed" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }%Étant donné que l'application exemple renvoie les informations de la requête dans sa réponse, vous devriez voir
added-headerdans le résultat. Cela confirme que l'opération a réussi.
Configurer la répartition proportionnelle du trafic
Mettez à jour la HTTPRoute en vous basant sur le modèle YAML suivant. Dans ce modèle, des règles de routage pour le service backend-2 sont ajoutées et des poids de trafic sont spécifiés pour les services backend et backend-2.
La somme des poids que vous spécifiez dans le paramètre backendRefs n'a pas besoin d'être égale à 100. Proportion du trafic routé vers un service =
-
Mettez à jour la HTTPRoute. Enregistrez le contenu YAML suivant sous le nom
httproute.yaml. Ensuite, exécutez la commandekubectl apply -f httproute.yamlpour l'appliquer.apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: ack-gateway hostnames: - "www.example.com" rules: - matches: - path: type: PathPrefix value: /get backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 8 - group: "" kind: Service name: backend-2 port: 3000 weight: 2 -
Accédez à l'application 20 fois, puis vérifiez le ratio de trafic réel entre les deux services.
La commande suivante envoie 20 requêtes et traite le résultat pour afficher uniquement le service backend (
backendoubackend-2) qui a traité chaque requête.for i in $(seq 1 20); do curl -sS -H "Host: www.example.com" http://$GATEWAY_HOST/get |grep backend; done | \ sed -E 's/".*"(backend(-2)?)-[0-9a-zA-Z]*-.*/\1/'Résultat attendu :
backend-2 backend backend backend backend backend backend backend backend backend backend backend-2 backend-2 backend backend backend-2 backend backend backend backendLe résultat montre qu'environ 80 % des requêtes sont transférées vers le service
backendet les 20 % restants vers le servicebackend-2.