Ingress se quedó sin recorrido. Gateway API es el relevo, y el argumento es el organigrama
Gateway API se suele vender por funcionalidades. El motivo real para moverse es que Ingress no separa al equipo que posee el balanceador del que posee la ruta. Esta es la migración que no necesita ventana de mantenimiento.
Abre los objetos Ingress de un clúster que lleve tres años funcionando y cuenta las anotaciones. El récord que hemos visto en un solo objeto es veintitrés: un destino de reescritura, un bloque de CORS, un tiempo de espera de lectura a medida, un fragmento de Lua metido en la configuración, afinidad de sesión y un tamaño de búfer de proxy que alguien ajustó durante un incidente en 2022. Nada de eso está en la especificación de Ingress. Todo eso es específico de un controlador. No hay esquema, no hay validación y no hay forma de saber qué anotaciones ignoró el controlador en silencio.
Esa factura se cobra el día que cambias de controlador, y a muchos equipos les entregaron ese día cuando quienes mantienen ingress-nginx anunciaron que el proyecto se cerraría en vez de ampliarse. Comprueba la situación actual antes de planificar sobre ello, pero la dirección está clara: el controlador de Ingress más desplegado del mundo no es la respuesta a largo plazo, y el trabajo sucesor está ocurriendo en Gateway API.
Merece la pena moverse a Gateway API de todas formas, y no principalmente por las funcionalidades. Merece la pena porque parte un objeto en tres, justo por la línea que ya existe en tu organización.
En qué falló Ingress de verdad
La especificación es demasiado pequeña. Un Ingress puede expresar un nombre de host, una ruta, un servicio de destino y un secreto TLS. Todo lo demás, tiempos de espera, reintentos, redirecciones, manipulación de cabeceras, límites de frecuencia, pesos de canario y autenticación, vive en anotaciones. Una anotación es una cadena sin tipo. No se valida en la admisión, no se versiona y no es portable.
No hay separación de roles. Un solo objeto contiene la reclamación del nombre de host, la referencia al certificado TLS y las reglas de encaminamiento, y lo posee quien tenga permiso de escritura en el namespace. Nada impide que dos equipos reclamen el mismo nombre de host. Cuando lo hacen, la resolución del conflicto no está definida en la especificación y en la práctica depende de la implementación, a menudo "gana el objeto más antiguo", en silencio.
El encaminamiento se acaba en host y ruta. Sin coincidencia por cabecera, ni por método, ni por parámetro de consulta, ni reparto ponderado entre dos destinos. Por eso todo despliegue canario acaba siendo otra anotación, o un segundo producto.
El modelo de recursos es el argumento
Gateway API sustituye el objeto único por tres, cada uno propiedad de un rol distinto.
GatewayClass tiene alcance de clúster y se comporta como StorageClass. Dice "este tipo de pasarela lo implementa este controlador". Lo instala quien provee el plano de datos, que en una nube gestionada suele ser el propio proveedor.
Gateway vive en un namespace y pertenece al equipo de plataforma. Declara los escuchadores: puerto, protocolo, nombre de host, certificado TLS. Y lo decisivo, declara allowedRoutes, es decir qué namespaces pueden enganchar rutas a ese escuchador, seleccionados por etiqueta. El equipo de plataforma posee el certificado, la dirección pública, el cortafuegos de aplicación que tenga delante y la política de nombres de host.
HTTPRoute vive en un namespace y pertenece al equipo de aplicación, en su propio namespace. Declara coincidencias por ruta, cabecera, método y consulta, filtros de redirección, reescritura, modificación de cabeceras de petición y respuesta y duplicación de tráfico, y backendRefs con pesos. GRPCRoute hace lo mismo para gRPC.
Dos cosas más pequeñas marcan una gran diferencia en la práctica. ReferenceGrant exige que el namespace propietario consienta explícitamente antes de que una ruta de otro namespace pueda apuntar a su Service o a su Secret, lo que cierra la vía del delegado confundido que Ingress dejaba abierta. Y tanto Gateway como Route publican condiciones de estado reales, aceptado, referencias resueltas y programado, así que cuando tu configuración está mal, te lo dice la API en vez de dejar una línea en un log que nadie lee.
El resultado es que el equipo de plataforma puede entregar a los equipos de aplicación una superficie de encaminamiento autoservida sin darles administración del clúster y sin un ticket por nombre de host. Es el mismo problema de fronteras que varios equipos en un clúster, resuelto con el mismo instinto.
Dónde está el soporte de verdad
El conjunto básico, GatewayClass, Gateway y HTTPRoute, alcanzó la versión uno en el canal estándar, y GRPCRoute fue después. Los tipos de ruta de nivel cuatro, TCPRoute, UDPRoute y TLSRoute, se han quedado en el canal experimental mucho más tiempo, así que si tu tráfico no es mayoritariamente HTTP, comprueba en qué canal está la funcionalidad que necesitas antes de diseñar sobre ella.
Implementaciones que merece la pena poner en la lista corta: Envoy Gateway, Istio, que sirve tanto el tráfico de entrada como el de servicio a servicio con los mismos tipos de ruta, Cilium, Contour, Traefik, Kong y NGINX Gateway Fabric. En nubes gestionadas, Google tiene un controlador propio que se mapea a sus balanceadores incluidas las pasarelas multiclúster, AWS expone Gateway API tanto por su controlador de balanceador como por uno de VPC Lattice, y Azure lo hace con Application Gateway for Containers. La cobertura de funcionalidades difiere bastante entre ellas. Cada implementación publica un informe de conformidad por versión; lee el de la versión exacta que piensas ejecutar, no la página de marketing.
Migrar sin big bang
Ingress y Gateway API conviven. Recursos distintos, controladores distintos, mismo clúster.
- Instala los recursos personalizados de Gateway API y un controlador junto al existente. Esos recursos tienen alcance de clúster y son compartidos, así que decide versión y canal a conciencia y ponlos bajo el mismo control de cambios que cualquier otra cosa que afecte al clúster entero.
- El equipo de plataforma crea una Gateway compartida por cada clase expuesta al exterior, con el certificado y el sufijo de nombre de host, y un selector de etiquetas en
allowedRoutes. - Mueve un servicio de poco tráfico. La herramienta
ingress2gatewayconvierte la especificación, pero convierte solo lo que está en la especificación. Las anotaciones son la migración de verdad, y cada una hay que volver a expresarla como filtro, como campo de la especificación o como política específica de la implementación. - Desplaza el tráfico en el DNS o en el balanceador, no borrando el Ingress. Conserva el objeto antiguo hasta tener una semana de métricas limpias de latencia y de error.
- Recorre el entorno equipo a equipo. Todo lo que lleve un fragmento de Lua va el último.
Los backendRefs ponderados son nativos, que es la razón de que tanto Argo Rollouts como Flagger tengan proveedores de Gateway API. Si ya haces entrega progresiva, esto también saca de ese camino las anotaciones de canario específicas del controlador.
Lo que se olvida
- La propiedad de los recursos personalizados es compartida. Dos controladores en un clúster usan un único conjunto. Decide quién los actualiza y fija la versión, o la actualización de un controlador rompe el otro.
- La adjunción de políticas es la parte sin terminar. Algunas cosas ya están en la especificación, como los tiempos de espera de HTTPRoute. Los reintentos, los límites de frecuencia, el TLS mutuo hacia el destino y la autenticación siguen siendo recursos de política propios de cada implementación. Sigues escribiendo configuración por implementación, solo que ahora está tipada y es revisable en vez de ser una cadena.
- Los permisos tienen que cambiar con el modelo. Partir los objetos no compra nada si los equipos de aplicación conservan permiso de edición sobre las Gateway.
- cert-manager y external-dns admiten recursos de Gateway, pero a partir de versiones concretas y con anotaciones distintas de las del camino de Ingress. Verifícalo antes de conmutar.
- Una Gateway por equipo significa un balanceador de la nube por equipo. Una Gateway compartida con escuchadores por nombre de host es apreciablemente más barata y es el valor por defecto que recomendamos.
Cuándo todavía no compensa moverse
Si tienes menos de diez objetos Ingress, un solo equipo, ninguna necesidad de canario y un controlador con futuro mantenido, la migración es coste sin beneficio este trimestre. Lo mismo si tu tráfico es sobre todo TCP en crudo, o si la oferta gestionada de tu nube va por detrás en las funcionalidades de las que dependes. En ese caso haz la mitad barata: deja de añadir anotaciones con fragmentos de código y asegúrate de que el controlador que ejecutas seguirá mantenido dentro de dos años. Lo recorremos en la fase de plataforma de un proyecto cloud.
Qué hacer esta semana
Ejecuta kubectl get ingress -A -o json y cuenta las anotaciones por objeto, de mayor a menor. Las cinco primeras son tu plan de migración real, y el recuento te dice con honestidad qué parte de tu lógica de encaminamiento no es portable hoy.