Ir al contenido
Volver a Tutoriales

Cómo Desplegar un AI Gateway en Kubernetes para Cargas de Trabajo de Inferencia

Intermedio · 1 hour · 25 min de lectura · Byte Smith ·

Antes de comenzar

  • Un clúster de Kubernetes con un controlador compatible con Gateway API instalado
  • Al menos un servicio de inferencia o endpoint de modelo ya desplegado
  • Acceso al clúster con permisos para crear Namespaces, recursos de Gateway API y NetworkPolicies
  • Un stack de observabilidad básico como Prometheus, OpenTelemetry o métricas nativas del controlador
  • Un entorno de staging o namespace aislado donde puedas probar escenarios de ráfaga y fallo

Lo que aprenderás

  • Identificar qué patrones de tráfico de IA necesitan comportamiento diferente en el gateway
  • Diseñar un AI gateway v1 mínimo sin sobreingeniería
  • Desplegar una capa de entrada básica con Gateway API para servicios de inferencia
  • Añadir enrutamiento por versión de modelo, límites por tenant y controles de despliegue
  • Aplicar timeouts, pensamiento de contrapresión y observabilidad para tráfico de inferencia
  • Asegurar el gateway con límites de namespace, red y auditoría
  • Probar el diseño con tráfico de ráfaga, solicitudes mixtas y fallos controlados
1
2
3
4
5
6
7
8
9
10
En esta página

El tráfico de IA no es simplemente “tráfico API normal con JSON más grande.” Las solicitudes de inferencia son a menudo más costosas, más sensibles a la latencia, de mayor duración y más variables que el tráfico web estándar. Las respuestas en streaming mantienen conexiones abiertas. Los agentes que llaman herramientas generan ráfagas de solicitudes más pequeñas. La inferencia por lotes puede parecer rendimiento en segundo plano en lugar de latencia interactiva. Y en muchos entornos, el gateway también se convierte en el lugar donde el control de acceso a modelos, el control de costos y los límites por tenant comienzan a importar.

Por eso los equipos de plataforma en Kubernetes deberían preocuparse ahora. El Kubernetes AI Gateway Working Group se lanzó específicamente para definir estándares y mejores prácticas para infraestructura de red que soporte cargas de trabajo de IA, y el proyecto oficial Gateway API Inference Extension ya está trabajando en enrutamiento consciente de modelos, selección de endpoints y otros patrones específicos de inferencia sobre Gateway API. En otras palabras, esto ya no es solo una categoría de producto de un proveedor específico. Se está convirtiendo en una preocupación de la plataforma Kubernetes.

Este tutorial muestra cómo construir un AI gateway v1 práctico en Kubernetes sin pretender que los estándares son más maduros de lo que realmente son. Desplegarás una capa de entrada básica con Gateway API, enrutarás solicitudes a servicios de inferencia, añadirás patrones conscientes de versión de modelo y tenant, ajustarás controles de fiabilidad, añadirás observabilidad, asegurarás el diseño y luego lo probarás bajo carga realista. El objetivo no es construir el gateway de inferencia más avanzado posible en el primer día. El objetivo es construir una línea base de plataforma limpia que puedas evolucionar de forma segura. Para contexto más amplio sobre cómo la red de Kubernetes se está adaptando para cargas de trabajo de IA, consulta Kubernetes AI Workloads and Networking.

Paso 1: Identifica tus tipos de tráfico de IA

Antes de escribir cualquier regla de enrutamiento, decide qué tipos de tráfico de inferencia tienes realmente. Kubernetes ahora tiene un esfuerzo oficial de AI Gateway porque las cargas de trabajo de IA introducen patrones de tráfico que necesitan comportamiento de red diferente, incluyendo rate limiting consciente de tokens, inspección de payloads, enrutamiento específico de IA y protocolos específicos de IA. El proyecto de extensión de inferencia va aún más lejos e introduce conceptos como enrutamiento consciente de modelos, prioridades de servicio, selección de endpoints y planificación consciente de latencia basada en métricas del servidor de modelos.

Clasifica la inferencia interactiva

La inferencia interactiva es lo que la mayoría de equipos piensa primero: completaciones de chat, resumen, embeddings bajo demanda, UX de asistente y llamadas similares orientadas al usuario. Estas solicitudes son normalmente sensibles a:

  • latencia de extremo a extremo
  • tiempo hasta el primer token
  • continuidad del streaming
  • selección de modelo
  • cuotas por tenant

