DEV Community

Alex Carter
Alex Carter

Posted on

Kubernetes: un runbook SRE para alertas de email

Una alerta de email que llega tarde suele parecer un problema del proveedor. En una guardia SRE, esa suposición cuesta tiempo. El retraso puede estar en el código, en una cola, en un Secret mal montado, en Kubernetes o en el propio proveedor SMTP.

Este es el tipo de runbook que conviene tener antes del incidente. No intenta explicar cada detalle de la plataforma. Su objetivo es ayudar a un compañero a pasar de “no llegó el correo” a una causa comprobable, sin cambiar cinco cosas a la vez.

El síntoma: la alerta llegó tarde

Empieza registrando tres tiempos distintos:

  1. Cuándo ocurrió el evento en la aplicación.
  2. Cuándo se creó el trabajo de envío.
  3. Cuándo el proveedor aceptó el mensaje.

Sin estos tiempos, “retrasado” es solo una impresión. Un mensaje puede estar encolado durante minutos, o puede haber sido aceptado y luego filtrado. En el incidente, anota también el pod, el namespace, el identificador de correlación y el entorno.

Una métrica sencilla ayuda bastante: email_delivery_lag_seconds. Mide desde la creación del trabajo hasta la confirmación del proveedor. No mezcles este valor con el tiempo de procesamiento de la API, porque las dos señales responden preguntas diferentes.

Qué debe contener el runbook

El documento debe empezar con una decisión rápida:

  • ¿Fallan todos los correos o solo una plantilla?
  • ¿Afecta a un namespace o a todos?
  • ¿Hay trabajos pendientes en la cola?
  • ¿El proveedor responde con error o no hay respuesta?

Después incluye comandos seguros y de solo lectura. Por ejemplo:

kubectl -n notifications get pods -o wide
kubectl -n notifications get events --sort-by=.lastTimestamp
kubectl -n notifications logs deploy/email-worker --since=30m
Enter fullscreen mode Exit fullscreen mode

No pegues valores de secretos en el ticket ni en el chat de guardia. Es una cosa pequeña, pero se olvida facilmente cuando todos miran el mismo fallo.

Separar aplicación, proveedor y Kubernetes

Divide el diagnóstico en tres capas.

Aplicación. Busca errores de serialización, plantillas que no compilan, timeouts y claves de idempotencia repetidas. Un reintento debe conservar el identificador del trabajo; si no, puede producir mensajes duplicados.

Cola y worker. Comprueba la edad del trabajo más antiguo, la tasa de reintentos y el número de consumidores. Si la cola crece pero los pods están sanos, “Running” no significa que el servicio esté bien. Puede haber un límite de concurrencia demasiado bajo o un backoff excesivo.

Kubernetes y proveedor. Revisa reinicios, cambios recientes de configuración, resolución DNS y límites de salida. Un NetworkPolicy puede bloquear al proveedor aunque el endpoint interno siga respondiendo. También verifica que el Secret usado por el Deployment tenga la versión esperada; no lo imprimas, compara solo su existencia, referencia y fecha de rotación.

Para flujos con reintentos, conviene documentar también cómo se conserva la evidencia. Un prompt de email que resiste reintentos es útil en automatización, pero no reemplaza una política de idempotencia en el worker.

Prueba controlada y evidencia

Cuando el alcance esté claro, envía una prueba a un buzón controlado y etiquetado. Usa una plantilla conocida, un correlation_id nuevo y un límite de tiempo. No pruebes con la lista real de clientes durante el incidente.

Guarda solo los datos necesarios: hora de creación, estado del job, respuesta del proveedor, número de intento y hora de confirmación. Si el mensaje contiene datos personales, redáctalos antes de compartir el registro. Para probar casos de producto, esta guía sobre emails de referidos en un SaaS aporta una separación útil entre datos de prueba y métricas reales.

A veces el síntoma aparece en un dominio de prueba como “tamp mail com”. No lo trates como evidencia de que el proveedor está caído: primero confirma DNS, cuota y respuesta SMTP para ese dominio.

Checklist para el siguiente incidente

  • [ ] Registrar los tres tiempos y el correlation_id.
  • [ ] Identificar si el fallo es global, por plantilla o por dominio.
  • [ ] Revisar cola, reintentos y edad del trabajo más antiguo.
  • [ ] Comparar pods, reinicios y eventos del namespace.
  • [ ] Confirmar configuración sin revelar secretos.
  • [ ] Ejecutar una prueba controlada.
  • [ ] Definir quién puede cambiar el backoff o escalar workers.
  • [ ] Escribir la causa y la señal que la confirmó.

El runbook queda mejor cuando tiene un dueño y una fecha de revisión. Si nadie sabe quien lo actualiza, en dos meses los nombres de los deployments ya no coinciden.

Preguntas frecuentes

¿Debo reiniciar los pods primero?

No como primer paso. Un reinicio puede borrar la pista más valiosa. Captura logs, métricas y eventos; después decide si el reinicio es una mitigación segura.

¿Un HTTP 200 del proveedor significa entrega?

Normalmente significa aceptación de la solicitud, no que el usuario haya visto el mensaje. Conserva el estado de aceptación y, si existe, la información posterior de entrega o rebote.

¿Cuándo escalo el incidente?

Escala cuando se acerque el presupuesto de errores, cuando la cola siga creciendo o cuando el fallo afecte a una ruta de autenticación. Esperar a tener la causa perfecta puede aumentar el impacto.

La meta de un buen runbook SRE no es adivinar. Es reducir el espacio de posibilidades, proteger la evidencia y dejar una decisión clara para la persona que está de guardia a las tres de la mañana.

Top comments (0)