Rotar secretos de SMTP en Kubernetes suele parecer una tarea menor hasta que el primer correo de alerta no sale, sale duplicado o llega con enlaces viejos. El cambio tecnico ya ocurrio, pero la parte operativa sigue abierta. En varios equipos he visto ese hueco: se actualiza el Secret, se reinicia lo justo, se mira que el pod quede sano... y nadie confirma que la alerta mas importante todavia explica bien lo que paso.
Por eso me gusta tratar esta verificacion como un mini cierre de cambio. No hace falta montar una suite enorme. Hace falta una prueba corta, legible y repetible que confirme que el flujo de correo sigue vivo despues de la rotacion. Si usas una direccion de correo desechable para la corrida, mejor todavia, porque aislas evidencia y no llenas una inbox compartida con ruido. En notas internas alguna gente lo llama tem email; no es bonito, pero ya sabes como escribimos cuando vamos con prisa.
Por que rotar el secreto no cierra el trabajo
El riesgo no suele estar en Kubernetes por si solo. El riesgo aparece entre piezas:
- el deployment tomo el secreto nuevo pero el worker de alertas no
- el certificado o relay externo acepta auth, pero rechaza el remitente
- la plantilla del mensaje sigue apuntando a un host viejo
- un reintento automatico manda dos avisos y confunde al on-call
Ese ultimo punto pasa mas de lo que parece. Segun el informe 2024 de The State of Production Incidents de PagerDuty, la claridad del contexto inicial sigue siendo uno de los factores que mas reduce escalado innecesario durante incidentes. No hace falta poner un numero en cada runbook para notar lo mismo en guardias reales: si el primer aviso llega raro, todo el mundo pierde minutos valiosos.
Tambien conviene pensar en el cambio como una cadena de estados, no como un unico "correo enviado". Si ya trabajaste patrones para recibir eventos de email sin mezclar estados viejos, esta validacion encaja bien con esa mentalidad. Y si el sistema tiene polling o reintentos, revisar como manejar reintentos de verificacion sin duplicados tambien ayuda bastante.
Que suelo validar justo despues del cambio
Cuando termino la rotacion, reviso solo lo minimo que de verdad evita una guardia tonta:
- La alerta sale usando las credenciales nuevas.
- El asunto identifica servicio, entorno y accion.
- El cuerpo trae un enlace util al sistema correcto.
- No aparecen duplicados por restart o por replay del worker.
- La marca horaria coincide con el cambio recien hecho.
Si una de esas cinco cosas falla, no doy por cerrado el cambio. Es un criterio simple, pero muy util. Aveses la entrega funciona y aun asi el correo llega con un link a un dashboard viejo o con un nombre de cluster heredado. Eso no rompe el transporte, pero si rompe la operacion.
En entornos con Alertmanager, un relevo SMTP o un worker propio, tambien miro donde se cachean credenciales. Hay procesos que releen secretos al vuelo y otros que necesitan reinicio controlado. Esa diferencia, tan pequena sobre el papel, es la que luego explica porque la prueba manual "parecia bien" y la alerta real de media hora despues no salio.
Un check pequeno que evita guardias confusas
Mi preferencia es usar una sola corrida, una sola inbox aislada y una sola expectativa clara:
RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)"
RECIPIENT="alert-rotate-$RUN_ID@example.test"
kubectl apply -f smtp-secret.yaml
kubectl rollout restart deploy/alert-dispatcher -n platform
kubectl rollout status deploy/alert-dispatcher -n platform
trigger_test_alert \
--namespace platform \
--service checkout-api \
--severity warning \
--recipient "$RECIPIENT"
wait_for_message "$RECIPIENT" 120
assert_message_count "$RECIPIENT" 1
assert_subject_contains "$RECIPIENT" "checkout-api"
assert_body_contains "$RECIPIENT" "platform"
assert_link_host "$RECIPIENT" "grafana.example.com"
No intenta probar todo. Solo responde la pregunta correcta: despues de cambiar el secreto, la alerta util sigue llegando y sigue apuntando al sitio correcto? Si la respuesta es no, quiero enterarme en ese momento, no cuando alguien esta medio dormido a las 03:10.
Otra cosa que me sirve mucho es guardar el run_id junto al evento de prueba. Asi puedes separar una entrega tardia de una corrida anterior frente a un fallo real de la actual. Parece obvio, pero en mas de una revision he visto equipos perseguir un flake que era simplemente un mensaje viejo.
Senales que conviene guardar en el runbook
No hace falta llenar el runbook de campos, pero estas senales si las conservo:
run_id- namespace o cluster
- nombre del deployment reiniciado
- destinatario usado en la prueba
- host principal detectado en enlaces
- latencia hasta recepcion
- resultado final de la verificacion
Con eso ya puedes explicar casi cualquier fallo comun. Si el correo no llega, miras auth y relay. Si llega duplicado, revisas replay o reintentos. Si llega bien pero enlaza mal, la causa suele estar en plantilla o config. Es una tabla de decision bastante humilde, pero funciona.
Preguntas frecuentes
Hay que probar esto en cada rotacion?
Si la rotacion afecta credenciales reales del flujo de alertas, para mi si. No siempre con la misma profundidad, pero al menos con un smoke check corto.
Sirve una inbox compartida?
Puede servir, pero prefiero una aislada por corrida. Una direccion de correo desechable o temporal reduce ruido y hace mas facil saber que mensaje pertenece a este cambio y no a otro.
Debo validar HTML completo?
Normalmente no. Prefiero asunto, destinatario, host de enlaces y una o dos cadenas clave del cuerpo. El objetivo es confianza operativa, no perfeccion visual.
Cual es el error mas comun?
Cerrar el cambio cuando el pod ya levanto y asumir que el correo tambien quedo bien. Esa suposicion es la parte fragil, y suele costar mas de lo que paresce.
Top comments (0)