---
title: "Pruebas de carga de APIs y microservicios en Kubernetes: ingress, timeouts y señales del HPA"
description: "Pruebas de carga en Kubernetes: timeouts de ingress, HPA, overhead del mesh—k6 contra hostnames reales del cluster con contexto de red de Kubernetes.io."
publishDate: "2026-09-14"
draft: false
keyword: "pruebas carga microservicios kubernetes"
intent: "MOFU"
cta: "Usa Performate para convertir este playbook en escenarios k6 ejecutables, umbrales y reportes compartibles sin perder días en código de integración."
tags: ["k6", "pruebas-de-carga", "rendimiento-api", "kubernetes"]
translationOf: kubernetes-microservice-load-testing
---

La prueba de carga «pasó» contra la IP del pod en el namespace `staging`, pero producción sigue fallando en el ingress: timeouts de `proxy-read`, HPA que escala tarde y un sidecar de mesh que suma 40 ms por hop. En Kubernetes, **el hostname que ve el cliente** y **las señales del plano de control** son parte del experimento—no un detalle de infra.

Las pruebas de carga de microservicios en Kubernetes no tratan de demostrar que un Deployment arranca. Tratan de validar que **tráfico externo realista** cumple SLO mientras ingress, autoscaling y mesh interactúan. En esta guía verás por qué golpear pod IPs engaña, cómo alinear duraciones de test con anotaciones de ingress, y cómo correlacionar rampas de k6 con eventos de HPA y métricas de cluster.

## Por qué Kubernetes cambia los modos de fallo

Bajo concurrencia, la latencia de microservicios suele estar dominada por la plataforma, no solo por tu handler HTTP:

- **Ingress / Gateway API:** timeouts de lectura, buffers y límites de conexión cortan requests lentos antes de que el servicio responda.
- **HPA:** el lag entre métrica, decisión y pod listo crea rampas de latencia durante subidas de carga ([documentación de Kubernetes](https://kubernetes.io/docs/home/)).
- **Service mesh:** sidecars duplican TLS, retries y políticas—milisegundos por hop que se acumulan en cadenas de llamadas.
- **DNS y políticas de red:** resolución y `NetworkPolicy` distintas entre «desde laptop» y «desde runner en cluster».

Piensa en k6 como un cliente fuera del cluster (o en un job de CI con egress real): debe usar el **mismo FQDN** que la app móvil o el BFF, no `http://10.x.x.x:8080` interno.

### Cuando el microservicio está sano pero el percentil explota

Un `p99` que solo aparece bajo rampa suele ser cola en ingress o cold pods, no un bug de SQL. Sin correlacionar `kubectl get hpa` y eventos con la ventana de k6, el equipo optimiza el servicio equivocado. Etiqueta workloads con `mesh:on` / `mesh:off` al comparar—ver [k6 observabilidad: métricas y tags](/es/blog/k6-observabilidad-metricas-tags).

## Implementación práctica con k6: ingress, rampas y tags

**Script de ejemplo (ilustrativo).** Hostnames y umbrales ficticios.

**Qué demuestra este ejemplo:**

- **BASE_URL apunta al ingress público** (`api.staging.example.com`), no al Service ClusterIP.
- **Escenario con rampa** para observar lag del HPA, no solo meseta instantánea.
- **Tags** `route`, `mesh` y `ingress` para partir métricas en postmortems.

```javascript
import http from 'k6/http';
import { check, sleep } from 'k6';

// Hostname que resuelve el ingress — igual que clientes reales
const BASE = __ENV.INGRESS_HOST || 'https://api.staging.example.com';

export const options = {
  scenarios: {
    checkout_ramp: {
      executor: 'ramping-arrival-rate',
      startRate: 5,
      timeUnit: '1s',
      preAllocatedVUs: 20,
      maxVUs: 120,
      stages: [
        { duration: '2m', target: 20 },
        { duration: '3m', target: 50 },
        { duration: '2m', target: 10 },
      ],
      tags: { route: 'checkout', mesh: __ENV.MESH || 'on' },
      exec: 'checkout',
    },
  },
  thresholds: {
    http_req_failed: ['rate<0.01'],
    'http_req_duration{route:checkout}': ['p(95)<900', 'p(99)<1500'],
  },
};

export function checkout() {
  const res = http.post(
    `${BASE}/v1/checkout`,
    JSON.stringify({ sku: 'SKU-1', qty: 1 }),
    {
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${__ENV.API_TOKEN}`,
      },
      tags: { route: 'checkout', mesh: __ENV.MESH || 'on' },
      timeout: '60s', // alinea con proxy-read-timeout del ingress
    },
  );
  check(res, { 'checkout 2xx': (r) => r.status >= 200 && r.status < 300 });
  sleep(0.3);
}
```

**Patrones que funcionan**

- Revisa anotaciones del ingress (`proxy-read-timeout`, `proxy-body-size`) **antes** de escalar RPS—un timeout de 30s mata soak de 45m aunque el pod aguante.
- Corre k6 desde un runner con egress similar a prod (CI en VPC, no solo laptop) cuando las políticas de red importan.
- Captura en paralelo: `kubectl top pods`, eventos HPA, métricas de kube-state; alinea timestamps con el export de k6.
- Para colas async downstream, combina con [pruebas de carga de pipeline async queue/worker](/es/blog/pruebas-carga-pipeline-async-queue-worker).

**Anti-patrones a evitar**

- Load test solo contra pod IP—omite TLS termination, WAF y límites de ingress.
- Ignorar `maxReplicas` del HPA durante stress—el test «pasa» porque nunca llegó al techo realista.
- Mezclar namespaces sin aislar datos—staging compartido invalida umbrales (ver [errores comunes](/es/blog/errores-comunes-pruebas-de-carga)).

**Pro tip (comando de ejemplo):**

```bash
k6 run k8s-checkout-ramp.js -e INGRESS_HOST="https://api.staging.example.com" -e MESH=on \
  --summary-export=summary-k8s.json
