DEV Community

Alex Carter
Alex Carter

Posted on

Kubernetes: pruebas sintéticas sin ruido en alertas

Una alerta sintética debería responder una pregunta sencilla: ¿un usuario real podría completar este paso ahora mismo? En muchos clusters de Kubernetes, el canario de correo termina respondiendo otra pregunta: ¿el job de prueba sigue vivo?

La diferencia parece pequeña, pero cambia el turno de guardia. Si el test usa un buzón compartido, un mensaje retrasado puede parecer una caída del proveedor. Si reintenta sin límite, puede generar duplicados y ocultar la causa. Y si el pod muere sin dejar evidencia, el equipo solo ve un CrashLoopBackOff y empieza a adivinar.

El síntoma: una alerta que nadie cree

El patrón que he visto en revisiones de runbooks es bastante repetido:

  • Un CronJob crea una dirección de prueba.
  • La aplicación envía un correo de verificación.
  • El job espera unos segundos y busca el mensaje.
  • Una métrica marca éxito o fallo.

El problema es que esos cuatro pasos mezclan disponibilidad, entrega, identidad y lógica del test. Un fallo en cualquiera de ellos dispara la misma alerta. Después de unas semanas, las personas dejan de reaccionar. Ese es el incidente de verdad: la señal perdió credibilidad.

También aparece el clásico dummy e mail en fixtures antiguos. No es malo como dato de entrada, pero no debe confundirse con una comprobación de entrega. Una cadena válida no prueba que el proveedor aceptó, procesó y entregó el mensaje.

Separar la prueba del incidente real

Primero define qué estás midiendo. Para un flujo de verificación, conviene tener al menos estas señales separadas:

  1. Aceptación: la API devuelve un identificador de mensaje y un estado aceptado.
  2. Entrega observable: el buzón de prueba recibe el mensaje dentro del tiempo esperado.
  3. Contenido: asunto, destinatario y enlace corresponden al entorno de staging.
  4. Limpieza: el test puede terminar sin dejar datos reutilizables.

Un buzón aislado por ejecución hace más fácil atribuir el mensaje correcto. Si el sistema crea direcciones de forma dinámica, guarda solo un identificador efímero en el Secret o en el almacén de pruebas; no escribas el contenido completo del correo en los logs. Esa pequeña decisión es parte de la Security, no un detalle de comodidad.

Para instrumentar el flujo, un recibo estructurado ayuda más que un mensaje de log largo. Este formato es suficiente:

{
  "run_id": "ci-1842",
  "message_id": "provider-abc",
  "accepted_at": "2026-09-17T17:20:00Z",
  "received_at": "2026-09-17T17:20:08Z",
  "result": "verified"
}
Enter fullscreen mode Exit fullscreen mode

Si tu API genera eventos, documenta el contrato y registra la transición, no solo el resultado final. Un artículo sobre recibos de emails asincrónicos muestra por qué esta evidencia resulta útil cuando el trabajo ocurre fuera de la petición original.

Un contrato pequeño para el canario

El canario debe tener límites explícitos: timeout total, máximo de reintentos y una política para mensajes tardíos. Por ejemplo, un timeout de 60 segundos puede ser razonable para staging, pero el valor debe salir del comportamiento normal medido, no de una cifra copiada.

En Kubernetes, configura el CronJob para evitar ejecuciones solapadas. Usa concurrencyPolicy: Forbid si una segunda ejecución podría leer el buzón de la primera. Define activeDeadlineSeconds para que un proveedor lento no deje pods eternos. El contenedor debe devolver códigos distintos para error de infraestructura y fallo funcional, aunque la métrica agregada los presente por separado.

Un punto importante: el canario no debe hacer alert fatigue por cada fallo aislado. Usa una ventana corta y exige dos o tres fallos consecutivos, salvo que se trate de un error de autenticación o una caída total. La alerta puede incluir la fase que falló: acceptance, delivery, content o cleanup. Eso ahorra minutos valiosos durante un incidente.

Qué registrar cuando falla

Registra el nombre del entorno, versión desplegada, región, run_id, fase y latencia. Evita direcciones completas, tokens, enlaces privados y cuerpos de mensajes. Si necesitas comparar contenido, guarda un hash de campos permitidos y no el correo entero.

Cuando el test falle, compara con el estado del cluster: reinicios del pod, saturación de nodos, errores DNS y latencia de salida. Luego revisa el proveedor. Las revisiones de riesgo del correo también recuerdan una regla útil: una dirección de prueba o un correo recibido es una señal operacional, no una prueba completa de identidad.

Checklist de operación

  • ¿Cada ejecución tiene un run_id y una bandeja aislada?
  • ¿La alerta indica la fase exacta que falló?
  • ¿Hay timeout, límite de reintentos y control de solapamiento?
  • ¿Los logs excluyen secretos y cuerpos de correo?
  • ¿Se distinguen fallos funcionales de fallos del cluster?
  • ¿Se prueban los enlaces contra el host de staging?
  • ¿El runbook dice qué evidencia recoger antes de reiniciar?

La mejor prueba sintética no intenta imitar toda la producción. Mide un camino pequeño, deja un recibo verificable y desaparece al terminar. Cuando las señales tienen límites claros, el equipo de SRE puede confiar otra vez en sus alertas, incluso cuando la madrugada viene un poco movida.

Top comments (0)