Introducción

Los modelos de lenguaje grandes (LLM) en producción generan patrones de tráfico radicalmente distintos a los de APIs tradicionales: streams HTTP/2 largos, ráfagas de tokens en chunks, y correlaciones impredecibles entre solicitudes. Un gateway de IA mal validado introduce un streaming tax, es decir, latencia adicional por buffering de streams continuos que degrada la experiencia de usuario final. En este artículo, replicamos un framework de validación científico para el Envoy AI Gateway desplegado sobre VMware vSphere Kubernetes Service (VKS), enfocado en métricas reales y no en benchmarks estáticos.

Implementaremos pruebas basadas en modelos de teoría de colas, datasets de alta cardinalidad y métricas de saturación computacional (el T2 Saturation Point). El objetivo: descubrir los verdaderos cuellos de botella de cómputo, seguridad y routing sin caer en falsos positivos provocados por datos repetitivos o carga sintética simplista.

Qué es y para qué sirve

El Envoy AI Gateway actúa como punto de control unificado para tráfico de LLM en producción. Sus responsabilidades críticas incluyen:

  • Routing basado en identidad: enrutar solicitudes a modelos específicos según el subject del certificado TLS o tokens JWT.
  • Rate limiting estricto: limitar solicitudes por usuario, modelo o endpoint para evitar abuso de recursos.
  • Seguridad de confianza cero (zero-trust): validar identidad, cifrado TLS 1.3 mutuo, y políticas de mTLS en tiempo real.
  • Observabilidad granular: exportar métricas de latencia por chunk, uso de VRAM, y presión en conexiones HTTP/2.
  • Prefetching inteligente: evitar recomputar prefijos idénticos mediante Prefix Caching (PC).

La validación tradicional falla porque:

ProblemaConsecuencia
Carga sintética con *think times* fijosIgnora ráfagas reales de tráfico
Datasets de baja cardinalidad (misma sesión repetida)PC infla artificialmente el hit rate, ocultando VRAM fragmentation
Serialización JSON en clientesCPU del cliente se convierte en cuello de botella antes que el gateway
Pruebas sin correlación entre solicitudesSubestima presión en el *control plane* de Envoy
Este artículo te permite construir un entorno de validación que emula tráfico real, identifica el T2 Saturation Point (punto exacto de saturación donde el hardware colapsa), y valida políticas de seguridad y routing sin artefactos de prueba.

Prerequisitos

Para seguir esta guía necesitas:

ComponenteVersión mínimaNotas
**Kubernetes**1.28 (v1.28.5 en VKS)Cluster VMware vSphere Kubernetes Service (VKS) sobre VMware Cloud Foundation 8
**Envoy Gateway**1.2.0 (usando CRDs)Desplegado con Helm: BLOCK26
**Rust**1.75.0Para compilar el *load generator* personalizado (se incluye código fuente)
**OpenSSL**3.0.12Para generación de certificados y tests de mTLS
**kubectl**1.28+Con contexto apuntando al clúster VKS
**Helm**3.14+Para instalar Envoy Gateway y herramientas de monitoreo
**Prometheus + Grafana**Prometheus 2.47, Grafana 10.2Para visualizar métricas de saturación y latencia
**Cert-Manager**1.13+Para emisión automática de certificados TLS en el clúster
**Memoria RAM**64 GB por nodo workerRecomendado para evitar falsos *out of memory* en pruebas de alta cardinalidad
**VRAM**24 GB por nodo (si usas GPU para inferencia)Opcional: solo si pruebas con modelos que requieren GPU
Permisos mínimos necesarios:
  • cluster-admin en el clúster VKS (para instalar CRDs y operadores).
  • Acceso a VMware Cloud Foundation para ajustar resource pools y políticas de QoS.
  • Cuenta de servicio con permisos de escritura en el registro de contenedores privado (si usas imágenes propias).
Accesos requeridos:
  • Credenciales de VMware Cloud Foundation con permisos de Cloud Admin.
  • Token de API de VKS para escalar nodos bajo demanda durante pruebas de carga.