Si tienes tráfico interactivo, tu gateway debería estar optimizado para comportamiento de respuesta predecible y despliegue controlado en lugar de solo máximo rendimiento.

Clasifica la inferencia por lotes

La inferencia por lotes normalmente se ve diferente:

  • ráfagas más grandes
  • menos sensibilidad a la latencia del primer token
  • más tolerancia al encolamiento
  • más énfasis en rendimiento y equidad
  • patrones de ejecución programados o asíncronos

No querrás ajustar todo tu gateway alrededor del chat interactivo si la mitad de tu carga son embeddings offline o trabajos de enriquecimiento nocturnos.

Clasifica los agentes que llaman herramientas

Los agentes que llaman herramientas a menudo producen tráfico fácil de subestimar:

  • muchas llamadas pequeñas
  • ráfagas después de fases de planificación
  • reintentos del llamador si un paso de herramienta falla
  • cargas mixtas entre múltiples modelos o endpoints

Esto importa porque el gateway puede necesitar cuotas más estrictas, consciencia de idempotencia o observabilidad más fuerte por ruta y por tenant.

Clasifica las respuestas en streaming

El streaming de inferencia es donde los equipos tienen problemas más rápido. Gateway API ahora tiene soporte estándar para timeouts de ruta, pero el soporte de reintentos aún está en evolución activa y es especialmente matizado alrededor de patrones de streaming o bidireccionales. Trata los streams de larga duración como una clase distinta, no solo “la misma ruta con un body diferente.”

Crea un documento simple de clasificación de tráfico antes de continuar.

Archivo: traffic-profile.yaml

interactive_inference:
  examples:
    - chat-completions
    - real-time-summarization
  latency_sensitive: true
  streaming: true
  retry_friendly: false

batch_inference:
  examples:
    - offline-embeddings
    - nightly-document-labeling
  latency_sensitive: false
  streaming: false
  retry_friendly: true

tool_calling_agents:
  examples:
    - planner-executor-agents
    - retrieval-agents
  latency_sensitive: mixed
  streaming: mixed
  retry_friendly: mixed

streaming_responses:
  examples:
    - server-sent-events
    - token-streaming-chat
  latency_sensitive: true
  streaming: true
  retry_friendly: false
Consejo

Mantén la primera versión de tu gateway con opiniones firmes sobre las clases de tráfico. Una ruta que sirve chat de baja latencia no debería heredar los mismos supuestos de timeout y contrapresión que un trabajo de embedding en segundo plano.

Ahora deberías tener un perfil de tráfico que te dice qué rutas necesitan baja latencia, cuáles pueden tolerar encolamiento y cuáles deberían evitar reintentos por completo.

Paso 2: Decide qué debe hacer el gateway

Un gateway se vuelve desordenado cuando asume responsabilidades por accidente. El esfuerzo de Kubernetes AI Gateway enmarca explícitamente los AI gateways como infraestructura que puede aplicar políticas, control de acceso, inspección de payloads, limitación consciente de tokens y enrutamiento específico de IA. Eso no significa que tu primera versión debería hacer todas esas cosas a la vez. Significa que deberías decidir el alcance por adelantado.

Comienza con un conjunto pequeño de responsabilidades

Para una primera versión, tu AI gateway normalmente debería hacer estas cosas:

  • exponer uno o más puntos de entrada estables
  • enrutar solicitudes al servicio de inferencia correcto
  • aislar tenants o entornos
  • aplicar límites básicos de autenticación y admisión
  • emitir logs y métricas fiables
  • soportar despliegues seguros de modelos

Lo que normalmente no debería hacer en v1:

  • realizar inspección semántica completa de prompts inline
  • convertirse en tu único sistema de cuotas
  • implementar cada patrón de fallback de proveedor
  • ocultar todo el comportamiento del servidor de modelos del equipo de aplicación

Define las dimensiones de enrutamiento

La mayoría de equipos necesitan una o más de estas:

  • enrutar por familia de modelo como chat versus embeddings
  • enrutar por versión de modelo como v1 versus v2
  • enrutar por tenant usando hostnames, paths o headers
  • enrutar por clase de tráfico como interactivo versus lote

Escribe la política. No la dejes dentro de valores de Helm o defaults del controlador.

Archivo: ai-gateway-responsibilities.yaml

entrypoints:
  - tenant-hostnames
  - shared-api-domain

routing_dimensions:
  - route_by_path
  - route_by_model_version
  - route_by_tenant

required_controls:
  - authn
  - authz
  - request_logging
  - per_route_timeouts
  - rollout_support

deferred_for_v2:
  - semantic_payload_inspection
  - provider_failover
  - token_based_rate_limiting
  - body_based_model_routing

Decide si el gateway o un servicio router posee la selección de modelo

Esta es una de las decisiones de diseño más importantes.

Si tus clientes llaman a endpoints distintos como /v1/chat/completions y /v1/embeddings, el HTTPRoute estándar es suficiente para un buen diseño v1. Si tus clientes envían una solicitud compatible con OpenAI donde el nombre del modelo solo está en el body de la solicitud, Gateway API estándar por sí solo no es suficiente para enrutamiento consciente de modelos. Eso es precisamente por qué el proyecto de extensión de inferencia introduce enrutamiento basado en body y patrones de selección de endpoints.

Para v1, elige una de estas opciones:

  • Enrutamiento simple por path o hostname si tu superficie API ya separa las cargas de trabajo limpiamente
  • Un servicio router interno liviano si el nombre del modelo solo existe en el body y quieres mantener la API externa estable
  • Una extensión consciente de inferencia más adelante, si el enrutamiento basado en body vale la complejidad
Nota

Si tu API es compatible con OpenAI y el nombre del modelo vive en el body JSON, no pretendas que las reglas simples de Gateway basadas en path pueden resolver el enrutamiento consciente de modelos por sí solas.

Ahora deberías saber qué posee tu gateway, qué no posee, y si la elección de modelo ocurre en reglas estándar de Gateway, en un servicio router o en una capa consciente de inferencia más avanzada después.

Paso 3: Despliega una capa de gateway básica

El lugar más limpio para empezar es un Gateway compartido en un namespace de plataforma, servicios de modelo en un namespace de servicio de modelos y rutas de tenant en namespaces de tenant. Gateway API está diseñado para este tipo de separación, y el enrutamiento entre namespaces es un patrón de primera clase. Cuando una ruta apunta a un backend en otro namespace, el namespace destino debe permitirlo explícitamente con un ReferenceGrant.

Crea namespaces y labels

Archivo: namespaces.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: ai-gateway
---
apiVersion: v1
kind: Namespace
metadata:
  name: ai-models
---
apiVersion: v1
kind: Namespace
metadata:
  name: tenant-a
  labels:
    ai-routes: "enabled"

Aplícalos:

kubectl apply -f namespaces.yaml

Crea el Gateway compartido

Este ejemplo asume que tu controlador ya instaló un GatewayClass. Reemplaza your-gateway-class con el nombre real de la clase de tu entorno.

Archivo: gateway.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: ai-shared-gateway
  namespace: ai-gateway
spec:
  gatewayClassName: your-gateway-class
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      hostname: "*.ai.example.com"
      tls:
        mode: Terminate
        certificateRefs:
          - name: ai-example-com-tls
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              ai-routes: "enabled"

Aplícalo:

kubectl apply -f gateway.yaml
kubectl get gateway -n ai-gateway

Expón tus servicios de inferencia

Este tutorial asume que ya tienes Deployments de servicio de modelos ejecutándose. Crea Services estables para ellos.

Archivo: model-services.yaml

apiVersion: v1
kind: Service
metadata:
  name: chat-llama3-8b-v1
  namespace: ai-models
spec:
  selector:
    app: chat-llama3-8b-v1
  ports:
    - name: http
      port: 8000
      targetPort: 8000
---
apiVersion: v1
kind: Service
metadata:
  name: embed-bge-small-v1
  namespace: ai-models
spec:
  selector:
    app: embed-bge-small-v1
  ports:
    - name: http
      port: 8000
      targetPort: 8000

Aplícalo:

kubectl apply -f model-services.yaml

Permite referencias de backend entre namespaces

Debido a que el HTTPRoute vivirá en tenant-a y los backends viven en ai-models, necesitas un ReferenceGrant en el namespace del backend.

Archivo: referencegrant.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
  name: allow-tenant-a-routes
  namespace: ai-models
spec:
  from:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      namespace: tenant-a
  to:
    - group: ""
      kind: Service

Aplícalo:

kubectl apply -f referencegrant.yaml

Crea el HTTPRoute inicial

Archivo: tenant-a-routes.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: tenant-a-inference
  namespace: tenant-a
