Saltar al contenido

Ingress vs Gateway API: dos formas de exponer tráfico en Kubernetes

Augusto Mancuso
Published date:

Ingress vs Gateway API: dos formas de exponer tráfico en Kubernetes

La idea central: dos caminos para resolver el mismo problema

Ingress y Gateway API resuelven un problema parecido: permitir que el tráfico externo llegue a servicios dentro de Kubernetes. La diferencia está en cómo modelan ese problema.

Ingress es un recurso estable de Kubernetes para publicar servicios HTTP/HTTPS usando reglas de host y path. Es simple, muy conocido y todavía sigue siendo válido. Pero tiene una limitación importante: la API está congelada. Es GA, no se va a remover, pero ya no está pensada para crecer con nuevas capacidades.

Gateway API aparece como una evolución de ese modelo. No es un proxy ni un producto específico. Es una familia de CRDs oficiales del proyecto Kubernetes SIG Network que permite describir networking L4/L7 de una forma más expresiva, extensible, portable y con una separación más clara de responsabilidades.

A mí me sirve resumirlo así:

Ingress publica aplicaciones. Gateway API modela una plataforma de entrada de tráfico.

La comparación rápida sería esta:

TemaIngressGateway API
ModeloUn recurso principal: IngressVarios recursos: GatewayClass, Gateway, HTTPRoute, GRPCRoute, TLSRoute, ReferenceGrant, policies
EnfoqueCentrado en la aplicaciónCentrado en roles y responsabilidades
Entrada de tráficoImplícita en el Ingress ControllerExplícita mediante Gateway y listeners
RoutingHTTP/HTTPS básico por host y pathRouting por host, path, headers, query params, method, weights, filters, timeouts, etc.
ExtensibilidadPrincipalmente annotations del controllerCampos estructurados, filters, policies, extensionRefs, backendRefs
Multi-teamLimitadoDiseñado para infraestructura compartida
PortabilidadBaja cuando dependés de annotationsMejor, aunque depende del soporte real de cada implementación
EstadoEstable, pero congeladoLínea moderna de evolución del networking en Kubernetes

Ingress: el modelo clásico para publicar aplicaciones

El problema que resuelve Ingress

Ingress expone rutas HTTP y HTTPS desde fuera del clúster hacia Services dentro del clúster.

Sirve para cosas como:

No sirve para exponer cualquier protocolo o puerto de forma genérica. Para tráfico que no sea HTTP/HTTPS, normalmente se usan otros mecanismos, como NodePort, LoadBalancer o configuraciones específicas del controller.

Un modelo mental simple sería:

Cliente

DNS

Load Balancer / VIP / NodePort

Ingress Controller

Ingress rule

Service

Pod

El recurso Ingress por sí solo no alcanza. Necesitás un Ingress Controller que lo observe y lo convierta en configuración real para algún dataplane: NGINX, Traefik, HAProxy, Kong, Envoy, etc.

En otras palabras: el YAML de Ingress describe la intención, pero el controller es quien la hace funcionar.


Cómo se ve un Ingress por dentro

Un Ingress típico define:

Ejemplo básico:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  namespace: apps
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - app.example.com
      secretName: app-tls
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-service
                port:
                  number: 80

Esto se puede leer así:

Para app.example.com,
entrando por HTTPS,
mandá todo lo que matchee con "/" hacia app-service:80.

Para casos simples funciona muy bien. El problema aparece cuando necesitás algo más fino que host, path y TLS básico.


El límite real de Ingress: cuando todo termina en annotations

Ingress soporta de forma estándar un conjunto bastante acotado de capacidades:

Cuando necesitás features más avanzadas, la solución suele pasar por annotations específicas del controller.

Un Ingress real en producción puede terminar así:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
  ingressClassName: nginx
  rules:
    ...

Eso funciona, pero ya no es una configuración portable de Kubernetes. Es una configuración atada a NGINX Ingress.

Si mañana cambiás a Traefik, HAProxy, Kong o Envoy, esas annotations no se traducen solas. Ese es uno de los dolores más grandes de Ingress: muchas capacidades útiles quedaron fuera de spec y terminaron como strings key/value dentro de metadata.annotations.


Gateway API: una forma más moderna de modelar el tráfico

El problema que viene a resolver Gateway API

Gateway API intenta resolver el mismo problema base que Ingress, pero con una arquitectura más explícita.

El modelo se parece más a esto:

GatewayClass

Gateway

Listener

Route

BackendRef / Service

Pods

Los recursos viven en el grupo:

gateway.networking.k8s.io

y se instalan como CRDs.

El modelo principal gira alrededor de tres tipos de objetos:

GatewayClass define una clase de gateways.

Gateway pide un punto de entrada para tráfico.

Las Routes describen cómo ese tráfico se manda hacia los servicios.

La diferencia importante no es solo que haya más objetos. La diferencia es que cada objeto representa una responsabilidad distinta.


Gateway API no es un proxy: es una interfaz declarativa

Este punto conviene dejarlo claro:

Gateway API no es Envoy, no es Kong, no es Traefik y no es NGINX.

Gateway API es una interfaz declarativa. Después necesitás una implementación que la reconcilie.

El modelo real sería:

Kubernetes API Server
  ↓ watches
Gateway API Controller
  ↓ programs
Dataplane real
  ↓ handles traffic
Services / Pods

Algunos ejemplos:

ImplementaciónDataplane típico
Envoy GatewayEnvoy
KongKong Gateway
TraefikTraefik Proxy
CiliumEnvoy/eBPF, según el caso
NGINX Gateway FabricNGINX
ContourEnvoy

La API define el contrato. La implementación decide cómo convertir ese contrato en tráfico real.


Las piezas principales de Gateway API

GatewayClass: la clase que define quién controla el Gateway

GatewayClass define qué controller maneja un tipo de gateway.

Es un recurso cluster-scoped y cumple un rol parecido a IngressClass para Ingress o StorageClass para volúmenes.

Ejemplo:

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: envoy-gateway
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller

Esto no abre ningún puerto ni publica tráfico. Solo dice:

Los Gateways que usen esta clase serán manejados por este controller.

En muchas implementaciones, el GatewayClass lo crea el chart, el operator o el manifiesto de instalación del controller.


Gateway: el punto de entrada al clúster

Gateway representa el punto de entrada.

Define direcciones y listeners. Las direcciones indican cómo se alcanza al Gateway. Los listeners describen puerto, protocolo, hostname, TLS y qué routes pueden adjuntarse.

Ejemplo:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: public-gateway
  namespace: gateway-system
spec:
  gatewayClassName: envoy-gateway
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      hostname: "*.example.com"
      allowedRoutes:
        namespaces:
          from: All

Esto se puede leer así:

Quiero un punto de entrada público,
manejado por la clase envoy-gateway,
escuchando HTTP en el puerto 80,
para hosts *.example.com,
y aceptando routes desde todos los namespaces.

En Ingress, los entrypoints HTTP/HTTPS suelen venir dados por el controller. En Gateway API, esos entrypoints se declaran explícitamente en el Gateway.


Listener: donde se define cómo entra el tráfico

Un listener es parte de un Gateway.

Define preguntas concretas:

¿Qué protocolo escucho?
¿En qué puerto?
¿Para qué hostname?
¿Termino TLS o hago passthrough?
¿Qué routes pueden adjuntarse?

Ejemplo:

listeners:
  - name: https
    protocol: HTTPS
    port: 443
    hostname: app.example.com
    tls:
      mode: Terminate
      certificateRefs:
        - name: app-tls
    allowedRoutes:
      namespaces:
        from: Same

Gateway API también define reglas para evitar listeners ambiguos o en conflicto. Por ejemplo, dos listeners HTTPS en el mismo puerto pueden convivir si se distinguen por hostname.


HTTPRoute: donde vive la lógica de routing HTTP

HTTPRoute define reglas específicas para HTTP.

Sirve para HTTP o HTTPS terminado, y permite tomar decisiones usando datos de la request, como path, headers, query params o método HTTP.

Ejemplo:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-route
  namespace: apps
spec:
  parentRefs:
    - name: public-gateway
      namespace: gateway-system
  hostnames:
    - app.example.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: app-service
          port: 80

Esto dice:

Quiero adjuntarme al Gateway public-gateway.
Acepto tráfico para app.example.com.
Si el path empieza con /, mando la request a app-service:80.

HTTPRoute permite matches más ricos que Ingress:

También soporta pesos en backendRefs, lo que permite dividir tráfico entre dos versiones, por ejemplo 90% a v1 y 10% a v2.


Filters: cómo modificar o procesar requests

Los filters permiten modificar o procesar requests y responses.

Algunos casos típicos son:

El soporte concreto depende del tipo de filtro y de la implementación.

