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:
| Problema | Consecuencia |
|---|---|
| Carga sintética con *think times* fijos | Ignora 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 clientes | CPU del cliente se convierte en cuello de botella antes que el gateway |
| Pruebas sin correlación entre solicitudes | Subestima presión en el *control plane* de Envoy |
Prerequisitos
Para seguir esta guía necesitas:
| Componente | Versión mínima | Notas |
|---|---|---|
| **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.0 | Para compilar el *load generator* personalizado (se incluye código fuente) |
| **OpenSSL** | 3.0.12 | Para 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.2 | Para 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 worker | Recomendado 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 |
cluster-adminen 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).
- 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 -wPaso 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: ContainerValidación:kubectl apply -f qos-limitrange.yaml
kubectl describe limitrange qos-limitrange -n ai-gateway-validation2. 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
EOFValidación:kubectl wait --for=condition=Ready issuer/letsencrypt-staging -n ai-gateway-validation --timeout=300sPaso 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"
EOFResultado 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/loadgenPaso 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.jsonlContenido 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 VKSAplicar y monitorear:kubectl apply -f loadgen-job.yaml
kubectl logs -f job/envoy-stress-test -n ai-gateway-validation --tail=504. 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: 5sValidación:kubectl apply -f service-monitor.yaml
kubectl port-forward svc/envoy-gateway-metrics 9090:9090 -n ai-gateway-validationAccede 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/sResultado esperado (ejemplo de salida en Grafana):- T2 Saturation Point: 224 usuarios concurrentes (observado en pruebas con distribución hyper-exponential).
- Síntomas:
– 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: 60sValidació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-validationPaso 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 \
--http2Resultado 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).
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.
.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:
– 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: 4Validación:kubectl describe resourcequota gpu-quota -n ai-gateway-validationConclusión
Validar un Envoy AI Gateway en producción requiere más que benchmarks sintéticos. Este framework combina:
- Teoría de colas para emular tráfico realista (distribuciones hyper-exponential).
- Datasets de alta cardinalidad para evitar falsos positivos en Prefix Caching.
- Métricas de saturación (T2 Saturation Point) para identificar límites reales de cómputo.
- 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
- Validación de Envoy AI Gateway en VMware vSphere Kubernetes Service (VMware Cloud Foundation Blog)
- Documentación oficial de Envoy Gateway CRDs (gateway.envoyproxy.io)
- Teoría de colas aplicada a tráfico de LLM (Kubernetes Blog)
- Guía de optimización de VRAM en modelos de lenguaje (NVIDIA Developer)