spec:
  parentRefs:
    - name: ai-shared-gateway
      namespace: ai-gateway
      sectionName: https
  hostnames:
    - "tenant-a.ai.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /v1/chat/completions
      backendRefs:
        - name: chat-llama3-8b-v1
          namespace: ai-models
          port: 8000
    - matches:
        - path:
            type: PathPrefix
            value: /v1/embeddings
      backendRefs:
        - name: embed-bge-small-v1
          namespace: ai-models
          port: 8000

Aplícalo y verifica:

kubectl apply -f tenant-a-routes.yaml
kubectl get httproute -n tenant-a
kubectl describe httproute tenant-a-inference -n tenant-a
Info

Usa HTTPRoute para APIs HTTP o compatibles con OpenAI, y GRPCRoute cuando tu ruta de servicio sea realmente nativa de gRPC. Ambos son GA, pero mantén gRPC y HTTP regular en hostnames separados cuando sea posible para operaciones más limpias.

Ahora deberías tener un AI gateway compartido básico, dos Services de servicio de modelos y una ruta de tenant que reenvía tráfico de chat y embeddings a través de Gateway API.

Paso 4: Añade enrutamiento consciente de IA

Ahora que la línea base funciona, añade los tipos de enrutamiento que importan específicamente para inferencia. El proyecto oficial de extensión de inferencia se enfoca en enrutamiento consciente de modelos, prioridad de servicio, despliegues y selección de endpoints basada en métricas del servidor de modelos como estado de caché y profundidad de cola. Esa es la dirección a largo plazo. Para v1, mantenlo más simple: usa Gateway API para despliegue de versión de modelo y límites de tenant primero, y solo introduce enrutamiento basado en body o selección de endpoints cuando tengas una necesidad clara.

Añade enrutamiento canary por versión de modelo

Gateway API soporta división de tráfico ponderada a través de backendRefs, lo que lo hace una buena opción para despliegues de modelos.

Archivo: tenant-a-chat-canary.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: tenant-a-chat-canary
  namespace: tenant-a
spec:
  parentRefs:
    - name: ai-shared-gateway
      namespace: ai-gateway
      sectionName: https
  hostnames:
    - "tenant-a.ai.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /v1/chat/completions
      backendRefs:
        - name: chat-llama3-8b-v1
          namespace: ai-models
          port: 8000
          weight: 90
        - name: chat-llama3-8b-v2
          namespace: ai-models
          port: 8000
          weight: 10

Esta es la forma más limpia de hacer despliegues de modelos cuando la API externa permanece igual y solo la implementación del servicio cambia.

Añade aislamiento de tenant por hostname o propiedad de rutas

La guía de multi-tenancy de Kubernetes recomienda límites de namespace, RBAC, cuotas y políticas de red como controles fundamentales para clústeres compartidos. En la práctica, el modelo de aislamiento de AI gateway más fácil es:

  • un Gateway compartido
  • un namespace propietario de rutas por tenant o equipo de aplicación
  • un namespace de servicio de modelos o namespaces de modelos por tenant donde sea necesario
  • ReferenceGrant explícito donde se permita acceso entre namespaces

Eso mantiene la propiedad del enrutamiento de tenant separada de los puntos de entrada propiedad de la plataforma.

Mantén el fallback simple en v1

El verdadero fallback de inferencia es más sutil que el failover HTTP normal. Puedes querer hacer fallback de una versión de modelo a otra, de un pool a otro, o de inferencia auto-hospedada a un proveedor externo. Las propuestas activas de egress del AI Gateway Working Group están explícitamente dirigidas a servicios de IA externos, failover, enrutamiento de cumplimiento e inyección segura de tokens, lo que te dice que esta es aún un área de estándar en evolución.

Para v1, usa una de estas opciones:

  • un servicio router dedicado detrás de tu Gateway para lógica de fallback compleja
  • una ruta específica de modelo con una división canary controlada
  • una extensión de inferencia específica de la implementación si ya te comprometiste con ese stack

Un patrón limpio es mantener la ruta pública estable y enviar la lógica de fallback compleja a un servicio router interno:

Archivo: tenant-a-chat-router.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: tenant-a-chat-router
  namespace: tenant-a
spec:
  parentRefs:
    - name: ai-shared-gateway
      namespace: ai-gateway
      sectionName: https
  hostnames:
    - "tenant-a.ai.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /v1/chat/completions
      backendRefs:
        - name: llm-router
          namespace: tenant-a
          port: 8080

Ese router puede tomar decisiones de fallback conscientes de políticas sin forzar cada preocupación de inferencia en YAML de Gateway.

Consejo

