Gateway API est un projet officiel Kubernetes définissant la nouvelle génération d'API pour les ressources Ingress et l'équilibrage de charge. Cette API permet de configurer les règles de routage du trafic. Cette rubrique explique comment utiliser Gateway with Inference Extension pour mettre en œuvre les fonctionnalités de base de Gateway API.
Contexte
Gateway with Inference Extension s'appuie sur le projet Envoy Gateway. Il offre toutes les fonctionnalités de base de Gateway API ainsi que les extensions open source d'Envoy Gateway.
L'architecture d'Envoy Gateway comprend les composants suivants :
Plan de contrôle : constitué des composants Envoy Gateway, il surveille les règles de routage du cluster et gère dynamiquement la création des instances de proxy Envoy. Il met à jour les règles de transfert de ces instances sans participer directement au transfert du trafic.
Plan de données : composé des instances de proxy Envoy en cours d'exécution, il assure le traitement et le transfert efficaces et fiables du trafic.
Prérequis
Vous avez créé un cluster géré Container Service for Kubernetes (ACK) exécutant Kubernetes 1.30 ou version ultérieure. Pour plus d'informations sur la mise à niveau d'un cluster, consultez Mettre à niveau manuellement un cluster.
Vous avez créé un cluster Container Compute Service (ACS) exécutant Kubernetes 1.30 ou version ultérieure.
Gateway with Inference ExtensionGateway with Inference Extension est installé dans le cluster.
Préparatifs
-
Créez deux applications :
backendetbackend-2.RemarqueAprès avoir créé l'application backend, modifiez son fichier YAML en remplaçant
parbackend-2, puis utilisez ce fichier modifié pour créer l'application backend-2.apiVersion: v1 kind: ServiceAccount metadata: name: backend --- apiVersion: v1 kind: Service metadata: name: backend 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 -
Créez une GatewayClass et définissez
controllerNamesurgateway.envoyproxy.io/gatewayclass-controller.apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: eg spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller -
Créez une passerelle (Gateway).
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: eg spec: gatewayClassName: eg listeners: - name: http protocol: HTTP port: 80Une fois la passerelle créée, le plan de contrôle de Gateway with Inference Extension utilise automatiquement sa configuration pour déployer un déploiement EnvoyProxy ainsi qu'un Service LoadBalancing correspondant, en écoute sur le port spécifié. Pour plus d'informations sur les règles de facturation des instances Server Load Balancer (SLB), consultez Facturation SLB.
Vous pouvez personnaliser la configuration du déploiement EnvoyProxy et ajuster les paramètres du Service. Vous pouvez également activer la mise à l'échelle automatique horizontale des pods pour la passerelle.
-
Récupérez l'adresse IP de la passerelle.
export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
Configurer le routage HTTP par correspondance de préfixe de chemin
Le fichier YAML d'exemple ci-dessous crée une ressource HTTPRoute correspondant au préfixe /get.
-
Créez une HTTPRoute.
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: eg 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 ressource HTTPRoute pour ajouter un en-tête à la requête.
-
Mettez à jour la HTTPRoute.
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: eg 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" }%Cette application renvoie le contenu de la requête reçue. La présence de l'en-tête ajouté dans la sortie confirme la réussite de l'opération.
Configurer la répartition proportionnelle du trafic
Mettez à jour la ressource HTTPRoute en suivant le modèle YAML ci-dessous. Ce modèle ajoute des règles de routage vers le Service backend-2 et définit des poids de trafic pour les Services backend et backend-2.
La somme des poids indiqués dans le paramètre backendRefs n'a pas besoin d'être égale à 100. La proportion de trafic dirigée vers un Service correspond à
-
Mettez à jour la HTTPRoute.
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: eg 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 -
Envoyez 20 requêtes à l'application, puis vérifiez la répartition effective du trafic entre les deux Services.
RemarqueLa commande suivante filtre la sortie pour n'afficher que
backendetbackend-2.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 backendCe résultat montre qu'environ 80 % des requêtes sont dirigées vers le Service backend, tandis que les 20 % restants vont au Service backend-2.
Traiter le trafic TLS
Mettez à jour la passerelle en y ajoutant un certificat et un écouteur TLS.
-
Générez un certificat et utilisez-le pour créer un Secret.
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization" openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt kubectl create secret tls example-cert --key=www.example.com.key --cert=www.example.com.crt -
Ajoutez un écouteur TLS ainsi que le certificat créé à l'étape précédente.
kubectl patch gateway eg --type=json --patch ' - op: add path: /spec/listeners/- value: name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret group: "" name: example-cert ' -
Vérifiez que la modification a bien été appliquée.
kubectl get gateway/eg -o yaml | grep spec: -A 20Résultat attendu :
spec: gatewayClassName: eg listeners: - allowedRoutes: namespaces: from: Same name: http port: 80 protocol: HTTP - allowedRoutes: namespaces: from: Same name: https port: 443 protocol: HTTPS tls: certificateRefs: - group: "" kind: Secret name: example-cert mode: Terminate status:La sortie confirme la réussite de la modification.
-
Accédez à l'application.
curl -H Host:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ --cacert example.com.crt https://www.example.com/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": [ "https" ], "X-Request-Id": [ "ac539756-3826-474b-be2f-5e57fdd49dac" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }