Cuando varios equipos deben publicar aplicaciones HTTP desde un mismo clúster, el modelo de Ingress puede resultar limitado: normalmente concentra la infraestructura y las reglas de enrutamiento en recursos administrados por un mismo responsable.

Gateway API amplía este modelo mediante recursos con responsabilidades diferenciadas:

  • GatewayClass: identifica la implementación o clase de infraestructura disponible en el clúster.
  • Gateway: define listeners, puertos, protocolos y qué rutas pueden asociarse.
  • HTTPRoute: contiene las reglas de una aplicación, como hostname, path y backend.
  • Service: distribuye el tráfico hacia los Pods de la aplicación.

Esta separación permite que el equipo de infraestructura controle el punto de entrada mientras cada equipo de desarrollo administra sus propias rutas. Además, la asociación entre un Gateway y una ruta puede atravesar namespaces mediante una autorización explícita de ambas partes. Documentación oficial sobre enrutamiento entre namespaces.

¿Cuándo conviene utilizar Gateway API?

Gateway API resulta especialmente útil cuando se necesita:

  • Compartir una misma dirección IP o balanceador entre varios equipos.
  • Separar la administración de red del despliegue de aplicaciones.
  • Enrutar tráfico por hostname, path, encabezados o método HTTP.
  • Distribuir solicitudes entre distintas versiones mediante pesos.
  • Centralizar listeners y certificados TLS.
  • Migrar gradualmente desde Ingress por dominio o aplicación.

La disponibilidad de filtros, políticas y funciones avanzadas depende del controlador. Antes de diseñar una ruta, comprueba la matriz de compatibilidad de la implementación elegida.

Arquitectura del ejemplo

El procedimiento utilizará dos namespaces:

  • infra-ns: contiene el Gateway administrado por infraestructura.
  • app-ns: contiene el HTTPRoute, el Service y los Pods de la aplicación.

El flujo de tráfico será:

Cliente → Gateway → HTTPRoute → Service → Pods

GatewayClass no se encuentra en el flujo de datos: es el recurso de ámbito de clúster que indica qué controlador debe gestionar el Gateway.

Ver la Imagen 1: arquitectura compartida entre namespaces.

Requisitos previos

Antes de comenzar, verifica que dispones de:

  • Un clúster Kubernetes operativo.
  • Los CRD de Gateway API instalados.
  • Un controlador compatible, como NGINX Gateway Fabric, Envoy Gateway o Istio.
  • kubectl configurado con permisos para consultar y crear los recursos utilizados.
  • Un Service llamado api en app-ns, escuchando en el puerto 8080.
  • Un mecanismo para asignar una dirección externa al Gateway.

El DNS todavía no es obligatorio: primero se debe obtener y probar la dirección publicada por el Gateway. Después podrá crearse el registro para api.ejemplo.com.

Paso 1. Verificar los CRD y el controlador

Comprueba que estén disponibles los recursos utilizados por la guía:

kubectl get crd gatewayclasses.gateway.networking.k8s.io
kubectl get crd gateways.gateway.networking.k8s.io
kubectl get crd httproutes.gateway.networking.k8s.io

Luego consulta las clases existentes:

kubectl get gatewayclass
kubectl describe gatewayclass NOMBRE_DE_LA_CLASE

La GatewayClass elegida debe existir y mostrar la condición Accepted=True. El nombre depende del controlador y de cómo fue instalado; no debe asumirse que siempre será nginx.

También puedes comprobar los permisos actuales:

kubectl auth can-i create gateways.gateway.networking.k8s.io -n infra-ns
kubectl auth can-i create httproutes.gateway.networking.k8s.io -n app-ns

Si no aparece ninguna GatewayClass, instalar únicamente los CRD no será suficiente: también se necesita un controlador que observe y materialice la configuración.

Paso 2. Crear y autorizar los namespaces

Crea un archivo namespaces.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: infra-ns
---
apiVersion: v1
kind: Namespace
metadata:
  name: app-ns
  labels:
    shared-gateway-access: "true"

Aplícalo:

kubectl apply -f namespaces.yaml

La etiqueta de app-ns será utilizada por allowedRoutes. Así, solo los namespaces autorizados podrán asociar rutas al Gateway compartido.