Gateway API es excelente en puntos de entrada estables, divisiones de tráfico para despliegue y límites de propiedad. Úsalo para eso primero. Añade enrutamiento consciente de body o selección de endpoints solo cuando tu tráfico realmente lo necesite.

Ahora deberías tener una forma de hacer despliegue seguro de versión de modelo, un patrón claro de aislamiento de tenant y una posición realista de v1 sobre la lógica de fallback.

Paso 5: Añade controles de fiabilidad

El tráfico de inferencia falla de forma diferente a una API CRUD normal. Algunas solicitudes son costosas y de larga duración. Algunos streams nunca deberían reintentarse automáticamente. Algunos servidores de modelos encolan internamente antes de responder. Eso significa que la fiabilidad es una mezcla de configuraciones del gateway y comportamiento del servidor de modelos.

Establece timeouts explícitos de ruta

Gateway API ahora proporciona campos estándar de timeout de ruta en reglas HTTPRoute. Úsalos. No dejes rutas de inferencia críticas completamente en los defaults del controlador.

Archivo: tenant-a-route-timeouts.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: tenant-a-inference-with-timeouts
  namespace: tenant-a
spec:
  parentRefs:
    - name: ai-shared-gateway
      namespace: ai-gateway
      sectionName: https
  hostnames:
    - "tenant-a.ai.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /v1/chat/completions
      timeouts:
        request: 120s
        backendRequest: 115s
      backendRefs:
        - name: chat-llama3-8b-v1
          namespace: ai-models
          port: 8000
    - matches:
        - path:
            type: PathPrefix
            value: /v1/embeddings
      timeouts:
        request: 30s
        backendRequest: 25s
      backendRefs:
        - name: embed-bge-small-v1
          namespace: ai-models
          port: 8000

Estos números son ejemplos. Los valores correctos dependen de tus modelos y las expectativas de los usuarios. El punto importante es que chat y embeddings no deberían heredar la misma política de timeout ciegamente.

Sé conservador con los reintentos

El trabajo de reintentos de Gateway existe, pero es aún un área donde la semántica varía y el streaming es especialmente complicado. Para chat en streaming, por defecto no hagas reintentos automáticos del gateway a menos que hayas probado explícitamente el comportamiento de extremo a extremo. Para solicitudes idempotentes no-streaming como algunas cargas de trabajo de embedding, reintentos limitados pueden ser aceptables si tu implementación los soporta y la semántica de tu backend es segura.

Añade controles básicos de fiabilidad del backend

No te enfoques solo en el gateway. Tus cargas de trabajo de servicio de modelos también necesitan comportamiento estable ante interrupciones.

Archivo: chat-pdb.yaml

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: chat-llama3-8b-v1
  namespace: ai-models
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: chat-llama3-8b-v1

Esto no resolverá la sobrecarga, pero te protege de interrupciones voluntarias evitables durante mantenimiento.

Decide dónde viven el encolamiento y la contrapresión

Para v1, la regla más segura es:

  • Gateway: aplica límites a nivel de conexión y ruta
  • Servidor de modelo o router: posee las decisiones de encolamiento y descarte de solicitudes
  • Autoescalado: reacciona a señales de demanda reales donde sea posible

Si tu stack soporta visibilidad de cola consciente de inferencia o selección de endpoints más adelante, puedes evolucionar hacia ello. El proyecto de extensión de inferencia está específicamente construido alrededor de selección de endpoints y métricas del servidor de modelos como longitud de cola y estado de caché, lo cual es una señal fuerte de que el balanceo de carga L7 genérico no es suficiente para cargas de trabajo de inferencia maduras.

Advertencia

No habilites reintentos en rutas de streaming solo porque tu controlador soporta reintentos en algún lugar. Los fallos de streaming a menudo necesitan recuperación consciente del llamador, no replay ciego.

Ahora deberías tener timeouts explícitos, una posición conservadora de reintentos y una separación clara entre los controles de fiabilidad del gateway y el comportamiento de contrapresión del servidor de modelos.

Paso 6: Añade observabilidad

Un AI gateway sin observabilidad se convierte en un amplificador de costos y un cuello de botella para debugging. Como mínimo, necesitas entender:

  • volumen de solicitudes
  • latencia de solicitudes
  • tasa de fallos
  • distribución por tenant
  • distribución por modelo
  • streaming versus no-streaming
  • señales de tokens y costos cuando estén disponibles

El trabajo oficial de extensión de inferencia también destaca métricas del servidor de modelos, objetivos estilo time-to-first-token y decisiones de planificación conscientes de modelos, lo cual es una buena señal de lo que la observabilidad madura necesitará incluir.