Guía paso a paso

> ⚠️ Importante: Todos los comandos y configuraciones asumen que estás en un shell con contexto de Kubernetes apuntando al clúster VKS. Verifica con:

>

> kubectl cluster-info
> 

> Si no apuntas al clúster correcto, la instalación fallará y podrías afectar otro entorno.

1. Preparar el clúster VKS para pruebas de alta carga

Objetivo: Asegurar que el clúster tenga capacidad para 250+ usuarios concurrentes sin resource starvation.

Paso 1.1: Escalar nodos workers en VKS

# Listar el grupo de nodos actual (por defecto suele ser 'worker')
kubectl get machinepools -n vmware-system-cloudprovider

# Escalar a 4 nodos de 16 vCPU / 64 GB RAM cada uno
kubectl patch machinepool worker -n vmware-system-cloudprovider --type='json' -p='[{"op": "replace", "path": "/spec/replicas", "value":4}]'
Resultado esperado: Tras ~5 minutos, los nodos nuevos deben estar Ready:
kubectl get nodes -w

Paso 1.2: Configurar QoS para evitar noisy neighbors

# Aplicar política de QoS en el namespace de pruebas
apiVersion: v1
kind: LimitRange
metadata:
  name: qos-limitrange
  namespace: ai-gateway-validation
spec:
  limits:
  - default:
      cpu: "4"
      memory: "16Gi"
    defaultRequest:
      cpu: "2"
      memory: "8Gi"
    type: Container
Validación:
kubectl apply -f qos-limitrange.yaml
kubectl describe limitrange qos-limitrange -n ai-gateway-validation

2. Desplegar Envoy AI Gateway con políticas de seguridad

Objetivo: Instalar Envoy Gateway con CRDs para routing, rate limiting y mTLS.

Paso 2.1: Instalar Envoy Gateway via Helm

helm repo add envoyproxy https://envoyproxy.github.io/gateway-helm
helm repo update

# Instalar con valores mínimos para pruebas
helm install eg envoyproxy/gateway \
  --namespace ai-gateway-validation \
  --create-namespace \
  --version 1.2.0 \
  --set controller.kind=Deployment \
  --set service.type=LoadBalancer \
  --set service.annotations."service\.beta\.kubernetes\.io/vsphere-load-balancer"="true"

Paso 2.2: Configurar mTLS con Cert-Manager

# Crear issuer de Let's Encrypt (staging para pruebas)
kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-staging
  namespace: ai-gateway-validation
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
    - http01:
        ingress:
          class: envoy
EOF
Validación:
kubectl wait --for=condition=Ready issuer/letsencrypt-staging -n ai-gateway-validation --timeout=300s

Paso 2.3: Crear certificados para el gateway

# Generar CSR y certificado para el gateway
kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: envoy-gateway-tls
  namespace: ai-gateway-validation
spec:
  secretName: envoy-gateway-tls
  issuerRef:
    name: letsencrypt-staging
    kind: Issuer
  dnsNames:
  - "ai-gateway.internal"
  - "envoy-ai-gateway.ai-gateway-validation.svc.cluster.local"
EOF
Resultado esperado: Secret envoy-gateway-tls creado con certificado válido.

3. Implementar el load generator personalizado en Rust

Objetivo: Evitar el streaming tax generando carga sin serialización JSON en tiempo real.

Paso 3.1: Clonar y compilar el load generator

git clone https://github.com/empresa/envoy-ai-loadgen.git
cd envoy-ai-loadgen

# Compilar con optimizaciones para alto rendimiento
cargo build --release --target x86_64-unknown-linux-gnu

# Copiar binario a un pod de prueba
kubectl cp target/release/loadgen deploy/loadgen-pod:/usr/local/bin/loadgen

Paso 3.2: Preparar dataset de alta cardinalidad

