Cette rubrique explique comment utiliser la Gateway API avec un Application Load Balancer (ALB) pour exposer les services d'un cluster au trafic externe.
Contexte
La Gateway API regroupe un ensemble de ressources Kubernetes destinées à modéliser le trafic réseau des services. Son objectif est de créer un modèle de mise en réseau des services expressif, extensible et orienté rôles.
L'ALB Ingress Controller prend en charge la Gateway API depuis la version 2.17.0. Vous pouvez installer l'ALB Ingress Controller pour exposer des services via un ALB en utilisant la Gateway API.
Prérequis
Vous avez créé un cluster géré ACK exécutant Kubernetes 1.24 ou une version ultérieure.
Vous avez installé l'ALB Ingress Controller version 2.17 ou ultérieure dans le cluster.
Vous avez installé la Gateway API version 1.1.0 ou ultérieure dans le cluster.
Vous avez créé deux vSwitches compatibles avec ALB dans le Virtual Private Cloud (VPC) du cluster.
Vérifier l'environnement
Si votre cluster satisfait aux prérequis, une ressource GatewayClass nommée alb est automatiquement créée. Procédez comme suit pour le vérifier.
Console
Connectez-vous à la console ACK. Dans le volet de navigation de gauche, cliquez sur Clusters.
Sur la page Clusters, cliquez sur le nom de votre cluster. Dans le volet de navigation de gauche, cliquez sur .
-
Cliquez sur gateway.networking.k8s.io et consultez la section GatewayClass sous v1.
Vérifiez qu'une instance GatewayClass nommée alb existe bien.
Console
Connectez-vous à la console ACS. Dans le volet de navigation de gauche, cliquez sur Clusters.
Sur la page Clusters, cliquez sur le nom du cluster cible. Dans le volet de navigation de gauche, choisissez Workloads > Custom Resources.
-
Cliquez sur gateway.networking.k8s.io et consultez la section GatewayClass sous v1.
Vérifiez qu'une instance GatewayClass nommée alb existe bien.
kubectl
kubectl get gatewayclass
Résultat attendu :
NAME CONTROLLER ACCEPTED AGE
alb gateways.alibabacloud.com/alb/v1 True 1m
Déployer une application exemple
-
Créez un fichier nommé httpbin.yaml.
RemarquePar défaut, le Service de l'application présentée dans cette rubrique utilise le type
ClusterIP. Si le type de réseau de votre cluster est Flannel, remplacez la valeurspec.typedu Service parNodePort.apiVersion: apps/v1 kind: Deployment metadata: name: go-httpbin namespace: default spec: replicas: 1 selector: matchLabels: app: go-httpbin template: metadata: labels: app: go-httpbin version: v1 spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/mse/go-httpbin args: - "--port=8090" - "--version=v1" imagePullPolicy: Always name: go-httpbin ports: - containerPort: 8090 --- apiVersion: v1 kind: Service metadata: name: go-httpbin namespace: default spec: type: ClusterIP ports: - port: 80 targetPort: 8090 protocol: TCP selector: app: go-httpbin -
Déployez l'application.
kubectl apply -f httpbin.yaml
Déployer la passerelle et les routes
Cette opération crée une instance ALB dans le cloud, ce qui entraîne des frais. Une instance ALB créée par une passerelle (Gateway) n'est pas supprimée automatiquement avec le cluster. Pour éviter tout coût inattendu, supprimez les ressources Gateway de votre cluster avant de supprimer ce dernier.
-
Créez un fichier nommé gateway.yaml.
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: alb namespace: default spec: gatewayClassName: alb listeners: - name: http protocol: HTTP port: 80 hostname: "*.ingress.top" allowedRoutes: namespaces: from: Same --- apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: demo-route spec: parentRefs: # Reference the Gateway resource. - group: gateway.networking.k8s.io kind: Gateway name: alb hostnames: - demo.ingress.top # Set the hostname to demo.ingress.top. rules: - matches: # The matching rule is a path prefix match. - path: type: PathPrefix value: / backendRefs: # The backend is a Service named go-httpbin on port 80. - kind: Service name: go-httpbin port: 80 -
Déployez la passerelle ainsi que les règles de routage.
kubectl apply -f gateway.yaml -
Patientez environ 2 minutes, puis vérifiez l'état de la passerelle.
kubectl get gateway albRésultat attendu :
NAME CLASS ADDRESS PROGRAMMED AGE alb alb alb-0mwhq4ck6xxxxxxxxx.cn-hangzhou.alb.aliyuncsslb.com True 2m12s -
Vérifiez l'état de la route.
kubectl describe httproute demo-route|grep Status -A 20Résultat attendu :
Status: Parents: Conditions: Last Transition Time: 2025-05-23T08:21:25Z Message: Route is accepted. Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-05-23T08:21:25Z Message: Route is resolved. Observed Generation: 1 Reason: ResolvedRefs Status: True Type: ResolvedRefs Controller Name: gateways.alibabacloud.com/alb/v1 Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: alb -
Testez l'accès à l'application.
-
Récupérez l'adresse de la passerelle.
export ALB_DOMAIN=$(kubectl get gateway alb -n default -o jsonpath='{.status.addresses[?(@.type=="Hostname")].value}') -
Accédez à l'application.
curl -H "Host: demo.ingress.top" http://${ALB_DOMAIN}/versionRésultat attendu :
version: v1 hostname: go-httpbin-547xxxxxf6-xxxxx
-
Cas d'utilisation
Cas d'utilisation 1 : Modifier les en-têtes de requête
HTTPRoute prend en charge des filtres permettant un traitement supplémentaire lors des phases de requête ou de réponse. L'exemple suivant illustre l'utilisation d'un filtre pour ajouter un en-tête aux requêtes envoyées au backend.
-
Créez un fichier nommé httproute-filter.yaml.
apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: demo-filter spec: parentRefs: # Reference the Gateway resource. - group: gateway.networking.k8s.io kind: Gateway name: alb hostnames: - filter.ingress.top # Set the hostname to filter.ingress.top. rules: - matches: # The matching rule is a path prefix match. - path: type: PathPrefix value: / filters: - type: RequestHeaderModifier # Add the request header my-header: foo. requestHeaderModifier: add: - name: my-header value: foo backendRefs: # The backend is a Service named go-httpbin on port 80. - kind: Service name: go-httpbin port: 80Ce fichier crée une ressource HTTPRoute nommée
demo-filter. Une fois déployée, lorsque vous accédez à l'application go-httpbin via le nom de domainefilter.ingress.top, l'en-tête de requêtemy-header : fooest automatiquement ajouté à la requête. -
Déployez la règle de routage.
kubectl apply -f httproute-filter.yaml -
Accédez à l'application.
curl -H "Host: filter.ingress.top" http://${ALB_DOMAIN}/headerRésultat attendu :
headers: { "Accept": [ "*/*" ], "Connection": [ "close" ], "Host": [ "filter.ingress.top" ], "My-Header": [ "foo" ], "Path": [ "/header" ], "Protocol": [ "HTTP/1.1" ], "Remoteip": [ "118.xx.xx.91" ], "URL": [ "/header" ], "User-Agent": [ "curl/8.9.1" ] } query param: , hostname: go-httpbin-547xxxxxf6-xxxxx
Cas d'utilisation 2 : Répartir le trafic par poids
En définissant des pondérations pour plusieurs services backend, vous pouvez répartir le trafic entre eux.
-
Créez un fichier nommé nginx.yaml.
Le fichier précédent déploie deux applications NGINX. Le service
old-nginxretourne la chaîneold, tandis que le servicenew-nginxretourne la chaînenew. Les ressources déployées sont placées dans le namespacedefault. -
Créez un fichier nommé httproute-weight.yaml.
apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: demo-weight spec: parentRefs: # Reference the Gateway resource. - group: gateway.networking.k8s.io kind: Gateway name: alb hostnames: - weight.ingress.top # Set the hostname to weight.ingress.top. rules: - matches: # The matching rule is a path prefix match. - path: type: PathPrefix value: / backendRefs: # Set backends and their corresponding weights. Weights are not percentages and do not need to sum to 100. - kind: Service name: old-nginx port: 80 weight: 100 # Set the weight of old-nginx to 100. - kind: Service name: new-nginx port: 80 weight: 100 # Set the weight of new-nginx to 100.Dans cette règle de routage, les poids attribués aux services
old-nginxetnew-nginxsont identiques. Par conséquent, lors de l'accès à l'application, le trafic vers les servicesnew-nginxetold-nginxdoit suivre un ratio de 1:1. -
Déployez les applications ainsi que la règle de routage.
kubectl apply -f nginx.yaml kubectl apply -f httproute-weight.yaml -
Accédez à l'application 10 fois.
for i in {1..10}; do curl -H "Host: weight.ingress.top" http://${ALB_DOMAIN}/; doneRésultat attendu :
old new new old new old old new new oldComme vous pouvez le constater, le trafic est réparti équitablement (1:1) entre les services
new-nginxetold-nginx.
Opérations associées
Configurer un certificat pour une application
Vous pouvez configurer un certificat TLS pour votre application directement dans la ressource Gateway.
-
Générez un certificat auto-signé pour le nom de domaine
ingress.tap.openssl req -subj '/CN=ingress.top' -new -newkey rsa:2048 -sha256 \ -days 365 -nodes -x509 -keyout server.key -out server.crt \ -addext "subjectAltName = DNS:ingress.top" \ -addext "keyUsage = digitalSignature" \ -addext "extendedKeyUsage = serverAuth" 2> /dev/null; openssl x509 -in server.crt -subject -noout -
Créez un Secret TLS.
kubectl create secret tls ingress.top --key server.key --cert server.crt -
Créez un fichier nommé gateway-tls.yaml afin de mettre à jour la passerelle.
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: alb namespace: default spec: gatewayClassName: alb listeners: - name: http protocol: HTTP port: 80 hostname: "*.ingress.top" allowedRoutes: namespaces: from: Same - name: https protocol: HTTPS port: 443 hostname: "*.ingress.top" allowedRoutes: namespaces: from: Same tls: # Configure TLS. mode: Terminate certificateRefs: # Reference the created Secret. - kind: Secret name: ingress.top -
Appliquez le fichier
gateway-tls.yamlpour mettre à jour la passerelle. La sortie suivante indique une mise à jour réussie :gateway.gateway.networking.k8s.io/alb configured -
Attendez que l'état Programmed de la passerelle passe à True, puis vérifiez la configuration du certificat.
openssl s_client -servername ingress.top -connect ${ALB_DOMAIN}:443Résultat attendu :
CONNECTED(00000003) depth=0 CN = ingress.top verify error:num=18:self-signed certificate verify return:1 depth=0 CN = ingress.top verify return:1 --- Certificate chain 0 s:CN = ingress.top i:CN = ingress.top a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256 v:NotBefore: Jun 24 10:49:39 2025 GMT; NotAfter: Jun 24 10:49:39 2026 GMT --- Server certificate -----BEGIN CERTIFICATE----- ... ... ... -----END CERTIFICATE----- subject=CN = ingress.top issuer=CN = ingress.top --- No client certificate CA names sent Peer signing digest: SHA256 Peer signature type: RSA-PSS Server Temp Key: X25519, 253 bits --- SSL handshake has read 1506 bytes and written 410 bytes Verification error: self-signed certificate --- New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES128-GCM-SHA256 Session-ID: xxxxxxxxxxxxxxxxxxxxxxxxx Session-ID-ctx: Master-Key: xxxxxxxxxxxxxxxxxxxxxxxxxxx PSK identity: None PSK identity hint: None SRP username: None TLS session ticket lifetime hint: 300 (seconds) TLS session ticket: ... ... ... Start Time: 1750820008 Timeout : 7200 (sec) Verify return code: 18 (self-signed certificate) Extended master secret: yes ---RemarqueExécutez la commande
curl -H "Host: demo.ingress.top" -k https://${ALB_DOMAIN}/versionpour accéder à l'application. Le résultat attendu est identique à celui décrit dans la section Tester l'application.