Estandariza un contrato de log del gateway

Aunque tu pipeline exacto de métricas cambie después, define un contrato de log estructurado ahora.

Archivo: gateway-log-example.json

{
  "timestamp": "2026-03-10T15:22:11.418Z",
  "request_id": "req_01JPN8XQZ0Y1M0AX3R0D4M9J7E",
  "tenant": "tenant-a",
  "hostname": "tenant-a.ai.example.com",
  "route": "/v1/chat/completions",
  "model_route": "chat-llama3-8b-v1",
  "stream": true,
  "http_status": 200,
  "latency_ms": 1840,
  "ttft_ms": 420,
  "prompt_tokens": 612,
  "completion_tokens": 238,
  "estimated_cost_usd": 0.0194,
  "gateway_backend": "chat-llama3-8b-v1.ai-models.svc.cluster.local:8000"
}

Si no puedes obtener cada campo en el primer día, está bien. Pero tenant, ruta, backend, estado, latencia y stream/no-stream deberían estar presentes desde el inicio.

Crea reglas de grabación para métricas propias

Si operas una capa de router o adaptador personalizada, exporta tus propias métricas con nombres y labels estables.

Archivo: prometheus-rules.yaml

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: ai-gateway-recording-rules
  namespace: ai-gateway
spec:
  groups:
    - name: ai-gateway.rules
      rules:
        - record: ai_gateway:requests_per_second
          expr: sum(rate(ai_gateway_requests_total[5m])) by (tenant, route, model_route)
        - record: ai_gateway:error_rate
          expr: sum(rate(ai_gateway_requests_total{status=~"5.."}[5m])) by (tenant, route, model_route)
        - record: ai_gateway:p95_latency_ms
          expr: histogram_quantile(0.95, sum(rate(ai_gateway_request_duration_ms_bucket[5m])) by (le, tenant, route, model_route))

Estos son nombres de métricas de ejemplo para tu adaptador o telemetría del gateway. La fuente exacta puede ser tu controlador, tu servicio router, o ambos.

Rastrea métricas del gateway y del backend por separado

Mantén estas categorías distintas:

  • latencia de solicitud del gateway
  • latencia del modelo backend
  • profundidad de cola
  • saturación o descarte
  • rendimiento de tokens
  • costo o costo estimado
  • tasa de éxito por modelo

Si mezclas todo en un solo número de “latencia de IA”, no sabrás si el problema es el enrutamiento, el controlador, el servidor de modelos o la presión de GPU upstream.

Info

La observabilidad de inferencia no es solo observabilidad HTTP. Necesitas suficiente contexto para responder: qué tenant, qué ruta, qué modelo, qué latencia, cuántos tokens y cuánto costó.

Ahora deberías tener un plan de observabilidad estructurado que cubre comportamiento del gateway, comportamiento del modelo y visibilidad de costos a nivel de tenant o modelo.

Paso 7: Asegúralo

Tu AI gateway es tanto un límite de red como un límite de políticas. Eso lo convierte en un lugar natural para aplicar acceso, separación de tenants y visibilidad de auditoría. La propia guía de multi-tenancy de Kubernetes enfatiza namespaces, RBAC, cuotas y políticas de red como bloques de construcción fundamentales para aislar tenants y evitar problemas de vecino ruidoso o sobre-permisos en clústeres compartidos.

Aísla los servicios de modelo del resto del clúster

No dejes que cada carga de trabajo llame directamente a tu namespace de servicio de modelos. Usa una NetworkPolicy para que solo el namespace del gateway pueda alcanzar los pods de servicio de modelos.

Archivo: model-networkpolicy.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: only-gateway-to-models
  namespace: ai-models
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ai-gateway
      ports:
        - protocol: TCP
          port: 8000

Aplícalo:

kubectl apply -f model-networkpolicy.yaml

Pon presupuestos de tenant en algún lugar explícito

Las cuotas de solicitudes o tokens son a menudo específicas del controlador o de la aplicación, pero aún deberías aislar el consumo de recursos del tenant a nivel de namespace.

Archivo: tenant-a-quota.yaml

apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-a-ai-quota
  namespace: tenant-a
spec:
  hard:
    requests.cpu: "20"
    requests.memory: 64Gi
    limits.cpu: "40"
    limits.memory: 128Gi
    pods: "50"

