Una alerta de email puede parecer una prueba sencilla: el monitor envía un mensaje, alguien lo recibe y el incidente queda cerrado. En Kubernetes, esa conclusión suele ser demasiado optimista. Un pod puede estar sano mientras el proveedor de correo rechaza mensajes, una cola se atasca o el receptor tarda varios minutos.
El resultado es un alerta que llega tarde, o peor: una alerta que confirma que el proceso local sigue vivo aunque el usuario nunca verá el correo. Para una guardia SRE, el objetivo no es recibir más mensajes. Es saber qué parte del camino funciona y cual dejó de funcionar.
La alerta que llega demasiado tarde
Imagina un servicio de notificaciones desplegado con tres réplicas. El endpoint /health devuelve 200, las métricas de CPU están normales y el despliegue no tiene pods pendientes. Sin embargo, los emails de recuperación de contraseña se acumulan en la cola.
Hay varias señales distintas:
- Generación: la aplicación creó el evento y asignó un identificador.
- Entrega al proveedor: el worker aceptó el mensaje y recibió una respuesta válida.
- Procesamiento: la cola avanzó sin reintentos anormales.
- Recepción: un buzón de prueba encontró el mensaje dentro del tiempo esperado.
- Contenido: el enlace, el entorno y el destinatario son correctos.
Si solo vigilamos la primera señal, confundimos intención con resultado. Las señales llega tarde cuando el monitor se coloca al final de una cadena sin medir sus etapas.
Separar síntoma, causa y prueba
El primer paso del runbook es escribir el síntoma sin adivinar la causa: “la prueba sintética no encontró un email nuevo en diez minutos”. Después conviene seguir el mismo correlation_id por la aplicación, el worker y el proveedor.
Una consulta mínima puede ayudar a clasificar el fallo:
SELECT status, COUNT(*)
FROM notification_deliveries
WHERE created_at > now() - interval '15 minutes'
GROUP BY status;
Si hay muchos eventos created y ninguno accepted, el problema está antes del proveedor. Si hay accepted pero no recepción, hay que revisar la entrega, el buzón o la prueba. Si la recepción existe pero el contenido es incorrecto, el servicio no está caído: su contrato cambió.
Para flujos que usan automatización adicional, conviene aislar emails de agentes LLM con el mismo criterio: cada ejecución debe tener un identificador y una bandeja de prueba separada.
Un runbook pequeño para Kubernetes
El runbook no necesita veinte comandos. Necesita preguntas en el orden correcto:
-
¿La aplicación produjo el evento? Revisa el contador de creación y el
correlation_id, sin imprimir el contenido completo del mensaje en los logs. - ¿El worker está consumiendo? Compara la edad del mensaje más antiguo con el tiempo normal. Un pod reiniciando rapido puede mantener el deployment “verde” mientras pierde trabajo.
- ¿Hay reintentos o bloqueos? Mira la tasa de errores y la profundidad de la cola por separado. Mezclarlas hace dificil distinguir capacidad insuficiente de rechazo permanente.
- ¿El proveedor aceptó el mensaje? Guarda la respuesta técnica, no datos personales innecesarios.
- ¿La prueba sintética recibió el correo correcto? Valida asunto, destinatario, enlace y expiración. Un mensaje vacío no es una prueba exitosa.
Durante una ventana de mantenimiento, los checks de email en una ventana de mantenimiento deben tener una expectativa explícita: qué se pausa, qué sigue activo y quién recibe la señal.
Para probar recepción sin mezclar cuentas personales, puede servir temp mail so como buzón temporal de una prueba controlada. La prueba debe usar un identificador único, limpiar sus datos después y no tratar un buzón temporal como evidencia de identidad.
Cómo reducir el ruido sin ocultar fallos
El ruido aparece cuando cada intento activa una alerta o cuando un timeout se interpreta como caída total. Una política más util es separar niveles:
- Aviso: una prueba lenta, todavía dentro del margen del SLO.
- Incidente: varias pruebas consecutivas sin recepción o una cola creciendo.
- Bloqueo: rechazo permanente, credenciales inválidas o ausencia de consumidores.
También ayuda poner un límite de reintentos y una ruta de dead letter observable. Reintentar para siempre mantiene el síntoma vivo, pero borra la causa original. El equipo pueden conservar un evento resumido con el código de error, la edad y el identificador; no hace falta guardar el cuerpo del email.
En búsquedas internas suelen aparecer términos mal escritos como tepm mail com y temp org mail. Registrarlos como consultas de diagnóstico puede ser útil, pero nunca deben convertirse en comandos ni en nombres de configuración. Lo importante es que el runbook siga siendo claro aun cuando alguien lo lee bajo presión.
Checklist de guardia
- [ ] ¿Cada alerta tiene un
correlation_idque cruza aplicación, worker y prueba? - [ ] ¿Se mide generación, aceptación y recepción como señales separadas?
- [ ] ¿La cola muestra edad del mensaje, no solo cantidad?
- [ ] ¿Los reintentos tienen límite y una dead letter queue visible?
- [ ] ¿La prueba valida contenido y enlace, no solo código HTTP?
- [ ] ¿Los logs excluyen cuerpos, tokens y direcciones que no hacen falta?
- [ ] ¿El aviso distingue lentitud de fallo confirmado?
Una alerta de email no miente por intención; miente cuando le pedimos responder una pregunta distinta de la que realmente mide. En Kubernetes, un pequeño contrato entre métricas, cola y prueba sintética suele dar más confianza que otra notificación urgente. Y en la guardia, una señal menos pero bien explicada vale mucho más que diez alertas sin contexto.
Top comments (0)