SRE: aislar fallos de email en Kubernetes
Cuando un smoke test de registro falla en Kubernetes, el primer impulso suele ser culpar al clúster. A veces el problema está en el proveedor de correo, en un buzón temporal que expiró o en un selector demasiado estricto. Otras veces sí es un NetworkPolicy que bloqueó la salida.
La diferencia importa. Si se escala el Deployment cuando el fallo real está en el inbox de prueba, se añade ruido y se gasta tiempo del equipo. En una guardia aprendí a tratar cada prueba de email como un pequeño contrato operativo: debe decir qué espera, durante cuanto tiempo lo espera y qué evidencia deja si no ocurre.
El síntoma: correo fallido o clúster fallido
El test normalmente tiene tres partes: crea un usuario, espera el mensaje y confirma un enlace o un código. Un resultado rojo solo nos dice que una de esas fases no terminó. No explica si falló la aplicación, la red, el proveedor o la lectura del buzón.
Antes de tocar Kubernetes, separo las señales:
- La API devolvió un
202o un error de entrega. - El worker tomó el evento de email y lo confirmó.
- La red permitió la conexión de salida.
- El buzón recibió un mensaje nuevo, no uno viejo.
- El test encontró el correo correcto y lo consumió una sola vez.
Este modelo también funciona para fixtures de datos. Las listas semilla para un onboarding SaaS ayudan a que el caso de prueba empiece con entradas conocidas, pero no sustituyen la observabilidad de la entrega.
Un contrato de prueba pequeño y observable
Un smoke test no necesita conocer todos los detalles internos. Sí necesita un identificador único por ejecución, un destinatario aislado y un límite de tiempo explícito. Una dirección temporal o un buzón temporal puede servir para probar un flujo controlado, siempre que el entorno sea de pruebas y no se envíen datos sensibles.
El contrato puede verse así:
test_id: signup-20260930-0522-8f31
recipient: único para esta ejecución
expected_subject: Confirmación de cuenta
deadline: 90 segundos
cleanup: eliminar usuario y fixture al terminar
El test_id debe viajar en los logs del servicio de signup, del worker y del consumidor de correo. No hace falta imprimir el contenido completo del mensaje. Basta con registrar el hash del mensaje o un identificador de entrega, el estado y la hora. Un detalle que parece menor: el texto de prueba tem email puede aparecer en fixtures antiguos; no debe convertirse en una condición especial del código.
Aislamiento con namespaces y permisos mínimos
Para investigar un fallo, un entorno de prueba debe tener límites claros. Un namespace separado evita mezclar los pods del smoke test con los workers de producción. Un ServiceAccount dedicado permite saber qué identidad hizo cada llamada y facilita retirar permisos después.
La configuración mínima suele incluir:
- Un
NetworkPolicyque permita solo el endpoint de correo y los servicios necesarios. - Un
Secretmontado únicamente en el worker que necesita autenticarse. - Un
ResourceQuotapara que una repetición accidental no consuma todo el nodo. - Un
JobconbackoffLimitacotado y una política de limpieza definida. - Un nombre de ejecución que conecte Kubernetes, CI y el buzón.
No conviene dar acceso de lectura a todos los secretos “para depurar más rápido”. Ese atajo hace más difícil distinguir una causa de una exposición. Si el test necesita un proveedor externo, prefiero una credencial de alcance pequeño y rotación automática. La revisión de permisos queda entonces dentro del mismo ticket que la prueba.
Evidencia útil para SRE
Cuando el test falla, guarda evidencia pequeña y suficiente: nombre del Job, razón de terminación, eventos del pod, latencia de cada etapa y estado de entrega. Evita guardar tokens, cuerpos de correo o URLs con credenciales.
También conviene separar tres tiempos: publicación del evento, aceptación por el worker y aparición en el buzón. Si solo se mide el tiempo total, una regresión de 20 segundos puede parecer un simple timeout. Con las tres medidas, el equipo ve donde se desplazó la latencia.
En el dashboard, una métrica como email_smoke_test_failure_total debe tener etiquetas de baja cardinalidad: stage, provider y reason. No uses el email completo, el test_id o el nombre de usuario como etiqueta. Eso llena el sistema de métricas y hace más dificil encontrar la señal importante.
La interfaz de resultados también debe ser honesta. Si una consola tarda en mostrar el correo, los estados honestos para flujos lentos son preferibles a mostrar “enviado” cuando todavía solo se aceptó la solicitud.
Errores comunes durante el incidente
- Reiniciar todo el Deployment antes de comprobar el estado del proveedor.
- Reutilizar el mismo buzón para varios Jobs concurrentes.
- Buscar por asunto sin verificar el identificador de la ejecución.
- Aumentar el timeout sin medir cada etapa.
- Dejar Jobs y buzones vivos después del test.
- Copiar el contenido del mensaje en un canal de incidente.
- Confundir
tem emailcon una dirección legítima solo porque el test antiguo la usaba.
El más costoso suele ser el segundo. Un correo de otra ejecución puede hacer que el test pase mientras una versión rota sigue desplegándose. La prueba verde resulta entonces más peligrosa que una roja.
Checklist antes de cerrar el ticket
- [ ] ¿El fallo está asignado a aplicación, red, proveedor o lectura del buzón?
- [ ] ¿Cada ejecución tiene un destinatario y un
test_idúnico? - [ ] ¿Los logs conectan API, worker, Job y recepción?
- [ ] ¿El namespace tiene permisos y cuota mínimos?
- [ ] ¿Se borraron usuario, Job y fixture al terminar?
- [ ] ¿La evidencia excluye secretos y contenido sensible?
- [ ] ¿El cambio mejora una señal medible, no solo el timeout?
El objetivo de un smoke test de email no es demostrar que Kubernetes funciona. Es producir una señal confiable sobre un flujo concreto. Cuando el contrato es pequeño, el aislamiento es real y la evidencia está conectada, el equipo SRE puede corregir la causa sin convertir cada correo perdido en un incidente de todo el clúster.
Top comments (0)