Esta no es una cuota de solicitudes por minuto. Es un límite de equidad del clúster. Mantén las cuotas a nivel de tráfico en tu capa de gateway o router, pero no olvides la equidad a nivel de clúster.

Haz la autenticación y auditoría explícitas

La autenticación y autorización en el gateway dependerán de tu implementación. Algunos stacks usarán JWT o política de mTLS adjunta. Otros usarán servicios de autenticación externos. Tu línea base de seguridad mínima aún debería ser la misma:

  • autenticar llamadores antes del acceso a inferencia
  • autorizar por tenant y ruta
  • registrar quién llamó a qué
  • evitar pasar contenido sensible de prompts crudos en logs amplios
  • registrar suficientes metadatos de auditoría para reconstruir el acceso después

Un contrato de auditoría simple es suficiente para empezar.

Archivo: audit-log-example.json

{
  "timestamp": "2026-03-10T15:40:02.112Z",
  "tenant": "tenant-a",
  "subject": "svc:agent-platform",
  "route": "/v1/chat/completions",
  "model_route": "chat-llama3-8b-v1",
  "decision": "allow",
  "request_id": "req_01JPN92C7S49YJ1E0QY6T5G6P3",
  "sensitive_payload_logged": false
}

Protege datos sensibles de prompts y respuestas

Para v1, mantén esto simple:

  • no registres prompts completos por defecto
  • no registres respuestas de streaming completas por defecto
  • redacta secretos o identificadores obvios en middleware donde sea posible
  • reserva la inspección de payloads para casos de uso de políticas explícitas

El AI Gateway Working Group está trabajando activamente en propuestas de procesamiento de payloads y guardrails de tráfico de IA, lo cual es un indicador fuerte de que la inspección inline de prompts/respuestas es territorio real de plataforma, pero sigue siendo un área de estándar emergente. No lo sobrediseñes en el primer día.

Advertencia

Tu gateway debería poder responder “quién llamó a qué ruta de modelo y qué pasó” sin almacenar prompts o respuestas completas en logs de propósito general.

Ahora deberías tener aislamiento de red alrededor de servicios de modelo, límites de tenant a nivel de namespace y un punto de partida claro para controles de autenticación y auditoría.

Paso 8: Prueba con una carga de trabajo realista

Ahora valida el diseño bajo condiciones que se parezcan más a producción. El tráfico de IA rara vez es uniforme. Quieres tráfico de ráfaga, rutas mixtas, streaming y al menos un fallo de backend.

Envía tráfico de ráfaga a una ruta no-streaming

Crea un payload de embeddings.

Archivo: embeddings.json

{
  "input": [
    "hello world",
    "design a safe ai gateway on kubernetes",
    "measure latency, error rate, and cost"
  ],
  "model": "bge-small"
}

Ejecuta una prueba de ráfaga:

export GATEWAY_ADDR=http://YOUR_GATEWAY_ADDRESS
hey -n 200 -c 20 \
  -m POST \
  -T application/json \
  -H "Host: tenant-a.ai.example.com" \
  -D embeddings.json \
  ${GATEWAY_ADDR}/v1/embeddings

Esto valida el manejo de ráfagas en una ruta que es generalmente más segura para reintentar y más fácil de comparar entre ejecuciones.

Prueba el comportamiento de streaming explícitamente

Crea una solicitud de streaming.

Archivo: chat-stream.json

{
  "model": "llama3-8b",
  "stream": true,
  "messages": [
    { "role": "user", "content": "Explain why AI gateways need different timeout and routing rules." }
  ]
}

Ejecútalo:

curl -N \
  -H "Host: tenant-a.ai.example.com" \
  -H "Content-Type: application/json" \
  -X POST \
  --data @chat-stream.json \
  ${GATEWAY_ADDR}/v1/chat/completions

Observa:

  • tiempo hasta el primer token
  • continuidad estable del stream
  • desconexiones prematuras
  • sorpresas de buffering del proxy
  • comportamiento incorrecto de timeout

Mezcla rutas y tipos de tráfico

Un bucle shell simple es suficiente para la primera validación.

for i in $(seq 1 20); do
  curl -s \
    -H "Host: tenant-a.ai.example.com" \
    -H "Content-Type: application/json" \
    -X POST \
    --data @embeddings.json \
    ${GATEWAY_ADDR}/v1/embeddings > /dev/null &

  curl -s \
    -H "Host: tenant-a.ai.example.com" \
    -H "Content-Type: application/json" \
    -X POST \
    --data @chat-stream.json \
    ${GATEWAY_ADDR}/v1/chat/completions > /dev/null &
