SRE: Chaos Engineering, Rompiendo Cosas a Propósito
Apoya este blog
Si te resulta util este contenido, considera apoyar el blog.
Introducción
En los artículos anteriores cubrimos SLIs y SLOs, gestión de incidentes, y observabilidad. Tenés métricas, alertas, trazas, runbooks y procesos de postmortem. Pero, ¿cómo sabés que algo de eso realmente funciona antes de que un incidente real pase?
Ahí es donde entra el chaos engineering. La idea es simple: inyectar fallas intencionalmente en tu sistema para verificar que tus mecanismos de resiliencia, monitoreo, alertas y procesos de respuesta a incidentes funcionan como se espera. Es como un simulacro de incendio, pero para tu infraestructura.
En este artículo vamos a cubrir los principios del chaos engineering, cómo configurar Litmus y Chaos Mesh en Kubernetes, cómo planificar y ejecutar game days, y cómo construir una cultura donde romper cosas a propósito no solo es aceptado sino fomentado.
Vamos al tema.
¿Por qué romper cosas a propósito?
Los sistemas complejos fallan de maneras complejas. No podés predecir todos los modos de falla leyendo código o diagramas de arquitectura. La única forma de realmente entender cómo se comporta tu sistema bajo fallas es hacerlo fallar.
El chaos engineering te ayuda a:
- Descubrir modos de falla desconocidos antes de que te muerdan en producción a las 3am
- Validar tu monitoreo y alertas, ¿tu alerta de SLO realmente salta cuando la latencia sube?
- Probar tus runbooks, ¿el ingeniero de guardia realmente puede seguirlos bajo presión?
- Construir confianza, saber que tu sistema puede manejar un crash de pod o una partición de red te hace dormir mejor
- Reducir MTTR, practicar respuesta a incidentes te hace más rápido cuando pasan incidentes reales
El equipo de ingeniería de Netflix, que fue pionero en chaos engineering con Chaos Monkey, lo dijo mejor: “La mejor manera de evitar fallas es fallar constantemente.”
El proceso de chaos engineering
Chaos engineering no es simplemente matar pods al azar. Es un proceso disciplinado:
- Definir estado estable: ¿Cómo se ve “normal”? Usá tus SLIs (del artículo 1) como base.
- Hipotetizar: “Si matamos un pod, los pods restantes deberían manejar la carga y el SLO no debería violarse.”
- Inyectar falla: Realmente matá el pod (o cualquier falla que estés probando).
- Observar: Mirá tus métricas, trazas y logs. ¿El sistema se comportó como esperabas?
- Aprender: Si no se comportó como esperabas, encontraste una debilidad. Arreglala antes de que una falla real la encuentre.
Siempre empezá de a poco. Matá un pod, no todo el deployment. Agregá 100ms de latencia, no 30 segundos. El objetivo son experimentos controlados, no caos descontrolado.
Chaos Mesh: chaos engineering para Kubernetes
Chaos Mesh es un proyecto de la CNCF que provee un conjunto completo de experimentos de caos para Kubernetes. Es fácil de instalar y tiene una interfaz web copada para manejar experimentos.
Instalalo con Helm:
helm repo add chaos-mesh https://charts.chaos-mesh.org
helm repo update
helm install chaos-mesh chaos-mesh/chaos-mesh \
--namespace chaos-mesh \
--create-namespace \
--set chaosDaemon.runtime=containerd \
--set chaosDaemon.socketPath=/run/containerd/containerd.sock
Ahora definamos algunos experimentos. Todos los experimentos son custom resources de Kubernetes, así que encajan perfectamente en un flujo de GitOps con ArgoCD.
1. Falla de pod: matar un pod al azar
# chaos/pod-kill.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: tr-web-pod-kill
namespace: default
spec:
action: pod-kill
mode: one
selector:
namespaces:
- default
labelSelectors:
app: tr-web
scheduler:
cron: "@every 2h" # Matar un pod cada 2 horas
duration: "60s"
Esto mata un pod aleatorio de tr-web cada 2 horas. Si tu deployment tiene múltiples réplicas y un readiness probe adecuado, los usuarios no deberían notar nada. Si lo notan, encontraste un problema.
2. Latencia de red: agregar delay artificial
# chaos/network-delay.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: tr-web-network-delay
namespace: default
spec:
action: delay
mode: all
selector:
namespaces:
- default
labelSelectors:
app: tr-web
delay:
latency: "200ms"
jitter: "50ms"
correlation: "25"
direction: to
target:
selector:
namespaces:
- default
labelSelectors:
app: postgresql
mode: all
duration: "5m"
Esto agrega 200ms de latencia (con 50ms de jitter) entre tus pods web y la base de datos por 5 minutos. Es increíblemente útil para probar configuraciones de timeout y lógica de reintentos.
3. Partición de red: aislar un servicio
# chaos/network-partition.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: tr-web-partition
namespace: default
spec:
action: partition
mode: all
selector:
namespaces:
- default
labelSelectors:
app: tr-web
direction: both
target:
selector:
namespaces:
- default
labelSelectors:
app: postgresql
mode: all
duration: "2m"
Esto corta completamente el tráfico de red entre tus pods web y la base de datos. ¿Tu app crashea? ¿Muestra una página de error amigable? ¿Se recupera cuando la red vuelve? Son preguntas importantes.
4. Estrés de CPU: simular contención de recursos
# chaos/cpu-stress.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: StressChaos
metadata:
name: tr-web-cpu-stress
namespace: default
spec:
mode: one
selector:
namespaces:
- default
labelSelectors:
app: tr-web
stressors:
cpu:
workers: 2
load: 80
duration: "5m"
Esto quema 80% de CPU en un pod. Con resource limits apropiados y HPA, tu cluster debería manejar esto sin problemas.
5. Falla de DNS: romper la resolución de nombres
# chaos/dns-failure.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: DNSChaos
metadata:
name: tr-web-dns-failure
namespace: default
spec:
action: error
mode: all
selector:
namespaces:
- default
labelSelectors:
app: tr-web
patterns:
- "api.github.com"
duration: "5m"
Esto hace que la resolución DNS falle para api.github.com desde tus pods web. ¿Recordás cómo arreglamos
el problema de la API de GitHub con un pool de Hackney dedicado? Este experimento verifica que ese arreglo
realmente funciona, las conexiones a la base de datos no deberían verse afectadas aunque GitHub sea
inalcanzable.
Litmus: workflows de experimentos
Litmus es otro proyecto de la CNCF que se enfoca en workflows de experimentos. Mientras Chaos Mesh es genial para experimentos individuales, Litmus destaca en orquestar escenarios de caos con múltiples pasos.
Un workflow de Litmus te permite encadenar múltiples experimentos con pasos de validación:
# litmus/workflow-resilience-test.yaml
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
name: tr-web-resilience-test
namespace: litmus
spec:
entrypoint: resilience-test
templates:
- name: resilience-test
steps:
# Paso 1: Verificar estado estable
- - name: verify-baseline
template: check-slo
# Paso 2: Matar un pod
- - name: pod-kill
template: pod-kill-experiment
# Paso 3: Verificar que el SLO todavía se cumple
- - name: verify-after-pod-kill
template: check-slo
# Paso 4: Agregar latencia de red
- - name: network-delay
template: network-delay-experiment
# Paso 5: Verificar SLO de latencia
- - name: verify-after-delay
template: check-latency-slo
# Paso 6: Limpieza y verificación final
- - name: final-verification
template: check-slo
Este workflow verifica que tu servicio se mantiene dentro de los objetivos de SLO incluso mientras es sometido a caos. Si algún paso de verificación falla, sabés que tenés una brecha de resiliencia que arreglar.
Game days: caos estructurado
Un game day es un evento programado donde el equipo inyecta fallas intencionalmente y practica respuesta a incidentes. Es como un simulacro de incendio, pero todos saben que está pasando (casi todos).
Acá cómo planificar y ejecutar un game day:
Antes del game day (1 semana antes)
- Elegí una fecha y hora (durante horario laboral, nunca un viernes)
- Definí los escenarios que querés probar (2-3 por game day, no más)
- Notificá a los stakeholders que las cosas pueden romperse
- Asigná roles: facilitador, operador de caos, observadores
- Preparar los experimentos (tener los archivos YAML listos)
- Revisar runbooks para los escenarios que vas a probar
Checklist template de game day:
# game-days/2026-02-25-checklist.md
# Game Day: 25 de Febrero, 2026
## Pre-game
- [ ] Todos los participantes confirmados
- [ ] Stakeholders notificados
- [ ] Dashboards de monitoreo abiertos
- [ ] Runbooks accesibles
- [ ] Procedimientos de rollback listos
- [ ] Canal de comunicación creado (#gameday-2026-02-25)
## Escenario 1: Recuperación ante falla de pod
- **Hipótesis**: Matar 1 de 3 pods de tr-web no debería causar errores visibles para el usuario
- **Experimento**: `chaos/pod-kill.yaml`
- **Criterio de éxito**: SLI de disponibilidad se mantiene por encima de 99.9%
- **Duración**: 10 minutos
- **Resultado**: [ PASS / FAIL ]
- **Notas**: ___
## Escenario 2: Pico de latencia en base de datos
- **Hipótesis**: 200ms de latencia extra a la DB debería disparar la alerta de SLO de latencia pero no la de disponibilidad
- **Experimento**: `chaos/network-delay.yaml`
- **Criterio de éxito**: La alerta de latencia salta en 5 minutos, la app sigue funcional
- **Duración**: 15 minutos
- **Resultado**: [ PASS / FAIL ]
- **Notas**: ___
## Escenario 3: Falla de dependencia externa
- **Hipótesis**: La API de GitHub estando inaccesible no debería afectar los tiempos de carga del blog
- **Experimento**: `chaos/dns-failure.yaml`
- **Criterio de éxito**: Las páginas del blog cargan normalmente, solo la sección de sponsors está vacía
- **Duración**: 10 minutos
- **Resultado**: [ PASS / FAIL ]
- **Notas**: ___
## Post-game
- [ ] Todos los experimentos limpiados
- [ ] Sistemas de vuelta al estado estable
- [ ] Retro del game day completada
- [ ] Acciones creadas como issues de GitHub
- [ ] Resultados compartidos con el equipo
Durante el game day
- El facilitador mantiene el tiempo y coordina
- El operador de caos aplica los experimentos
- Los observadores miran dashboards y logs (usando el stack de observabilidad del artículo 3)
- El ingeniero de guardia responde como si fuera un incidente real
- Todos toman notas
Después del game day
Hacé una retro (igual que un postmortem pero para el ejercicio). ¿Qué funcionó? ¿Qué no? ¿Qué te sorprendió? Creá acciones para todo lo que necesite arreglo.
Chaos engineering para aplicaciones Elixir/BEAM
La VM BEAM tiene algunas características únicas que afectan el chaos engineering:
Los árboles de supervisión manejan muchas fallas automáticamente. Cuando matás un proceso Elixir, el supervisor lo reinicia. Esto es genial para la resiliencia pero significa que necesitás probar fallas más duras (como particiones de red o agotamiento de recursos) para encontrar problemas reales.
La distribución (clustering de Erlang) es sensible a problemas de red. Si tus nodos están en cluster
(como nuestra app con RELEASE_DISTRIBUTION=name), probá qué pasa cuando los nodos pierden conectividad:
# chaos/cluster-partition.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: beam-cluster-partition
namespace: default
spec:
action: partition
mode: all
selector:
namespaces:
- default
labelSelectors:
app: tr-web
fieldSelectors:
metadata.name: tr-web-0
direction: both
target:
selector:
namespaces:
- default
labelSelectors:
app: tr-web
fieldSelectors:
metadata.name: tr-web-1
mode: all
duration: "5m"
Esto particiona dos nodos de tu cluster de Erlang. ¿Tu app maneja el netsplit de forma elegante? ¿Se recupera cuando vuelve la conectividad? Son preguntas importantes para aplicaciones BEAM en cluster.
Qué probar primero
Si recién empezás con chaos engineering, acá hay una lista priorizada:
- Falla de un solo pod: ¿Tu servicio puede manejar la pérdida de una instancia? (Esto es el mínimo)
- Timeout de dependencia: ¿Qué pasa cuando un servicio externo responde lento?
- Falla de DNS: ¿Tu app puede manejar fallas de resolución de nombres de forma elegante?
- Agotamiento de recursos: ¿Qué pasa cuando llegás a los límites de CPU o memoria?
- Partición de red: ¿Tu servicio puede manejar estar aislado de una dependencia?
- Presión de disco: ¿Qué pasa cuando queda poco espacio en disco?
- Desfase de reloj: ¿Qué pasa cuando el tiempo se desfasa entre nodos?
Empezá con el #1 y avanzá hacia abajo. Cada experimento debería repetirse regularmente, no solo una vez.
Guardarraíles de seguridad
El chaos engineering puede salir mal si no tenés cuidado. Acá hay reglas de seguridad no negociables:
- Siempre tené un kill switch. Todo experimento tiene que poder detenerse inmediatamente.
- Empezá en staging. Nunca corras un experimento nuevo en producción por primera vez.
- Control del radio de explosión. Afectá un pod, no todos. Un servicio, no todos.
- Acotado en tiempo. Todo experimento tiene una duración. Nada de caos sin fin.
- Monitoreá continuamente. Si los SLOs se violan más allá de umbrales aceptables, abortá.
- Solo en horario laboral (para experimentos manuales). No hagas game days un viernes a las 5pm.
- Comunicá. Todos los que necesitan saber deberían saber que hay caos en curso.
Juntando todo
Acá está el modelo de madurez de chaos engineering:
- Nivel 0 - Sin caos: Esperás que las cosas funcionen. (La mayoría de los equipos arrancan acá)
- Nivel 1 - Game days manuales: Game days trimestrales con escenarios pre-planificados
- Nivel 2 - Caos automatizado en staging: Experimentos regulares corren automáticamente en staging
- Nivel 3 - Caos automatizado en producción: Caos continuo en producción con guardarraíles basados en SLOs
- Nivel 4 - Caos como CI: Experimentos de caos corren como parte de tu pipeline de deployment
No necesitás llegar al Nivel 4 para obtener valor. Incluso el Nivel 1 (game days trimestrales) va a mejorar dramáticamente la confianza de tu equipo y la velocidad de respuesta a incidentes.
Notas finales
Chaos engineering no se trata de romper cosas por diversión. Se trata de construir confianza en que tus sistemas pueden manejar las fallas que inevitablemente van a ocurrir. Cada experimento que pasa te dice “este modo de falla está manejado.” Cada experimento que falla te dice “arreglá esto antes de que una falla real lo encuentre.”
Las herramientas que cubrimos, Chaos Mesh, Litmus, checklists de game days, son todas gratis y funcionan genial en Kubernetes. Empezá con un simple experimento de pod-kill en staging y construí desde ahí. Lo más difícil no son las herramientas, es conseguir el buy-in organizacional para romper cosas intencionalmente. Pero una vez que le mostrás al equipo el primer bug que encontraste a través del caos, se van a convencer.
Esto cierra nuestra serie de cuatro partes sobre SRE. Fuimos desde medir la confiabilidad (SLIs/SLOs) hasta responder a fallas (gestión de incidentes) hasta ver lo que está pasando (observabilidad) hasta encontrar debilidades proactivamente (chaos engineering). Juntas, estas prácticas te dan una base sólida para correr sistemas confiables.
¡Espero que te haya resultado útil y lo hayas disfrutado! ¡Hasta la próxima!
Errata
Si encontrás algún error o tenés alguna sugerencia, por favor mandame un mensaje para que se corrija.
También podés revisar el código fuente y los cambios en las fuentes acá
$ Comentarios
Online: 0Por favor inicie sesión para poder escribir comentarios.