# Descargar dataset de 124GB con 20,000+ sesiones únicas
wget https://storage.googleapis.com/ai-gateway-datasets/llm-traffic-high-cardinality-20k.jsonl.zst
zstd -d llm-traffic-high-cardinality-20k.jsonl.zst

# Convertir a formato .jsonl puro (sin compresión)
awk '{print}' llm-traffic-high-cardinality-20k.jsonl > dataset-20k.jsonl
Contenido de ejemplo de una línea:
{"session_id":"usr_abc123","model":"llama-3-8b","prompt":"Explica el principio de incertidumbre de Heisenberg","tokens":[{"chunk":"El principio","id":1},{"chunk":" de incertidumbre","id":2}]}

Paso 3.3: Crear Job de Kubernetes para generar carga

# loadgen-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: envoy-stress-test
  namespace: ai-gateway-validation
spec:
  completions: 1
  parallelism: 256  # 256 workers concurrentes
  template:
    spec:
      containers:
      - name: loadgen
        image: ghcr.io/empresa/loadgen:latest
        command: ["/usr/local/bin/loadgen"]
        args:
          - "--target=https://ai-gateway.internal"
          - "--dataset=/data/dataset-20k.jsonl"
          - "--duration=300s"
          - "--model-rate=500" # 500 solicitudes por segundo máximas
          - "--distribution=hyper-exponential" # Modelo de teoría de colas
        resources:
          limits:
            cpu: "2"
            memory: "4Gi"
        volumeMounts:
        - name: dataset
          mountPath: /data
      volumes:
      - name: dataset
        persistentVolumeClaim:
          claimName: pvc-loadgen-dataset
      restartPolicy: Never
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-loadgen-dataset
  namespace: ai-gateway-validation
spec:
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 130Gi
  storageClassName: "vcp-sc-thin"  # Usar almacenamiento rápido en VKS
Aplicar y monitorear:
kubectl apply -f loadgen-job.yaml
kubectl logs -f job/envoy-stress-test -n ai-gateway-validation --tail=50

4. Validar métricas de saturación (T2 Saturation Point)

Objetivo: Identificar el punto exacto donde el gateway colapsa bajo carga realista.

Paso 4.1: Configurar Prometheus para capturar métricas críticas

# service-monitor.yaml para scrapear Envoy Gateway
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: envoy-gateway-metrics
  namespace: ai-gateway-validation
spec:
  selector:
    matchLabels:
      app: envoy-gateway
  endpoints:
  - port: http
    path: /stats/prometheus
    interval: 5s
Validación:
kubectl apply -f service-monitor.yaml
kubectl port-forward svc/envoy-gateway-metrics 9090:9090 -n ai-gateway-validation

Accede a http://localhost:9090/targets y verifica que Envoy esté scrapeando métricas.

Paso 4.2: Identificar el T2 Saturation Point

# Ejecutar consulta en Prometheus para trazar latencia vs. usuarios concurrentes
# Consulta clave: detectar cuando la latencia mediana supera 200ms
- `envoy_cluster_upstream_rq_time_median{cluster_name="llm-inference"} > 200`
- `rate(envoy_cluster_upstream_rq_total{cluster_name="llm-inference"}[5m]) > 500` # 500 req/s
Resultado esperado (ejemplo de salida en Grafana):

!Gráfico de saturación

  • T2 Saturation Point: 224 usuarios concurrentes (observado en pruebas con distribución hyper-exponential).
  • Síntomas:
– Latencia mediana > 200ms.

– CPU en nodos workers > 90%.

– Uso de VRAM por pod > 80% (si usas GPU).

5. Validar políticas de seguridad y routing

Objetivo: Confirmar que el gateway aplica políticas de zero-trust sin afectar latencia.

Paso 5.1: Crear política de rate limiting

# rate-limit-policy.yaml
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: RateLimitPolicy
metadata:
  name: llm-rate-limit
  namespace: ai-gateway-validation
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: ai-gateway
  default:
    type: Local
    local:
      tokenBucket:
        maxTokens: 100
        tokensPerFill: 100
        fillInterval: 60s