```

**Qué demuestra este comando:** el export JSON se adjunta a tickets de capacidad junto a capturas de `kubectl describe hpa` en la misma ventana temporal.

## Marco de decisión: qué observar según la pregunta

| Pregunta | Acción recomendada |
|:---|:---|
| ¿El ingress aguanta el pico? | Hostname público + timeout alineado a anotaciones |
| ¿El HPA escala a tiempo? | `ramping-arrival-rate` + eventos HPA en la rampa |
| ¿El mesh es el costo? | Comparar corrida `mesh:on` vs `mesh:off` (solo en entornos permitidos) |
| ¿Capacidad para launch? | Campaña manual + [planificación de capacidad desde resultados k6](/es/blog/planificacion-capacidad-resultados-k6) |
| ¿Regresión por PR? | Smoke bajo RPS en ingress de preview—[pruebas de carga en CI/CD](/es/blog/pruebas-de-carga-en-ci-cd) |

**Usa hostname de ingress si** necesitas evidencia que el cliente real verá.

**Usa rampas si** la hipótesis es autoscaling o colas durante subida de tráfico.

**Usa soak controlado si** buscas fugas o inestabilidad tras pods estables—ver [playbook de soak testing](/es/blog/playbook-soak-testing-memory-leaks).

## Observabilidad y documentación

Antes de escalar más allá del presupuesto acordado con plataforma:

- [ ] Documenta FQDN, namespace, versión de chart y `git_sha` del servicio bajo test.
- [ ] Registra `proxy-read-timeout` y límites de conexión del ingress en el informe.
- [ ] Adjunta gráfica de réplicas HPA vs RPS de k6 en la misma línea de tiempo.
- [ ] Si usas mesh, anota versión de control plane y política de retries.
- [ ] Archiva `summary-k8s.json` y capturas de cluster para postmortems.

## Cómo Performate encaja en pruebas K8s

Los equipos pierden días cableando auth, hostnames y metadata de export cada vez que cambia el ingress. Abajo hay un **ejemplo concreto de flujo** para la API de búsqueda a través del ingress de staging.

**Ejemplo: escenario de búsqueda realista por ingress sin hacks de port-forward**

1. **Importa OpenAPI o Postman** para `GET /v1/search` con query params similares a producción. *Problema resuelto:* URLs y headers coinciden con lo que enruta el ingress—no atajos localhost.
2. **Define `API_BASE` al hostname del ingress de staging** (`https://api.staging.example.com`) en el panel de entorno. *Problema resuelto:* rutas TLS y DNS coinciden con el tráfico del cliente.
3. **Crea escenario ramping-arrival-rate**—5→30 req/s en quince minutos. *Problema resuelto:* ajuste visual de rampa mientras observas el HPA en otra terminal.
4. **Aplica tags** `route:search`, `target:ingress` y `mesh:on/off` desde entorno. *Problema resuelto:* reportes aíslan debates de overhead del mesh con datos, no anécdotas.
5. **Define umbrales** en `p99` y tasa de error del gateway (checks `502/504` en script). *Problema resuelto:* gates de release detectan kills del proxy que la latencia media oculta.
6. **Exporta script k6 y resumen** con metadata del escenario para la carpeta de postmortem. *Problema resuelto:* snapshots del cluster y mezclas de tráfico citan el mismo artefacto.

Ese flujo conecta directamente con el `cta` de este post: escenarios ejecutables y reportes compartibles sin perder días en glue code.

## Cierre

En Kubernetes, una prueba de carga creíble golpea **ingress + autoscaling + mesh**, no solo el contenedor. Usa hostnames de cliente, alinea timeouts de test con el proxy, y correlaciona rampas de k6 con señales del plano de control.

Programa la próxima corrida contra el FQDN de staging con una rampa de 20→50 req/s y anota si el `p99` sube antes de que el HPA añada réplicas—esa respuesta vale más que otro test contra IP interna.

[Try Performate free](https://performate.app) | [Book a demo](/demo) | [k6 running in Kubernetes](https://k6.io/docs/misc/fine-tuning-os/)