done

wait

Esto no es un benchmark perfecto. Es suficiente para detectar desajustes de rutas, saturación y comportamiento por defecto pobre.

Inyecta un fallo de backend

Ahora prueba que tus timeouts, división de despliegue y observabilidad se comportan como crees.

kubectl -n ai-models scale deployment chat-llama3-8b-v2 --replicas=0
kubectl -n ai-models get pods -w

Luego envía tráfico de nuevo y observa:

  • la ruta canary falló solo para la porción canary
  • el gateway devolvió los errores correctos
  • los logs identificaron el backend limpiamente
  • las rutas de streaming colgaron más de lo esperado
  • tus métricas separaron el fallo del gateway del fallo del backend
Consejo

No llames a un gateway listo para producción hasta que lo hayas visto manejar una ráfaga, un stream y un backend fallando en el mismo entorno.

Ahora deberías tener evidencia de que el gateway funciona bajo carga de ráfaga, uso mixto de rutas y fallo controlado, en lugar de solo bajo pruebas curl de camino feliz.

Problemas Comunes de Configuración

Tratar el AI gateway como ingress ordinario

Síntomas:

  • un timeout genérico para todo
  • sin distinción entre chat y embeddings
  • las rutas de streaming se caen inesperadamente
  • el comportamiento de despliegue es demasiado grueso

Causa raíz: el gateway fue diseñado como un web ingress normal en lugar de una capa de entrada de inferencia.

Solución: clasifica los tipos de tráfico primero, separa rutas interactivas y de lotes, y trata el streaming como su propia clase.

Intentar enrutar por nombre de modelo sin una capa consciente de modelos

Síntomas:

  • los clientes envían el modelo en el body de la solicitud
  • las reglas de Gateway no pueden seleccionar backends correctamente
  • los equipos empiezan a codificar variantes de path incómodas

Causa raíz: las reglas estándar de Gateway no parsean bodies JSON para enrutamiento por sí solas.

Solución: mantén v1 basado en path o hostname, añade un servicio router liviano, o adopta una extensión consciente de inferencia deliberadamente después.

ReferenceGrant faltante para backends entre namespaces

Síntomas:

  • HTTPRoute existe pero no puede resolver referencias de backend
  • el tráfico nunca llega a los servicios de modelo

Causa raíz: el namespace de la ruta puede ver el Gateway compartido, pero el namespace del backend nunca otorgó acceso de referencia entre namespaces.

Solución: añade un ReferenceGrant en el namespace del backend para el namespace fuente y tipo específico.

Reintentos habilitados en rutas de streaming

Síntomas:

  • outputs parciales duplicados
  • comportamiento extraño del cliente durante fallos
  • tasas de éxito engañosas

Causa raíz: la lógica de reintentos se aplicó como si el tráfico de streaming se comportara como solicitudes cortas idempotentes.

Solución: deshabilita o restringe estrictamente los reintentos en rutas de streaming, y deja que el llamador maneje el replay donde sea necesario.

Sin labels de tenant o modelo en logs y métricas

Síntomas:

  • la latencia se ve mal, pero nadie sabe para quién
  • los costos están aumentando, pero no hay visibilidad a nivel de ruta
  • los problemas de despliegue son difíciles de localizar

Causa raíz: la observabilidad se añadió solo como telemetría HTTP genérica.

Solución: registra y etiqueta por tenant, ruta, backend, ruta de modelo y flag de stream desde el primer día.

Conclusión

Un buen AI gateway v1 en Kubernetes no es una plataforma personalizada gigante. Es una capa de entrada limpia con Gateway API con propiedad explícita, rutas estables, controles de despliegue seguros, aislamiento sólido y suficiente observabilidad para entender latencia, fallos y costos. Mantén la primera versión simple: separa clases de tráfico, enruta claramente, aísla tenants, establece timeouts explícitos y verifica el comportamiento con tráfico real.

Pasa a una arquitectura más avanzada cuando realmente lo necesites: enrutamiento de modelos basado en body, selección de endpoints basada en métricas del servidor de modelos, failover de proveedor externo, limitación consciente de tokens o procesamiento inline de payloads. El Kubernetes AI Gateway Working Group y el proyecto Gateway API Inference Extension dejan claro que esos patrones se están convirtiendo en preocupaciones de plataforma de primera clase, pero aún están evolucionando. Por eso exactamente un v1 simple y bien estructurado es el lugar correcto para empezar.