HTTP Routing con Envoy Gateway en la Práctica: Host, Path, Header y División de Tráfico
Los dos primeros artículos te dieron la base de "qué es esto." Este entra en lo que realmente estarás editando día a día: HTTPRoute.
Piensa en HTTPRoute como un script de enrutamiento para el tráfico entrante — excepto que en lugar de escribir reglas de Nginx o memorizar anotaciones de controlador, estás usando recursos nativos de Kubernetes.
Una cosa que dejar clara primero: este artículo solo cubre HTTPRoute, porque maneja la semántica HTTP/HTTPS. Para gRPC, te inclinarías hacia GRPCRoute; para TCP sin procesar, TCPRoute; para TLS passthrough, TLSRoute. No fuerces todo en HTTPRoute — el YAML empieza a transmitir una vibra de "arreglándoselas."
El Enrutamiento Más Común: Host y Path
Aquí está el ejemplo más típico:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-route
spec:
parentRefs:
- name: eg
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080Lo que esto significa:
- Solo
Host: app.example.comcoincidirá con esta ruta - El path debe comenzar con
/api - El tráfico se reenvía a
api-service:8080
Si eliminas hostnames, la ruta se convierte en "solo path, cualquier dominio."
Qué Puede Coincidir matches
matches es uno de los conceptos más centrales en HTTPRoute.
Piénsalo como "qué condiciones activan esta regla."
Condiciones de coincidencia comunes:
pathheadersqueryParamsmethod
Ejemplo:
matches:
- method: GET
path:
type: PathPrefix
value: /api
headers:
- name: version
value: v2Significado:
- Solo solicitudes
GET - El path comienza con
/api - La solicitud debe incluir el header
version: v2
Este patrón es ideal para pruebas de versiones de API o lanzamientos graduales a usuarios específicos.
Una Route, Múltiples Reglas
Un solo HTTPRoute puede enrutar diferentes paths a diferentes servicios:
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080
- matches:
- path:
type: PathPrefix
value: /admin
backendRefs:
- name: admin-service
port: 8080Esto es excelente para dividir sub-paths bajo un mismo dominio — por ejemplo:
/apiva al servicio de API/adminva al backend de administración
La lógica de enrutamiento es inmediatamente visible. A diferencia de algunos archivos de configuración heredados donde lees hasta la mitad y empiezas a dudar de tu propia existencia.
Header, Method y Query como Condiciones
HTTPRoute no se limita a la coincidencia por path — también puede hacer coincidir por headers de solicitud, métodos y parámetros de query.
Por ejemplo, solo enrutar solicitudes con version: v2 al nuevo servicio:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: versioned-route
spec:
parentRefs:
- name: eg
rules:
- matches:
- path:
type: PathPrefix
value: /api
headers:
- name: version
value: v2
backendRefs:
- name: api-v2
port: 8080
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-v1
port: 8080Este patrón funciona bien para:
- Lanzamientos canary
- Permitir que clientes específicos prueben nuevas versiones antes
- Validación manual de nuevas características
Comparado con cambiar a un dominio completamente nuevo, el enrutamiento basado en headers es más granular y más fácil de experimentar.
filters: Procesar Solicitudes Antes de Reenviarlas
HTTPRoute no solo "hace coincidir y reenvía" — también puede aplicar transformaciones antes o después del reenvío. Para eso están los filters.
Un caso de uso común es agregar headers:
rules:
- filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: x-env
value: prod
backendRefs:
- name: api-service
port: 8080Esto es útil para:
- Inyectar metadatos de rastreo antes de reenviar al backend
- Agregar headers fijos en la capa de ingreso
- Transformaciones de solicitud/respuesta
Dicho esto, los filters son poderosos pero no son un pase libre para convertir la capa de ingreso en un blob gigante de middleware. Demasiada lógica acumulada en las rutas hará que depurar se sienta como si necesitara su propia sesión de terapia.
División de Tráfico Ponderada: El Patrón Canary Más Común
Para enviar el 90% del tráfico a la versión anterior y el 10% a la nueva, usa weight:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: canary-route
spec:
parentRefs:
- name: eg
hostnames:
- "app.example.com"
rules:
- backendRefs:
- name: api-v1
port: 8080
weight: 90
- name: api-v2
port: 8080
weight: 10Este es el canary básico / división de tráfico.
No necesitas un service mesh completo solo para ejecutar un experimento de tráfico. Para muchos servicios de API, esto es más que suficiente — y es mucho más limpio de configurar.
💡
weightes relativo, no es necesario que sume 100.9y1expresan la misma proporción que90y10.
timeouts: No Dejes que las Solicitudes Queden Colgadas para Siempre
HTTPRoute admite configuración de timeout a nivel de regla. Esto importa — si la capa de ingreso no tiene límites, las solicitudes malas se quedan indefinidamente como un cliente maleducado que no se quiere ir.
rules:
- matches:
- path:
type: PathPrefix
value: /reports
timeouts:
request: 10s
backendRequest: 2s
backendRefs:
- name: report-service
port: 8080Entendiendo los dos campos:
request: Tiempo máximo de espera total para la solicitud del clientebackendRequest: Espera máxima para una solicitud individual al backend
Ten en cuenta que backendRequest no debería exceder request — la lógica sería como decir "el viaje completo toma 10 minutos, pero un tramo en autobús puede esperar 20 minutos." El universo se confunde.
Dos Matices Comunes
1. parentRefs Puede Apuntar a un Listener Específico
Si un Gateway tiene múltiples listeners, puedes vincularte solo a uno:
parentRefs:
- name: eg
sectionName: httpEsto significa que la ruta solo se adjunta al listener http.
En configuraciones con múltiples listeners, esto es mucho más predecible que adjuntarse a todo.
2. Sin matches = Coincide con Todo
Si una regla no tiene matches, por defecto coincide con / — esencialmente un catch-all.
Esto es conveniente, pero puede silenciosamente absorber lo que pensabas que eran reglas más específicas. No lo omitas por pereza y luego pases una hora preguntándote por qué tus reglas precisas no se están disparando.
Verificando que el Enrutamiento Funciona
Después de configurar las rutas, valida con curl:
curl -H "Host: app.example.com" http://$GATEWAY_HOST/api/users
curl -H "Host: app.example.com" -H "version: v2" http://$GATEWAY_HOST/api/usersPara revisar el status de HTTPRoute:
kubectl get httproute app-route -o yamlPresta especial atención a:
status.parents- La condición
Accepted
A veces el YAML parece correcto, pero el Gateway lo rechazó. Es como enviar una solicitud de empleo y asumir que conseguiste el trabajo porque no recibiste respuesta.
Resumen en Una Línea
El núcleo de HTTPRoute es "primero hacer coincidir, luego reenviar." Una vez que tienes cubiertos host, path, header y weight, puedes manejar alrededor del 80% de los requisitos de ingreso HTTP del día a día.
Siguiente Paso
El próximo artículo aborda algo que encontrarás en cada entorno de producción: HTTPS, certificados, terminación TLS y seguridad: 👉 TLS y Seguridad