Paso 3. Configurar el Gateway compartido

Crea gateway.yaml y reemplaza nombre-de-la-clase por una GatewayClass real obtenida en el paso anterior:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: web-gateway
  namespace: infra-ns
spec:
  gatewayClassName: nombre-de-la-clase
  listeners:
    - name: http
      hostname: api.ejemplo.com
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              shared-gateway-access: "true"
        kinds:
          - group: gateway.networking.k8s.io
            kind: HTTPRoute

El listener acepta únicamente rutas HTTP procedentes de namespaces que tengan la etiqueta indicada. Además, el hostname del HTTPRoute deberá intersectar con api.ejemplo.com para que la asociación sea válida. Documentación oficial sobre hostnames.

Valida el manifiesto en el API server antes de aplicarlo:

kubectl apply --dry-run=server -f gateway.yaml
kubectl diff -f gateway.yaml

kubectl diff puede finalizar con código 1 cuando encuentra diferencias; esto no significa necesariamente que el manifiesto sea inválido.

Si la configuración es correcta:

kubectl apply -f gateway.yaml

Paso 4. Comprobar el backend antes de publicar la ruta

Verifica que el Service exista en el mismo namespace donde se creará el HTTPRoute:

kubectl get service api -n app-ns
kubectl get endpointslice -n app-ns \
  -l kubernetes.io/service-name=api

El puerto declarado en backendRefs debe coincidir con spec.ports[].port del Service, no necesariamente con el containerPort del Pod.

Si no aparecen endpoints, revisa los selectores del Service, el estado de los Pods y sus readiness probes antes de continuar.

Paso 5. Publicar la ruta de la aplicación

Crea httproute.yaml:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api
  namespace: app-ns
spec:
  parentRefs:
    - name: web-gateway
      namespace: infra-ns
      sectionName: http
  hostnames:
    - api.ejemplo.com
  rules:
    - backendRefs:
        - name: api
          port: 8080

Los campos namespace y sectionName evitan ambigüedades: la ruta apunta al Gateway de infra-ns y específicamente al listener http.

No se necesita un ReferenceGrant para esta asociación. El acceso de una ruta a un Gateway de otro namespace se controla mediante parentRefs y allowedRoutes. ReferenceGrant se utiliza para otras referencias entre namespaces, por ejemplo cuando un HTTPRoute intenta usar un Service ubicado en un namespace diferente.

Valida y aplica la ruta:

kubectl apply --dry-run=server -f httproute.yaml
kubectl diff -f httproute.yaml
kubectl apply -f httproute.yaml

Gateway API permite que varias rutas se asocien a un mismo Gateway siempre que cumplan las restricciones del listener y no generen conflictos. Guía oficial de enrutamiento HTTP.

Paso 6. Verificar las condiciones

Empieza por el estado declarado en los recursos, antes de revisar logs:

kubectl describe gateway web-gateway -n infra-ns
kubectl describe httproute api -n app-ns

También puedes inspeccionar el estado completo:

kubectl get gateway web-gateway -n infra-ns -o yaml
kubectl get httproute api -n app-ns -o yaml

Comprueba principalmente:

  • Gateway: Accepted=True y Programmed=True.
  • HTTPRoute: Accepted=True y ResolvedRefs=True.
  • observedGeneration: debe coincidir con la generación actual del recurso.

Accepted=True no garantiza por sí solo que el backend exista. Una ruta puede ser aceptada y mostrar ResolvedRefs=False si el Service no se encuentra o la referencia no está permitida. Programmed=True indica que la configuración fue enviada al plano de datos, aunque la disponibilidad final todavía debe probarse con una solicitud. Guía oficial de estado y diagnóstico.

Ver la Imagen 2: secuencia de configuración, validación, aplicación y comprobación.

Paso 7. Obtener la dirección y probar el tráfico

Consulta la dirección publicada por el Gateway:

kubectl get gateway web-gateway -n infra-ns -o wide
kubectl get gateway web-gateway -n infra-ns \
  -o jsonpath='{range .status.addresses[*]}{.value}{"\n"}{end}'

Si el proveedor entrega una dirección IP, prueba el enrutamiento antes de modificar el DNS:

curl --resolve api.ejemplo.com:80:IP_DEL_GATEWAY \
  http://api.ejemplo.com/health

También puede utilizarse directamente el encabezado Host:

curl -H 'Host: api.ejemplo.com' \
  http://IP_DEL_GATEWAY/health

Una respuesta válida confirma el recorrido Gateway → HTTPRoute → Service → Pod. Finalmente, crea o actualiza el registro DNS de api.ejemplo.com y verificalo:

dig +short api.ejemplo.com
curl -i http://api.ejemplo.com/health

Ten en cuenta el TTL del registro: una respuesta DNS antigua puede deberse a caché y no a Kubernetes.

Distribución de tráfico por peso

Para una migración progresiva, una regla puede repartir solicitudes entre dos Services del mismo namespace:

rules:
  - backendRefs:
      - name: api-v1
        port: 8080
        weight: 90
      - name: api-v2
        port: 8080
        weight: 10

Los pesos expresan una proporción, no una garantía exacta para una cantidad pequeña de solicitudes. Verifica además que el controlador declare soporte para esta funcionalidad.

Seguridad y uso en producción

El listener HTTP del ejemplo simplifica las primeras pruebas. Para una publicación real, utiliza HTTPS y almacena el certificado como Secret en infra-ns:

listeners:
  - name: https
    hostname: api.ejemplo.com
    port: 443
    protocol: HTTPS
    tls:
      mode: Terminate
      certificateRefs:
        - kind: Secret
          name: api-ejemplo-tls

Además:

  • Limita allowedRoutes mediante selectores de namespace.
  • Aplica RBAC separado para Gateways y rutas.
  • No incluyas claves privadas ni credenciales dentro de manifiestos versionados.
  • Separa hostnames de producción, pruebas y desarrollo.
  • Revisa las funciones compatibles y el nivel de conformidad del controlador.
  • Versiona los manifiestos y revisa kubectl diff antes de aplicarlos.
  • Migra desde Ingress por dominio o aplicación y conserva un procedimiento de reversión.
  • Supervisa condiciones, direcciones, errores HTTP y disponibilidad de endpoints.

Problemas frecuentes

El HTTPRoute no muestra estado

Comprueba que parentRefs apunte a un Gateway existente y gestionado por el controlador. Una referencia a un padre inexistente puede dejar la ruta sin condiciones porque ningún controlador la considera dentro de su ámbito.

Accepted=False

Revisa:

  • El namespace indicado en parentRefs.
  • El nombre y sectionName del listener.
  • La etiqueta requerida por allowedRoutes.
  • La intersección entre el hostname del listener y el de la ruta.
  • Los eventos mostrados por kubectl describe.

ResolvedRefs=False

Verifica que el Service exista en el namespace del HTTPRoute, que el puerto sea correcto y que cualquier referencia entre namespaces cuente con el ReferenceGrant correspondiente.

El Gateway no tiene dirección

Comprueba GatewayClass, Accepted, Programmed y los eventos del Gateway. Algunos controladores requieren configuración adicional del proveedor o no crean automáticamente un balanceador externo.

El DNS resuelve, pero la aplicación no responde

Prueba primero con curl --resolve, revisa el listener y confirma que el Service tenga EndpointSlices listos. Un error de ruta, un backend sin endpoints y una aplicación que falla su health check requieren diagnósticos diferentes.

Conclusión

Gateway API permite compartir infraestructura de entrada sin entregar a todos los equipos control sobre el mismo recurso. El Gateway establece puertos, protocolos, dominios y límites de asociación; cada HTTPRoute declara cómo debe publicarse una aplicación.

La implementación resulta más segura y predecible cuando se sigue siempre la misma secuencia: configurar → validar → aplicar → comprobar.

Flujo de uso de API GW

Cloud Serversby Donweb

Todo el poder de la nube a tus proyectos y aplicaciones.
Alojamiento ultra rápido, escalable y con alta disponibilidad.

  • Performance que te sorprenderá
  • Rápida escalabilidad y sin limitaciones
  • Arquitectura de alta disponibilidad
  • Soporte experto y ejecutivos de cuenta
  • Pagos en tu moneda y facturación local

Descubre la mejor solución de Cloud Hosting