La API de Gateway es la interfaz de enrutamiento y balanceo de carga de nueva generación para Kubernetes. En este tema se describe cómo configurar rutas HTTP, modificar encabezados de solicitud y distribuir solicitudes por peso dentro de un clúster ACK Edge mediante el componente Gateway with Inference Extension.
Funcionamiento
El componente Gateway with Inference Extension se basa en el proyecto Envoy Gateway. Este componente admite todas las funciones básicas de Gateway API y los recursos de extensión de Envoy Gateway.
La arquitectura de Envoy Gateway incluye lo siguiente:
Plano de control: está formado por el componente Envoy Gateway. Escucha las reglas de tráfico dentro del clúster, crea y gestiona dinámicamente instancias de proxy Envoy, y actualiza las reglas de reenvío en tiempo real. El plano de control no reenvía directamente el tráfico del servicio.
Plano de datos: está compuesto por instancias de proxy Envoy. Procesa y reenvía el tráfico del servicio.
En un clúster ACK Edge, el método de despliegue de Envoy Gateway difiere del que se usa en un clúster ACK estándar:
|
Diferencias |
ACK estándar |
ACK Edge |
|
Método de exposición del servicio |
LoadBalancer |
NodePort |
|
Despliegue del plano de control |
A nivel de clúster |
Se despliega un conjunto por cada node pool |
|
Despliegue del plano de datos |
A nivel de clúster |
Se despliega por node pool |
|
Varios node pools |
Comparten una sola puerta de enlace |
Se debe crear una puerta de enlace independiente para cada node pool |
|
Topología del servicio |
No requiere configuración |
Requiere la anotación |
El despliegue actual se configura con una política de distribución por node pool. Puede ajustar el número de réplicas en la gestión de componentes para asegurar que se ejecute como mínimo una réplica del plano de control en cada node pool.

Ámbito de aplicación
Cuenta con created a cluster de la versión 1.30 o posterior.
El componente Gateway with Inference Extension ya está instalado.
Preparativos
Paso 1: Crear una aplicación de prueba
Guarde el ejemplo a continuación como backend.yaml y ejecute el comando kubectl apply -f backend.yaml para crear las aplicaciones de prueba: backend y backend-2.
En escenarios de ACK Edge, debe configurar la topología del servicio. Agregue la anotación openyurt.io/topologyKeys: openyurt.io/nodepool al Service para garantizar que el tráfico se reenvíe únicamente a los pods dentro del mismo node pool. Para obtener más información, consulte Service topology for node pools .
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
Paso 2: Confirmar la GatewayClass
Después de instalar el componente Gateway with Inference Extension, se crea una GatewayClass de forma predeterminada. Ejecute el siguiente comando para confirmarlo:
kubectl get gatewayclass
Salida esperada:
NAME CONTROLLER ACCEPTED AGE
ack-gateway gateway.envoyproxy.io/gatewayclass-controller True 2m31s
Si no encuentra el recurso GatewayClass, puede crearlo manualmente. Guarde el siguiente ejemplo como gatewayclass.yaml y ejecute el comando kubectl apply -f gatewayclass.yaml para crearlo.
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: ack-gateway
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
Paso 3: Crear una configuración personalizada de EnvoyProxy
En un clúster ACK Edge, puede crear una configuración personalizada de EnvoyProxy para cada node pool. Esto le permite especificar el node pool de programación para los pods del plano de datos y el método de exposición del servicio.
Reemplace NPXXX en el siguiente ejemplo con su ID de node pool real. Luego, guarde la configuración como gateway-config.yaml y ejecute el comando kubectl apply -f gateway-config.yaml.
Puede encontrar el ID del node pool en la página de la consola de 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
Esta configuración incluye tres ajustes clave para escenarios de ACK Edge:
|
Elemento de configuración |
Descripción |
|
|
Programa los pods del plano de datos de la puerta de enlace en el node pool especificado |
|
Anotación |
Configura la topología del servicio para garantizar que el tráfico permanezca dentro del node pool |
|
|
Usa NodePort para exponer el servicio. En escenarios perimetrales no se utiliza LoadBalancer. |
Paso 4: Crear el recurso Gateway
Guarde el siguiente ejemplo como gateway.yaml y ejecute el comando kubectl apply -f gateway.yaml.
El plano de control del componente crea automáticamente un despliegue de EnvoyProxy y un servicio NodePort a partir del recurso Gateway. También inicia un listener en el puerto especificado del nodo.
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
Paso 5: Obtener el endpoint de la puerta de enlace
El servicio de la puerta de enlace se expone como NodePort. El endpoint correspondiente es la dirección IP de cualquier nodo del node pool junto con su puerto de servicio.
-
Consulte el puerto del servicio.
kubectl get service -n kube-system -l gateway.envoyproxy.io/owning-gateway-name=ack-gatewaySalida esperada:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE envoy-default-ack-gateway-7452df7d NodePort 192.168.86.174 <none> 80:30364/TCP 19m Establezca la variable de entorno del host de la puerta de enlace. Reemplace
NODEIPcon la dirección IP de cualquier nodo del node pool yNODEPORTcon el número de puerto obtenido en el paso anterior.export GATEWAY_HOST=NODEIP:NODEPORT
Configuración del enrutamiento HTTP mediante coincidencia de prefijos de ruta
A continuación se muestra un archivo YAML de ejemplo que sirve para crear un HTTPRoute con coincidencia para el prefijo /get.
-
Cree un HTTPRoute. Guarde el siguiente contenido YAML como
httproute.yaml. Después, ejecute el comandokubectl apply -f httproute.yamlpara aplicarlo.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 -
Acceda a la aplicación.
curl -H "Host: www.example.com" http://$GATEWAY_HOST/getSalida esperada:
{ "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" }
Agregar un encabezado de solicitud
Actualice el HTTPRoute y agregue un encabezado a la solicitud.
-
Actualice el recurso
HTTPRoute. Guarde el siguiente contenido YAML comohttproute.yaml. Después, ejecute el comandokubectl apply -f httproute.yamlpara aplicarlo.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" -
Acceda a la aplicación.
curl -H "Host: www.example.com" http://$GATEWAY_HOST/getSalida esperada:
{ "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" }%Dado que la aplicación de ejemplo devuelve la información de la solicitud en su respuesta, debería ver el encabezado
added-headeren la salida. Esto confirma que la operación fue exitosa.
Configurar la división proporcional del tráfico
Actualice el HTTPRoute con base en la siguiente plantilla YAML. En esta plantilla se agregan reglas de enrutamiento para el Service backend-2 y se especifican los pesos de tráfico para los Services backend y backend-2.
La suma de los pesos que especifique en el parámetro backendRefs no necesita ser 100. La proporción de tráfico enrutado a un Service =
-
Actualice el HTTPRoute. Guarde el siguiente contenido YAML como
httproute.yaml. Después, ejecute el comandokubectl apply -f httproute.yamlpara aplicarlo.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 -
Acceda a la aplicación 20 veces y compruebe la proporción de tráfico real entre ambos Services.
El siguiente comando envía 20 solicitudes y procesa la salida para mostrar únicamente el Service de backend (
backendobackend-2) que gestionó cada solicitud.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/'Salida esperada:
backend-2 backend backend backend backend backend backend backend backend backend backend backend-2 backend-2 backend backend backend-2 backend backend backend backendLa salida muestra que aproximadamente el 80 % de las solicitudes se reenvían al Service
backendy el 20 % restante al Servicebackend-2.