Ejemplo:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: header-route
  namespace: apps
spec:
  parentRefs:
    - name: public-gateway
      namespace: gateway-system
  hostnames:
    - app.example.com
  rules:
    - filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            add:
              - name: X-From-Gateway
                value: "true"
      backendRefs:
        - name: app-service
          port: 80

En Ingress, algo así normalmente terminaría como una annotation específica del controller. En Gateway API, al menos una parte de esas capacidades pasa a vivir en una API estructurada.


Rutas por protocolo: HTTP, gRPC, TLS, TCP y UDP

Gateway API define recursos de routing por protocolo, pero no todos tienen el mismo nivel de madurez ni el mismo soporte.

HTTPRoute sirve para HTTP o HTTPS terminado.

GRPCRoute está pensado para enrutar tráfico gRPC de forma más idiomática.

TLSRoute sirve para enrutar tráfico TLS usando SNI, especialmente cuando no querés inspeccionar HTTP.

TCPRoute y UDPRoute cubren tráfico L4, pero conviene tratarlos con más cuidado porque siguen dependiendo del canal experimental y del soporte de cada implementación.

Este punto es importante: usar Gateway API no significa que todo esté soportado igual en todos lados. Algunas features son core, otras extended, otras experimentales y otras directamente específicas de implementación.


ReferenceGrant: control seguro entre namespaces

ReferenceGrant resuelve un problema clave: las referencias entre namespaces.

Ejemplo típico:

Un HTTPRoute en el namespace apps
quiere mandar tráfico a un Service en el namespace shared-services.

Por seguridad, eso no debería permitirse automáticamente.

ReferenceGrant permite que el namespace dueño del recurso referenciado autorice esa referencia de forma explícita.

Ejemplo:

apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
  name: allow-apps-to-backend
  namespace: shared-services
spec:
  from:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      namespace: apps
  to:
    - group: ""
      kind: Service

Esto dice:

Permito que HTTPRoutes del namespace apps referencien Services de este namespace.

Sin ReferenceGrant, una referencia cross-namespace es inválida.

Este mecanismo también puede usarse para permitir que Routes referencien backends en otros namespaces, o que Gateways referencien Secrets en otros namespaces.

Ingress no tiene un mecanismo equivalente tan claro dentro de su propia API.


Qué pasa detrás de escena: el plano de control

Cómo se reconcilia Ingress

Con Ingress, el flujo de control suele ser:

Usuario aplica Ingress

API Server guarda el recurso

Ingress Controller observa Ingress, Services, EndpointSlices y Secrets

Genera configuración del proxy

Recarga o actualiza el dataplane

El proxy empieza a enrutar tráfico

Ejemplo con NGINX Ingress:

Ingress YAML

nginx-ingress-controller

nginx.conf dinámico

NGINX worker processes

Service / Pod

La complejidad real depende del controller. Por eso, cuando hay problemas, no alcanza con mirar solo el recurso Ingress: también hay que revisar eventos, logs del controller y documentación específica de la implementación.


Cómo se reconcilia Gateway API

Con Gateway API, el flujo de control queda más separado:

Se instalan los CRDs

Se instala una implementación de Gateway API

Se crea GatewayClass

El equipo de plataforma crea Gateway

Los equipos crean HTTPRoute, GRPCRoute o TLSRoute

El controller valida allowedRoutes, parentRefs, hostnames, ReferenceGrant y backendRefs

El controller programa el dataplane

El dataplane enruta tráfico real

Gateway API también tiene conformance tests para verificar que las implementaciones respeten la especificación.

Las features se suelen separar en:

Esto es clave para producción. Gateway API da una API común y un modelo de conformance más formal, pero no significa que todas las implementaciones soporten exactamente lo mismo.


El recorrido real de una request

Cómo viaja una request con Ingress

Ejemplo:

curl https://app.example.com/api/users

Flujo:

  1. DNS resuelve app.example.com a una IP pública, VIP o LoadBalancer.
  2. El tráfico llega al Ingress Controller.
  3. El controller o proxy termina TLS, si corresponde.
  4. El proxy mira Host: app.example.com.
  5. El proxy mira el path /api/users.
  6. Busca la regla Ingress correspondiente.
  7. Envía la request al Service.
  8. El Service balancea hacia Pods usando endpoints.

La regla Ingress podría verse así:

rules:
  - host: app.example.com
    http:
      paths:
        - path: /api
          pathType: Prefix
          backend:
            service:
              name: api-service
              port:
                number: 80

Cómo viaja una request con Gateway API

Ejemplo:

curl https://app.example.com/api/users

Flujo:

  1. DNS resuelve app.example.com a la IP o dirección del Gateway.
  2. El tráfico llega al dataplane del Gateway.
  3. Se selecciona un listener del Gateway: HTTPS, puerto 443, app.example.com.
  4. El listener termina TLS usando el Secret configurado.
  5. Se buscan HTTPRoutes adjuntas a ese listener.
  6. Se evalúa el hostname app.example.com.
  7. Se evalúan las reglas: path, headers, query params o method.
  8. Se aplican filters, si existen.
  9. Se selecciona el backendRef.
  10. El tráfico va al Service.
  11. El Service envía la request a los Pods.

Ejemplo:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: public-gateway
  namespace: gateway-system
spec:
  gatewayClassName: envoy-gateway
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      hostname: app.example.com
      tls:
        mode: Terminate
        certificateRefs:
          - name: app-tls
      allowedRoutes:
        namespaces:
          from: All
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-route
  namespace: apps
spec:
  parentRefs:
    - name: public-gateway
      namespace: gateway-system
      sectionName: https
  hostnames:
    - app.example.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api-service
          port: 80

La diferencia importante es que el entrypoint está modelado en el Gateway, no escondido dentro del controller.


La diferencia de fondo: simpleza contra modelo de plataforma

Un solo objeto contra un modelo distribuido

En Ingress, muchas cosas viven en un solo recurso:

Ingress = entrada + reglas + TLS + backend

En Gateway API, el modelo se divide:

GatewayClass = implementación
Gateway      = infraestructura de entrada
Listener     = puerto/protocolo/hostname/TLS
Route        = reglas de tráfico
BackendRef   = destino
Policy       = comportamiento adicional

Esta separación no es solo una cuestión de estilo. Tiene sentido cuando el clúster deja de ser de una sola app o de un solo equipo.

Gateway API está pensado para que distintas personas o equipos puedan administrar partes distintas del problema: infraestructura, plataforma y aplicaciones.


Desarrolladores, plataforma y responsabilidades mejor separadas

Con Ingress, un desarrollador suele crear el recurso completo:

kind: Ingress
metadata:
  name: app
spec:
  ingressClassName: nginx
  tls:
    ...
  rules:
    ...

En Gateway API, el equipo de plataforma puede crear esto:

kind: Gateway
metadata:
  name: public-gateway
  namespace: gateway-system
spec:
  listeners:
    ...

Y el equipo de aplicación crea solamente la route:

kind: HTTPRoute
metadata:
  name: app-route
  namespace: apps
spec:
  parentRefs:
    - name: public-gateway
      namespace: gateway-system
  rules:
    ...

Ese modelo permite repartir responsabilidades de una forma más sana.

El equipo de plataforma puede controlar:

Los equipos de aplicaciones pueden controlar:

Para plataformas compartidas, esta separación es una de las razones más fuertes para mirar Gateway API.


Cómo cambia la implementación en la práctica

Implementar Ingress en un clúster

Para implementar Ingress, normalmente hacés algo así:

  1. Instalás un Ingress Controller.
  2. Exponés el controller con Service tipo LoadBalancer, NodePort, hostNetwork o DaemonSet.
  3. Creás un IngressClass.
  4. Creás un Ingress por aplicación.
  5. Configurás DNS hacia el LB o VIP.
  6. Configurás cert-manager o Secrets TLS.

En un escenario on-prem, el modelo mental podría ser:

Internet

HAProxy / Keepalived VIP

NodePort / LoadBalancer con MetalLB

NGINX Ingress Controller

Ingress

Service

Pod

Implementar Gateway API en un clúster

Para implementar Gateway API, el flujo típico sería:

  1. Instalás los CRDs de Gateway API.
  2. Instalás una implementación: Envoy Gateway, Kong, Traefik, Cilium, etc.
  3. Confirmás que exista un GatewayClass.
  4. Creás un Gateway con listeners.
  5. Creás HTTPRoutes, GRPCRoutes o TLSRoutes.
  6. Configurás ReferenceGrant si hay referencias cross-namespace.
  7. Configurás DNS hacia la IP o dirección del Gateway.
  8. Validás el status de Gateway, listeners y Routes.

En on-prem, el flujo podría ser:

Internet

HAProxy / Keepalived VIP

MetalLB LoadBalancer IP del Gateway dataplane

Gateway implementation dataplane: Envoy / Kong / Traefik / etc.

Gateway + HTTPRoute

Service

Pod

Otra variante posible:

Internet

HAProxy SNI/TCP routing

Gateway dataplane por cluster

HTTPRoute / TLSRoute

Service / Pod

Para una arquitectura con HAProxy, Keepalived y MetalLB, Gateway API no elimina necesariamente HAProxy del edge.

Puede reemplazar o complementar al Ingress Controller dentro del clúster. El diseño correcto depende de dónde querés terminar TLS:


TLS: una diferencia importante entre ambos modelos

TLS en Ingress

En Ingress, TLS vive en spec.tls:

spec:
  tls:
    - hosts:
        - app.example.com
      secretName: app-tls

Es simple y funciona bien para casos básicos.

Pero la lógica avanzada —redirect HTTP a HTTPS, TLS passthrough, mTLS, selección avanzada de certificados— suele depender del controller y de sus annotations.


TLS en Gateway API

En Gateway API, TLS vive en el listener:

listeners:
  - name: https
    protocol: HTTPS
    port: 443
    hostname: app.example.com
    tls:
      mode: Terminate
      certificateRefs:
        - name: app-tls

Esto es más claro cuando pensás en una plataforma.

Un listener HTTPS define:

En vez de repartir la intención entre Ingress, spec.tls y annotations específicas, Gateway API ubica esa configuración en el punto de entrada.

También existe BackendTLSPolicy, que sirve para describir cómo el Gateway se conecta por TLS hacia un backend. Esto es útil cuando no querés solamente TLS en el borde, sino también TLS desde el dataplane hacia los servicios internos.


Routing: de reglas simples a decisiones más avanzadas

Routing en Ingress

Ingress rutea principalmente por:

Los pathType principales son:

ImplementationSpecific deja el matching en manos de la clase o del controller.


Routing en Gateway API

HTTPRoute puede rutear por:

Ejemplo de canary:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-canary
  namespace: apps
spec:
  parentRefs:
    - name: public-gateway
      namespace: gateway-system
  hostnames:
    - app.example.com
  rules:
    - backendRefs:
        - name: app-v1
          port: 80
          weight: 90
        - name: app-v2
          port: 80
          weight: 10

En Ingress, algo parecido normalmente se resolvería con annotations o con recursos propios del controller.


Extensibilidad: annotations contra APIs estructuradas

Cómo se extendió Ingress

Ingress se extendió principalmente con annotations:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/rewrite-target: /

El problema es bastante directo:

Por eso, migrar de un Ingress Controller a otro puede ser difícil si tu configuración depende mucho de annotations específicas.


Cómo se extiende Gateway API

Gateway API usa mecanismos más estructurados:

Esto no elimina toda configuración específica de implementación. Eso sería poco realista.

Pero sí ordena mejor el modelo: lo estándar va a campos estándar; lo extendido puede ir a filters o policies; lo específico queda más delimitado.


Seguridad y multitenancy: donde Gateway API empieza a brillar

Seguridad y aislamiento con Ingress

Con Ingress, si un equipo puede crear recursos Ingress en su namespace, puede intentar declarar hosts, paths, TLS, annotations, etc.

El control fino suele depender de varias capas externas:

Se puede operar así, pero no es el modelo más cómodo cuando varias aplicaciones o equipos comparten infraestructura de entrada.


Seguridad y control de acceso con Gateway API

Gateway API trae controles nativos más claros.

allowedRoutes: quién puede adjuntarse a un Gateway

En el listener:

allowedRoutes:
  namespaces:
    from: Selector
    selector:
      matchLabels:
        shared-gateway-access: "true"

Esto permite que el dueño del Gateway controle qué namespaces pueden adjuntar routes.

parentRefs: a qué Gateway quiere conectarse una Route

En la route:

parentRefs:
  - name: public-gateway
    namespace: gateway-system
    sectionName: https

La route declara a qué Gateway y a qué listener quiere adjuntarse.

ReferenceGrant: permisos explícitos entre namespaces

El namespace dueño del recurso referenciado debe autorizar referencias cross-namespace.

Sin ReferenceGrant, la referencia cross-namespace es inválida.

El modelo queda más claro:

La app pide adjuntarse.
El Gateway decide si acepta.
El backend o Secret remoto decide si puede ser referenciado.

Eso encaja mejor con plataformas multi-team.


Conflictos de rutas: qué pasa cuando varios equipos comparten entrada

En Ingress, muchos controllers mergean reglas de múltiples recursos Ingress, pero la API no define con el mismo nivel de detalle cómo resolver todos los conflictos.

Ejemplo:

Dos equipos publican rutas en el mismo dominio.
Uno declara /api.
Otro declara /api/v1.
Otro declara el mismo host con otra configuración TLS.

¿Quién gana?

Con Ingress, muchas veces la respuesta depende del controller.

Gateway API intenta que esto sea más determinista. La implementación debe mergear las reglas de los HTTPRoutes adjuntos a un listener y manejar conflictos siguiendo las reglas de diseño de la API, por ejemplo priorizando matches más específicos.

Esto importa mucho cuando varias aplicaciones comparten el mismo Gateway.


Troubleshooting: cómo diagnosticar problemas en cada modelo

Diagnosticar problemas con Ingress

Con Ingress, normalmente revisás:

kubectl describe ingress app -n apps
kubectl get ingress app -n apps
kubectl logs deploy/ingress-nginx-controller -n ingress-nginx
kubectl describe svc app-service -n apps
kubectl get endpointslice -n apps

El status puede mostrar la dirección asignada, pero muchos errores reales terminan apareciendo en eventos o logs del controller.


Diagnosticar problemas con Gateway API

Con Gateway API tenés más niveles de status:

kubectl get gateway -A
kubectl describe gateway public-gateway -n gateway-system
kubectl get httproute -A
kubectl describe httproute app-route -n apps

Conviene revisar:

Este modelo ayuda a separar mejor los problemas.

SíntomaPosible causa
Gateway no tiene addressEl controller no pudo programar LB/IP
Listener no está listoConflicto de listener, Secret TLS faltante o protocolo no soportado
attachedRoutes = 0Problema con allowedRoutes, namespace, hostname o parentRef
Accepted=FalseLa route no fue aceptada por el listener
ResolvedRefs=FalseBackend o Secret inválido, o referencia cross-namespace sin ReferenceGrant
404/503 en dataplaneMatch incorrecto, backend sin endpoints o Service mal configurado

Cuándo conviene seguir usando Ingress

Usaría Ingress cuando:

Ejemplo típico:

Una app interna.
Un dominio.
TLS simple.
Un backend.
NGINX Ingress funcionando bien.

En ese escenario, Ingress sigue siendo una opción válida.

Cuándo conviene empezar a usar Gateway API

Usaría Gateway API cuando:

Ejemplo típico:

Cluster productivo con varios equipos.
Un gateway público compartido.
Gateways internos por ambiente.
TLS controlado por plataforma.
Routes autogestionadas por equipos.
Canary o weighted routing.
Políticas de seguridad.

Ahí Gateway API empieza a tener mucho más sentido.


18. Resumen final

DimensiónIngressGateway API
FuturoEstable, pero congeladoEvolución moderna del networking Kubernetes
Tipo de APIBuilt-in Kubernetes APICRDs oficiales del proyecto Gateway API
Recurso principalIngressGatewayClass, Gateway, Route, policies
Entry pointsImplícitos por controllerExplícitos con listeners
Routing HTTPBásicoAvanzado
TLSEn spec.tls del IngressEn listener del Gateway
Canary / weightsUsualmente annotationsbackendRefs.weight
Headers/query/method matchingUsualmente annotations o controller-specificParte de HTTPRoute
Multi-namespaceLimitadoallowedRoutes + ReferenceGrant
Multi-teamDébilDiseñado para eso
PortabilidadBuena solo con features básicasMejor en Core/Extended; lo implementation-specific sigue existiendo
ExtensibilidadAnnotationsFilters, policies, extensionRefs
TroubleshootingMuy dependiente del controllerStatus más estructurado por Gateway, listener y Route
MigraciónMuy usado en entornos legacyMejor punto de partida para nuevos diseños

La idea que me queda es esta:

Ingress publica aplicaciones; Gateway API modela una plataforma de entrada de tráfico.

Para un clúster simple, Ingress todavía puede ser suficiente.

Para una plataforma productiva con varios equipos, varios namespaces, TLS serio, tráfico compartido, routing avanzado y una arquitectura más preparada para crecer, Gateway API ofrece un modelo más claro.

Previous
Kubernetes desde cero: componentes, nodos e interfaces principales
Next
Certificados, CAs y cadenas de confianza: una guía para no perderse