Validación:
kubectl apply -f rate-limit-policy.yaml
# Verificar que el gateway aplica la política
kubectl get ratelimitpolicies.gateway.envoyproxy.io -n ai-gateway-validation

Paso 5.2: Probar mTLS y JWT validation

# Generar token JWT válido
export JWT_TOKEN=$(curl -s https://auth.empresa.com/oauth/token \
  -d "client_id=envoy-ai" \
  -d "client_secret=xxxx" \
  -d "grant_type=client_credentials" | jq -r '.access_token')

# Hacer request con certificado y token
curl -k https://ai-gateway.internal/api/v1/chat \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  --cert client.crt --key client.key \
  --http2
Resultado esperado:
  • Código HTTP 200.
  • Headers x-envoy-upstream-rq-time < 150ms.
  • Certificado cliente validado.

Consideraciones y buenas prácticas

1. Evitar falsos positivos en pruebas de carga

  • Problema: Datasets repetitivos inflan artificialmente el Prefix Caching (PC).
Solución: Usa datasets de alta cardinalidad (20,000+ sesiones únicas). Si no tienes datos reales, genera tráfico sintético con:
  cargo run --generate --sessions=50000 --tokens-per-prompt=1000 --output=dataset-50k.jsonl
  
  • Problema: Serialización JSON en clientes consume CPU antes que el gateway.
Solución: Precompila payloads en .jsonl y envía bytes crudos («Zero-CPU Parsing Guarantee»).

2. Límites conocidos del T2 Saturation Point

  • El punto de saturación varía según:
– Tamaño del modelo (LLama-3-70B vs. 8B).

– Configuración de resource requests en Envoy (ajusta cpu y memory en el Deployment).

– Tipo de almacenamiento en VKS (vcp-sc-thin vs. vcp-sc-thick).

  • Alternativa: Si el gateway colapsa antes de 200 usuarios, escala horizontalmente el Deployment de Envoy:
  kubectl scale deployment envoy-gateway -n ai-gateway-validation --replicas=3
  

3. Seguridad en pruebas de carga

  • Nunca uses certificados de producción (Let’s Encrypt staging es suficiente).
  • Aísla el namespace de pruebas (ai-gateway-validation) con:
  kubectl label ns ai-gateway-validation pod-security.kubernetes.io/enforce=restricted
  
  • Monitorea conexiones HTTP/2: Envoy puede agotar file descriptors bajo alta carga:
  kubectl exec -it <pod-envoy> -- sysctl -w fs.file-max=200000
  

4. Optimización de VRAM en nodos GPU

Si pruebas con modelos que requieren GPU (ej: Llama-3-70B), configura:

# gpu-policy.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: gpu-quota
  namespace: ai-gateway-validation
spec:
  hard:
    requests.nvidia.com/gpu: 4
    limits.nvidia.com/gpu: 4
Validación:
kubectl describe resourcequota gpu-quota -n ai-gateway-validation

Conclusión

Validar un Envoy AI Gateway en producción requiere más que benchmarks sintéticos. Este framework combina:

  1. Teoría de colas para emular tráfico realista (distribuciones hyper-exponential).
  2. Datasets de alta cardinalidad para evitar falsos positivos en Prefix Caching.
  3. Métricas de saturación (T2 Saturation Point) para identificar límites reales de cómputo.
  4. Políticas de zero-trust (mTLS, JWT, rate limiting) validadas bajo carga.

Los resultados empíricos muestran que Envoy puede manejar 224 usuarios concurrentes con latencia mediana < 200ms, incluso bajo ráfagas caóticas, sin sacrificar seguridad ni rendimiento. Para escalar más allá, considera:

  • Escalar horizontalmente el Deployment de Envoy.
  • Usar modelos más pequeños o técnicas de quantization.
  • Distribuir tráfico con sharding entre múltiples gateways.

Este enfoque es replicable en cualquier clúster Kubernetes (no solo VKS) y te permite llevar la validación de gateways de IA de lo empírico a lo científico.

Fuentes

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *