Split View: Chaos Engineering 실전 가이드: Litmus와 Chaos Mesh로 Kubernetes 장애 주입과 복원력 검증
Chaos Engineering 실전 가이드: Litmus와 Chaos Mesh로 Kubernetes 장애 주입과 복원력 검증
- 들어가며
- Chaos Engineering 원칙
- Litmus vs Chaos Mesh 비교표
- 설치 가이드
- ChaosExperiment 설계
- GameDay 프로세스
- SLO 기반 정상 상태 가설 검증
- 실패 사례와 복구 절차
- 운영 시 주의사항 체크리스트
- 참고자료

들어가며
"모든 것은 결국 실패한다(Everything fails, all the time)." AWS CTO Werner Vogels의 이 말은 분산 시스템 운영의 핵심 진리를 담고 있다. 아무리 견고하게 설계된 시스템이라도 예기치 않은 장애가 발생할 수 있으며, 문제는 장애의 발생 여부가 아니라 장애 발생 시 시스템이 얼마나 빠르고 안전하게 복원되느냐이다.
Chaos Engineering은 이러한 철학을 기반으로, 통제된 환경에서 의도적으로 장애를 주입하여 시스템의 복원력(Resilience)을 사전에 검증하는 방법론이다. Netflix가 2010년대 초반에 Chaos Monkey를 도입한 이래, Chaos Engineering은 프로덕션 시스템의 신뢰성을 보장하는 핵심 엔지니어링 프랙티스로 자리잡았다. 특히 Kubernetes 환경에서는 Pod 장애, 네트워크 지연, 노드 다운, I/O 오류 등 다양한 유형의 장애가 발생할 수 있으며, 이를 사전에 실험하고 대응 체계를 갖추는 것이 운영 안정성의 핵심이다.
이 글에서는 Kubernetes 환경에서 가장 널리 사용되는 두 가지 오픈소스 Chaos Engineering 플랫폼인 LitmusChaos와 Chaos Mesh를 심층적으로 비교하고, 실제 프로덕션 환경에서의 장애 주입 실험 설계부터 GameDay 운영, SLO 기반 정상 상태 검증, 그리고 실패 사례와 복구 절차까지 종합적으로 다룬다.
Chaos Engineering 원칙
Chaos Engineering은 단순히 "시스템을 고장내는 것"이 아니라, 과학적 실험 방법론을 따르는 체계적인 접근이다. Netflix가 정립한 Chaos Engineering의 핵심 원칙은 다음과 같다.
1. 정상 상태에 대한 가설 수립 (Steady State Hypothesis)
실험 전에 시스템의 "정상 상태"를 정의한다. 이는 측정 가능한 비즈니스 메트릭이나 기술 지표로 표현되어야 한다. 예를 들어 "API 응답 시간 p99가 500ms 이하", "에러율이 0.1% 미만", "주문 처리량이 초당 100건 이상" 등이 정상 상태의 가설이 된다.
2. 실제 세계의 이벤트로 실험 (Real-World Events)
실험에서 주입하는 장애는 실제로 발생할 수 있는 시나리오를 반영해야 한다. Pod 크래시, 네트워크 파티션, 디스크 I/O 지연, CPU 과부하, DNS 장애 등이 대표적이다.
3. 프로덕션에서 실험 실행 (Run Experiments in Production)
시스템의 실제 동작을 가장 정확하게 검증하려면 프로덕션 환경에서 실험해야 한다. 다만 이는 충분한 안전장치(abort 조건, blast radius 제한)를 갖춘 후에 수행되어야 한다.
4. 지속적 자동화 (Automate Experiments to Run Continuously)
Chaos Engineering은 일회성 이벤트가 아니라, CI/CD 파이프라인에 통합하여 지속적으로 실행하는 것을 목표로 한다.
5. 폭발 반경 최소화 (Minimize Blast Radius)
실험의 영향 범위를 최소한으로 제한하고, 비정상 상황 발생 시 즉시 실험을 중단할 수 있는 메커니즘을 갖춰야 한다.
Litmus vs Chaos Mesh 비교표
두 플랫폼을 다양한 관점에서 비교하여 조직의 요구사항에 맞는 도구를 선택할 수 있도록 한다.
| 항목 | LitmusChaos | Chaos Mesh |
|---|---|---|
| CNCF 등급 | Incubating (2022년 승격) | Incubating (2022년 승격) |
| 개발 주체 | ChaosNative (Harness 인수) | PingCAP / 커뮤니티 |
| 지원 환경 | Kubernetes, VM, Cloud, Bare Metal | Kubernetes 전용 |
| 설치 방식 | Helm / kubectl / Operator | Helm / kubectl |
| 웹 UI | ChaosCenter (풀 대시보드) | Chaos Dashboard |
| 실험 정의 | ChaosExperiment + ChaosEngine CRD | 각 Chaos 타입별 CRD (PodChaos, NetworkChaos 등) |
| 실험 허브 | ChaosHub (커뮤니티 공유 실험) | 내장 실험 + 커스텀 |
| SLO 통합 | Probe 기반 정상 상태 검증 | StatusCheck + Grafana 연동 |
| RBAC | 네이티브 지원 (프로젝트/팀 단위) | Kubernetes RBAC 연동 |
| 스케줄링 | CronWorkflow 기반 | Schedule CRD 기반 |
| 학습 곡선 | 중간 (개념이 다소 복잡) | 낮음 (직관적 CRD 구조) |
| 커뮤니티 규모 | GitHub Stars 4.4k+ | GitHub Stars 6.5k+ |
| CI/CD 통합 | API/SDK, GitHub Actions 지원 | API, CLI 기반 |
| 상용 지원 | Harness Chaos Engineering | 커뮤니티 기반 |
선택 기준 요약: Kubernetes 외 환경도 포함한 포괄적인 Chaos Engineering이 필요하거나, 체계적인 실험 관리와 ChaosHub 기반의 실험 공유가 중요하다면 LitmusChaos가 적합하다. Kubernetes 전용 환경에서 빠르게 시작하고 싶거나, 직관적인 CRD 기반의 장애 주입을 선호한다면 Chaos Mesh가 좋은 선택이다.
설치 가이드
LitmusChaos 설치
LitmusChaos는 ChaosCenter(관리 대시보드)와 Chaos Infrastructure(실험 실행 에이전트)로 구성된다.
# LitmusChaos 네임스페이스 생성
kubectl create namespace litmus
# Helm 리포지토리 추가
helm repo add litmuschaos https://litmuschaos.github.io/litmus-helm/
helm repo update
# ChaosCenter 설치 (MongoDB, Auth Server, Frontend, Backend 포함)
helm upgrade --install litmus litmuschaos/litmus \
--namespace litmus \
--set portal.server.service.type=ClusterIP \
--set portal.frontend.service.type=ClusterIP \
--set mongodb.persistence.enabled=true \
--set mongodb.persistence.storageClass=standard \
--set mongodb.persistence.size=20Gi
# 설치 확인
kubectl get pods -n litmus
# ChaosCenter UI 접속 (포트 포워딩)
kubectl port-forward svc/litmus-frontend-service -n litmus 9091:9091
# 기본 관리자 계정: admin / litmus
# 첫 로그인 후 반드시 비밀번호 변경 필요
Chaos Mesh 설치
Chaos Mesh는 Controller Manager, Chaos Daemon, Dashboard로 구성된다.
# Chaos Mesh 네임스페이스 생성
kubectl create namespace chaos-mesh
# Helm 리포지토리 추가
helm repo add chaos-mesh https://charts.chaos-mesh.org
helm repo update
# Chaos Mesh 설치
helm upgrade --install chaos-mesh chaos-mesh/chaos-mesh \
--namespace chaos-mesh \
--set chaosDaemon.runtime=containerd \
--set chaosDaemon.socketPath=/run/containerd/containerd.sock \
--set dashboard.securityMode=true \
--set dashboard.create=true \
--version 2.7.0
# 설치 확인
kubectl get pods -n chaos-mesh
# CRD 확인
kubectl get crd | grep chaos-mesh
# Dashboard 접속 (포트 포워딩)
kubectl port-forward svc/chaos-dashboard -n chaos-mesh 2333:2333
주의할 점은 Chaos Mesh의 chaosDaemon.runtime과 chaosDaemon.socketPath를 클러스터의 컨테이너 런타임에 맞게 설정해야 한다는 것이다. containerd, CRI-O, Docker 각각의 소켓 경로가 다르므로, 클러스터의 런타임 환경을 먼저 확인해야 한다.
ChaosExperiment 설계
Pod Kill 실험
가장 기본적인 Chaos 실험으로, 특정 Pod를 강제 종료하여 애플리케이션의 자동 복구 능력을 검증한다.
Litmus - Pod Delete 실험:
# litmus-pod-delete.yaml
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
name: pod-delete-chaos
namespace: production
spec:
engineState: active
annotationCheck: 'false'
appinfo:
appns: production
applabel: app=payment-service
appkind: deployment
chaosServiceAccount: litmus-admin
experiments:
- name: pod-delete
spec:
components:
env:
# 실험 지속 시간 (초)
- name: TOTAL_CHAOS_DURATION
value: '60'
# Pod 삭제 간격 (초)
- name: CHAOS_INTERVAL
value: '10'
# 강제 삭제 여부
- name: FORCE
value: 'false'
# 삭제할 Pod 수
- name: PODS_AFFECTED_PERC
value: '50'
# 실험 순서 (parallel 또는 serial)
- name: SEQUENCE
value: 'parallel'
probe:
- name: payment-health-check
type: httpProbe
mode: Continuous
httpProbe/inputs:
url: 'http://payment-service.production.svc:8080/health'
method:
get:
criteria: ==
responseCode: '200'
runProperties:
probeTimeout: 5s
interval: 5s
retry: 3
probePollingInterval: 2s
Chaos Mesh - PodChaos 실험:
# chaos-mesh-pod-kill.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: pod-kill-payment
namespace: chaos-mesh
spec:
action: pod-kill
mode: fixed-percent
value: '50'
selector:
namespaces:
- production
labelSelectors:
app: payment-service
# gracePeriod: 0 이면 강제 종료
gracePeriod: 30
duration: '60s'
---
# 스케줄링된 실험 (매주 수요일 오전 10시)
apiVersion: chaos-mesh.org/v1alpha1
kind: Schedule
metadata:
name: scheduled-pod-kill
namespace: chaos-mesh
spec:
schedule: '0 10 * * 3'
type: PodChaos
historyLimit: 5
concurrencyPolicy: Forbid
podChaos:
action: pod-kill
mode: one
selector:
namespaces:
- production
labelSelectors:
app: payment-service
gracePeriod: 30
duration: '30s'
Network Latency 실험
네트워크 지연을 주입하여 마이크로서비스 간 통신에 대한 타임아웃 설정과 Circuit Breaker 패턴이 올바르게 동작하는지 검증한다.
Chaos Mesh - NetworkChaos (지연 주입):
# chaos-mesh-network-delay.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: network-delay-between-services
namespace: chaos-mesh
spec:
action: delay
mode: all
selector:
namespaces:
- production
labelSelectors:
app: order-service
delay:
latency: '200ms'
jitter: '50ms'
correlation: '25'
direction: to
target:
selector:
namespaces:
- production
labelSelectors:
app: payment-service
mode: all
duration: '5m'
---
# 네트워크 패킷 손실 실험
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: network-loss-experiment
namespace: chaos-mesh
spec:
action: loss
mode: all
selector:
namespaces:
- production
labelSelectors:
app: api-gateway
loss:
loss: '30'
correlation: '25'
direction: both
duration: '3m'
IO Fault 실험
디스크 I/O 장애를 시뮬레이션하여 데이터베이스, 캐시, 로깅 시스템의 복원력을 검증한다.
Chaos Mesh - IOChaos (I/O 장애 주입):
# chaos-mesh-io-fault.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
name: io-latency-database
namespace: chaos-mesh
spec:
action: latency
mode: one
selector:
namespaces:
- production
labelSelectors:
app: postgres
volumePath: /var/lib/postgresql/data
path: '**/*'
delay: '100ms'
percent: 50
duration: '5m'
---
# I/O 에러 주입 (읽기 작업에 에러 반환)
apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
name: io-error-experiment
namespace: chaos-mesh
spec:
action: fault
mode: one
selector:
namespaces:
- production
labelSelectors:
app: postgres
volumePath: /var/lib/postgresql/data
path: '**/*.dat'
errno: 5
percent: 30
duration: '3m'
CPU Stress 실험
CPU 과부하 상황을 시뮬레이션하여 HPA(Horizontal Pod Autoscaler)의 스케일 아웃 동작과 서비스 품질 저하 시의 대응을 검증한다.
Chaos Mesh - StressChaos (CPU/Memory 스트레스):
# chaos-mesh-stress.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: StressChaos
metadata:
name: cpu-stress-api
namespace: chaos-mesh
spec:
mode: all
selector:
namespaces:
- production
labelSelectors:
app: api-server
stressors:
cpu:
workers: 4
load: 80
memory:
workers: 2
size: '512MB'
duration: '5m'
containerNames:
- api-server
GameDay 프로세스
GameDay는 Chaos Engineering 실험을 조직적으로 수행하는 이벤트이다. 단순한 기술적 테스트를 넘어서, 팀의 장애 대응 프로세스와 커뮤니케이션을 실전적으로 검증하는 것이 핵심이다.
1단계: 사전 준비 (1-2주 전)
- 범위 정의: 실험 대상 서비스, 영향 범위(blast radius), 실험 유형을 확정한다.
- 가설 수립: 정상 상태 가설을 SLO 기반으로 정의한다. 예를 들어 "주문 서비스의 Pod 50%가 종료되어도 p99 응답 시간 1초 이하, 에러율 1% 미만을 유지해야 한다"는 형태로 구체화한다.
- 관찰 도구 준비: 실험 중 모니터링할 대시보드(Grafana), 로그 시스템(ELK/Loki), 트레이싱 시스템(Jaeger/Tempo)을 사전에 구성한다.
- 롤백 계획: 실험 중 예기치 않은 상황 발생 시의 긴급 중단 절차(abort)와 복구 절차를 문서화한다.
- 이해관계자 통지: 실험 일정과 예상 영향 범위를 관련 팀(운영, 비즈니스, 고객지원)에 사전 공유한다.
2단계: 실험 실행 (당일)
- 사전 점검: 실험 전 시스템의 현재 상태가 정상인지 확인한다. 이미 장애가 진행 중인 상태에서 Chaos 실험을 수행하면 안 된다.
- 장애 주입: 사전에 정의한 ChaosExperiment를 순차적으로 실행한다. 가벼운 실험부터 시작하여 강도를 점진적으로 높인다.
- 실시간 관찰: 정상 상태 가설의 지표를 실시간으로 모니터링하고, 이상 징후 발생 시 즉시 기록한다.
- 중단 조건 판단: 사전 정의한 중단 조건(에러율 5% 초과, 응답 시간 5초 초과 등)에 도달하면 즉시 실험을 중단한다.
3단계: 사후 분석 (실험 후 1주 이내)
- 결과 문서화: 각 실험의 가설, 실제 결과, 관찰된 이상 현상을 상세히 기록한다.
- 개선 항목 도출: 가설이 실패한 경우(시스템이 예상대로 복원되지 않은 경우), 구체적인 개선 항목과 담당자를 지정한다.
- 액션 아이템 추적: 도출된 개선 항목의 구현 상태를 지속적으로 추적하고, 다음 GameDay에서 개선 여부를 재검증한다.
SLO 기반 정상 상태 가설 검증
Chaos Engineering 실험의 성패는 **정상 상태 가설(Steady State Hypothesis)**의 정의와 검증에 달려 있다. SLO(Service Level Objective)를 기반으로 정상 상태를 정의하면 비즈니스 관점에서 의미 있는 실험 결과를 도출할 수 있다.
SLO 정의 예시
| 서비스 | SLI (지표) | SLO (목표) | 측정 방법 |
|---|---|---|---|
| API Gateway | 가용성 | 99.9% (월간) | Prometheus up 메트릭 |
| 주문 서비스 | 응답 시간 p99 | 500ms 이하 | Histogram http_request_duration_seconds |
| 결제 서비스 | 에러율 | 0.1% 미만 | http_requests_total{status=~"5.."} / 전체 요청 |
| 검색 서비스 | 처리량 | 초당 1000 요청 이상 | rate(http_requests_total[5m]) |
| 데이터베이스 | 쿼리 지연 p95 | 100ms 이하 | pg_stat_statements |
LitmusChaos Probe를 활용한 검증
LitmusChaos는 Probe 메커니즘을 통해 실험 실행 중 정상 상태 가설을 자동으로 검증한다. HTTP Probe, CMD Probe, Prometheus Probe, Kubernetes Probe 등 다양한 유형을 지원하며, 실험 결과가 가설을 충족하지 못하면 실험이 "Failed"로 표시된다.
HTTP Probe는 특정 엔드포인트의 응답 코드와 응답 시간을 실험 전(SOT), 실험 중(Continuous), 실험 후(EOT) 시점에 검증할 수 있다. Prometheus Probe는 Prometheus 쿼리를 실행하여 SLI 메트릭이 SLO 임계치를 벗어나지 않는지 검증한다. 이를 통해 실험의 성공 여부를 객관적으로 판단할 수 있다.
Chaos Mesh StatusCheck를 활용한 검증
Chaos Mesh에서는 StatusCheck CRD와 Workflow를 조합하여 정상 상태 검증을 자동화할 수 있다. 실험 실행 전후로 HTTP 요청이나 커스텀 스크립트를 실행하여 시스템 상태를 확인하고, Grafana 대시보드와 연동하여 SLO 지표의 변화를 시각적으로 추적한다.
실패 사례와 복구 절차
사례 1: Chaos Experiment가 중단되지 않는 문제
증상: NetworkChaos 실험의 duration이 만료되었음에도 네트워크 지연이 해제되지 않아, 프로덕션 서비스에 지속적인 영향이 발생한다.
원인: Chaos Daemon이 OOM Kill되거나 노드가 재시작되면서 tc(traffic control) 규칙의 정리(cleanup)가 수행되지 못한 경우. 또는 Chaos Mesh Controller Manager가 삭제 이벤트를 처리하지 못한 경우.
복구 절차:
# 1. 진행 중인 Chaos 리소스 강제 삭제
kubectl delete networkchaos network-delay-between-services -n chaos-mesh
# 2. Chaos Daemon이 정상 동작 중인지 확인
kubectl get pods -n chaos-mesh -l app.kubernetes.io/component=chaos-daemon
# 3. Chaos Daemon이 비정상이면 재시작
kubectl rollout restart daemonset chaos-daemon -n chaos-mesh
# 4. 수동으로 tc 규칙 정리 (영향을 받는 노드에서)
# 노드에 SSH 접속 후
tc qdisc show dev eth0
tc qdisc del dev eth0 root netem 2>/dev/null || true
# 5. iptables 규칙 정리 (네트워크 파티션 실험인 경우)
iptables -L -n | grep CHAOS
iptables -F CHAOS-INPUT 2>/dev/null || true
iptables -F CHAOS-OUTPUT 2>/dev/null || true
예방 조치: Chaos Daemon의 리소스 요청/제한을 충분히 설정하고, 실험 후 자동 정리 여부를 확인하는 모니터링 알림을 구성한다. 프로덕션 환경에서는 반드시 duration 필드를 짧게 설정하고 점진적으로 늘린다.
사례 2: Chaos 실험이 의도하지 않은 Pod에 영향
증상: 라벨 셀렉터 오류로 인해 Chaos 실험이 대상 서비스 외의 다른 서비스 Pod에도 장애를 주입하여 연쇄적인 서비스 장애가 발생한다.
원인: 라벨 셀렉터가 너무 광범위하게 설정되었거나, 네임스페이스 지정 누락으로 인해 전체 클러스터의 Pod가 대상에 포함된 경우.
복구 절차:
- 즉시 Chaos 리소스를 삭제하여 실험을 중단한다.
- 영향을 받은 Pod의 상태를 확인하고, 필요 시 Deployment를 롤아웃 재시작한다.
- Chaos 실험의 셀렉터를 수정하여 정확한 대상만 선택하도록 변경한다.
예방 조치: 실험 전에 --dry-run 또는 대상 Pod 목록을 사전 확인하는 스크립트를 실행한다. 네임스페이스를 반드시 명시적으로 지정하고, annotationCheck를 활성화하여 Chaos 대상 애노테이션이 있는 Pod만 선택하도록 한다.
사례 3: StressChaos로 인한 노드 전체 불안정
증상: CPU/메모리 스트레스 실험이 대상 Pod뿐만 아니라 동일 노드의 다른 Pod에도 영향을 미쳐, 노드 전체가 NotReady 상태가 된다.
원인: 스트레스 실험이 cgroup 제한 없이 실행되어 노드 수준의 리소스 고갈이 발생한 경우. 또는 대상 Pod에 리소스 제한(limits)이 설정되지 않아 스트레스가 노드 전체에 확산된 경우.
복구 절차:
- Chaos 리소스를 즉시 삭제한다.
- 노드가 NotReady 상태라면 kubelet을 재시작하거나 노드를 drain한 후 재부팅한다.
- 영향을 받은 워크로드의 복구 상태를 확인한다.
예방 조치: StressChaos 실험 대상 Pod에는 반드시 리소스 limits를 설정한다. containerNames 필드를 사용하여 특정 컨테이너에만 스트레스를 주입하고, 처음에는 낮은 부하(CPU load 20-30%)부터 시작하여 점진적으로 높인다.
사례 4: IOChaos 실험 후 데이터 정합성 문제
증상: I/O 장애 주입 실험 후, 데이터베이스의 WAL(Write-Ahead Log) 파일이 손상되어 데이터베이스가 정상적으로 시작되지 않는다.
원인: I/O 에러 주입(action: fault)이 데이터베이스의 크리티컬 경로에 적용되어 트랜잭션 로그가 불완전하게 기록된 경우.
복구 절차:
- 데이터베이스 Pod를 삭제하고 PVC에서 재시작하여 자동 복구를 시도한다.
- WAL 복구 도구를 사용하여 손상된 로그를 복원한다.
- 자동 복구가 불가능한 경우, 최근 백업에서 데이터를 복원한다.
예방 조치: IOChaos 실험에서 데이터베이스를 대상으로 할 때는 반드시 읽기 전용 경로에만 장애를 주입한다. path 필드를 사용하여 WAL 디렉토리를 제외하고, percent 값을 낮게(10-20%) 설정하여 부분적인 I/O 장애만 시뮬레이션한다. 실험 전 데이터베이스의 최신 백업이 존재하는지 반드시 확인한다.
사례 5: LitmusChaos ChaosEngine이 완료되지 않는 문제
증상: ChaosEngine 리소스의 상태가 Running에서 변하지 않고, 실험이 무한히 진행되는 것처럼 보인다.
원인: Chaos Runner Pod가 crash loop에 빠지거나, 실험 실행 Pod의 이미지 풀링에 실패하여 실험이 시작되지 못한 경우.
복구 절차:
- ChaosEngine의 상태와 관련 Pod를 확인한다:
kubectl describe chaosengine <name> -n <namespace> - Chaos Runner와 실험 Pod의 로그를 확인한다.
- ChaosEngine의
engineState를stop으로 변경하여 실험을 중단한다. - 문제를 해결한 후 새로운 ChaosEngine을 생성하여 재시도한다.
예방 조치: 실험에 사용되는 컨테이너 이미지를 사전에 노드에 풀링해두고, ChaosEngine에 타임아웃을 설정하여 지정된 시간 내에 완료되지 않으면 자동으로 중단되도록 한다.
운영 시 주의사항 체크리스트
실험 설계 시 점검사항
- 정상 상태 가설(Steady State Hypothesis)이 측정 가능한 지표로 정의되어 있는가
- 실험의 폭발 반경(blast radius)이 명확히 제한되어 있는가
- 라벨 셀렉터와 네임스페이스가 정확한 대상만 선택하는지 사전 검증했는가
- 실험 중단 조건(abort criteria)이 사전에 정의되어 있는가
- 롤백/복구 절차가 문서화되어 있고 팀원들이 숙지하고 있는가
프로덕션 적용 시 점검사항
- 스테이징 환경에서 충분히 테스트한 후 프로덕션에 적용하고 있는가
- 실험 시작 전 시스템의 현재 상태가 정상인지 확인했는가
- 실험 중 실시간 모니터링(Grafana 대시보드, 알림)이 구성되어 있는가
- 비즈니스 크리티컬 시간대(결제 피크, 이벤트 기간)를 피해서 실험을 수행하고 있는가
- 실험 일정과 영향 범위를 관련 팀에 사전 공유했는가
- Chaos RBAC을 통해 실험 실행 권한이 적절히 제한되어 있는가
실험 실행 중 점검사항
- 모든 SLI 지표가 실시간으로 모니터링되고 있는가
- 중단 조건에 도달할 경우 즉시 실험을 중단할 수 있는 준비가 되어 있는가
- 실험 결과(성공/실패)를 기록하고 있는가
- 예상치 못한 부수 효과(side effect)가 발견되면 즉시 보고하고 있는가
실험 후 점검사항
- 주입된 장애가 완전히 정리(cleanup)되었는지 확인했는가
- tc 규칙, iptables 규칙 등 시스템 수준의 변경이 원복되었는지 확인했는가
- 실험 결과를 문서화하고 개선 항목을 도출했는가
- 도출된 개선 항목에 담당자와 기한을 지정했는가
- 다음 GameDay 일정과 재검증 계획을 수립했는가
참고자료
- LitmusChaos 공식 문서
- LitmusChaos GitHub 리포지토리
- Chaos Mesh 공식 문서
- Chaos Mesh GitHub 리포지토리
- Principles of Chaos Engineering
- CNCF - LitmusChaos Q4 2025 업데이트
- Chaos Mesh로 Kubernetes 장애 실험 실행하기 - Hands-on Guide
- Top 5 Chaos Engineering Platforms Compared - Loft Labs
- AWS Blog - Chaos Engineering with LitmusChaos on Amazon EKS
Practical Guide to Chaos Engineering: Fault Injection and Resilience Validation in Kubernetes with Litmus and Chaos Mesh
- Introduction
- Chaos Engineering Principles
- Litmus vs Chaos Mesh Comparison
- Installation Guide
- ChaosExperiment Design
- GameDay Process
- SLO-Based Steady State Hypothesis Validation
- Failure Case Studies and Recovery Procedures
- Operational Checklist
- References

Introduction
"Everything fails, all the time." This statement by AWS CTO Werner Vogels captures a fundamental truth about operating distributed systems. No matter how robustly a system is designed, unexpected failures can occur. The question is not whether failures will happen, but how quickly and safely the system recovers when they do.
Chaos Engineering is a methodology rooted in this philosophy that proactively validates system resilience by intentionally injecting faults in a controlled environment. Since Netflix introduced Chaos Monkey in the early 2010s, Chaos Engineering has established itself as a core engineering practice for ensuring the reliability of production systems. In Kubernetes environments in particular, various types of failures can occur -- Pod crashes, network latency, node outages, I/O errors, and more -- making it essential to experiment with these scenarios in advance and build response mechanisms for operational stability.
This post provides an in-depth comparison of the two most widely used open-source Chaos Engineering platforms for Kubernetes environments -- LitmusChaos and Chaos Mesh -- and comprehensively covers everything from designing fault injection experiments in real production environments, to GameDay operations, SLO-based steady state validation, and failure case studies with recovery procedures.
Chaos Engineering Principles
Chaos Engineering is not simply about "breaking systems." It is a systematic approach that follows the scientific experimental method. The core principles of Chaos Engineering, as established by Netflix, are as follows.
1. Build a Hypothesis Around Steady State (Steady State Hypothesis)
Before running an experiment, define the "steady state" of the system. This must be expressed as measurable business metrics or technical indicators. For example, "API response time at p99 is under 500ms," "error rate is below 0.1%," or "order throughput exceeds 100 requests per second" serve as steady state hypotheses.
2. Vary Real-World Events (Real-World Events)
The faults injected in experiments must reflect scenarios that can actually occur. Typical examples include Pod crashes, network partitions, disk I/O latency, CPU overload, and DNS failures.
3. Run Experiments in Production
To most accurately validate actual system behavior, experiments should be run in the production environment. However, this should only be done after sufficient safeguards (abort conditions, blast radius limitations) are in place.
4. Automate Experiments to Run Continuously
Chaos Engineering is not a one-time event. The goal is to integrate experiments into CI/CD pipelines for continuous execution.
5. Minimize Blast Radius
Limit the scope of experimental impact to the absolute minimum, and ensure mechanisms are in place to immediately halt experiments when anomalies occur.
Litmus vs Chaos Mesh Comparison
The following table compares the two platforms across various dimensions to help organizations choose the right tool for their requirements.
| Category | LitmusChaos | Chaos Mesh |
|---|---|---|
| CNCF Status | Incubating (promoted in 2022) | Incubating (promoted in 2022) |
| Developed By | ChaosNative (acquired by Harness) | PingCAP / Community |
| Supported Envs | Kubernetes, VM, Cloud, Bare Metal | Kubernetes only |
| Installation | Helm / kubectl / Operator | Helm / kubectl |
| Web UI | ChaosCenter (full dashboard) | Chaos Dashboard |
| Experiment Def. | ChaosExperiment + ChaosEngine CRD | Per-chaos-type CRDs (PodChaos, NetworkChaos, etc.) |
| Experiment Hub | ChaosHub (community-shared experiments) | Built-in experiments + custom |
| SLO Integration | Probe-based steady state validation | StatusCheck + Grafana integration |
| RBAC | Native support (project/team level) | Kubernetes RBAC integration |
| Scheduling | CronWorkflow-based | Schedule CRD-based |
| Learning Curve | Moderate (concepts can be complex) | Low (intuitive CRD structure) |
| Community Size | GitHub Stars 4.4k+ | GitHub Stars 6.5k+ |
| CI/CD Integration | API/SDK, GitHub Actions support | API, CLI-based |
| Commercial Support | Harness Chaos Engineering | Community-based |
Selection Criteria Summary: If you need comprehensive Chaos Engineering that extends beyond Kubernetes, or if systematic experiment management and ChaosHub-based experiment sharing are important, LitmusChaos is the better fit. If you are working exclusively in Kubernetes and want to get started quickly, or prefer intuitive CRD-based fault injection, Chaos Mesh is an excellent choice.
Installation Guide
LitmusChaos Installation
LitmusChaos consists of ChaosCenter (management dashboard) and Chaos Infrastructure (experiment execution agent).
# Create LitmusChaos namespace
kubectl create namespace litmus
# Add Helm repository
helm repo add litmuschaos https://litmuschaos.github.io/litmus-helm/
helm repo update
# Install ChaosCenter (includes MongoDB, Auth Server, Frontend, Backend)
helm upgrade --install litmus litmuschaos/litmus \
--namespace litmus \
--set portal.server.service.type=ClusterIP \
--set portal.frontend.service.type=ClusterIP \
--set mongodb.persistence.enabled=true \
--set mongodb.persistence.storageClass=standard \
--set mongodb.persistence.size=20Gi
# Verify installation
kubectl get pods -n litmus
# Access ChaosCenter UI (port forwarding)
kubectl port-forward svc/litmus-frontend-service -n litmus 9091:9091
# Default admin credentials: admin / litmus
# Be sure to change the password after first login
Chaos Mesh Installation
Chaos Mesh consists of Controller Manager, Chaos Daemon, and Dashboard.
# Create Chaos Mesh namespace
kubectl create namespace chaos-mesh
# Add Helm repository
helm repo add chaos-mesh https://charts.chaos-mesh.org
helm repo update
# Install Chaos Mesh
helm upgrade --install chaos-mesh chaos-mesh/chaos-mesh \
--namespace chaos-mesh \
--set chaosDaemon.runtime=containerd \
--set chaosDaemon.socketPath=/run/containerd/containerd.sock \
--set dashboard.securityMode=true \
--set dashboard.create=true \
--version 2.7.0
# Verify installation
kubectl get pods -n chaos-mesh
# Verify CRDs
kubectl get crd | grep chaos-mesh
# Access Dashboard (port forwarding)
kubectl port-forward svc/chaos-dashboard -n chaos-mesh 2333:2333
An important note: chaosDaemon.runtime and chaosDaemon.socketPath in Chaos Mesh must be configured to match the container runtime of your cluster. The socket paths differ for containerd, CRI-O, and Docker, so you must verify your cluster's runtime environment first.
ChaosExperiment Design
Pod Kill Experiment
This is the most fundamental chaos experiment, which forcefully terminates specific Pods to validate the application's self-healing capabilities.
Litmus - Pod Delete Experiment:
# litmus-pod-delete.yaml
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
name: pod-delete-chaos
namespace: production
spec:
engineState: active
annotationCheck: 'false'
appinfo:
appns: production
applabel: app=payment-service
appkind: deployment
chaosServiceAccount: litmus-admin
experiments:
- name: pod-delete
spec:
components:
env:
# Experiment duration (seconds)
- name: TOTAL_CHAOS_DURATION
value: '60'
# Pod deletion interval (seconds)
- name: CHAOS_INTERVAL
value: '10'
# Force delete
- name: FORCE
value: 'false'
# Number of Pods to delete
- name: PODS_AFFECTED_PERC
value: '50'
# Execution order (parallel or serial)
- name: SEQUENCE
value: 'parallel'
probe:
- name: payment-health-check
type: httpProbe
mode: Continuous
httpProbe/inputs:
url: 'http://payment-service.production.svc:8080/health'
method:
get:
criteria: ==
responseCode: '200'
runProperties:
probeTimeout: 5s
interval: 5s
retry: 3
probePollingInterval: 2s
Chaos Mesh - PodChaos Experiment:
# chaos-mesh-pod-kill.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: pod-kill-payment
namespace: chaos-mesh
spec:
action: pod-kill
mode: fixed-percent
value: '50'
selector:
namespaces:
- production
labelSelectors:
app: payment-service
# gracePeriod: 0 means force kill
gracePeriod: 30
duration: '60s'
---
# Scheduled experiment (every Wednesday at 10:00 AM)
apiVersion: chaos-mesh.org/v1alpha1
kind: Schedule
metadata:
name: scheduled-pod-kill
namespace: chaos-mesh
spec:
schedule: '0 10 * * 3'
type: PodChaos
historyLimit: 5
concurrencyPolicy: Forbid
podChaos:
action: pod-kill
mode: one
selector:
namespaces:
- production
labelSelectors:
app: payment-service
gracePeriod: 30
duration: '30s'
Network Latency Experiment
Inject network latency to verify that timeout configurations and Circuit Breaker patterns between microservices are functioning correctly.
Chaos Mesh - NetworkChaos (Latency Injection):
# chaos-mesh-network-delay.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: network-delay-between-services
namespace: chaos-mesh
spec:
action: delay
mode: all
selector:
namespaces:
- production
labelSelectors:
app: order-service
delay:
latency: '200ms'
jitter: '50ms'
correlation: '25'
direction: to
target:
selector:
namespaces:
- production
labelSelectors:
app: payment-service
mode: all
duration: '5m'
---
# Network packet loss experiment
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: network-loss-experiment
namespace: chaos-mesh
spec:
action: loss
mode: all
selector:
namespaces:
- production
labelSelectors:
app: api-gateway
loss:
loss: '30'
correlation: '25'
direction: both
duration: '3m'
IO Fault Experiment
Simulate disk I/O faults to validate the resilience of databases, caches, and logging systems.
Chaos Mesh - IOChaos (I/O Fault Injection):
# chaos-mesh-io-fault.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
name: io-latency-database
namespace: chaos-mesh
spec:
action: latency
mode: one
selector:
namespaces:
- production
labelSelectors:
app: postgres
volumePath: /var/lib/postgresql/data
path: '**/*'
delay: '100ms'
percent: 50
duration: '5m'
---
# I/O error injection (return errors on read operations)
apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
name: io-error-experiment
namespace: chaos-mesh
spec:
action: fault
mode: one
selector:
namespaces:
- production
labelSelectors:
app: postgres
volumePath: /var/lib/postgresql/data
path: '**/*.dat'
errno: 5
percent: 30
duration: '3m'
CPU Stress Experiment
Simulate CPU overload conditions to validate HPA (Horizontal Pod Autoscaler) scale-out behavior and service quality degradation responses.
Chaos Mesh - StressChaos (CPU/Memory Stress):
# chaos-mesh-stress.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: StressChaos
metadata:
name: cpu-stress-api
namespace: chaos-mesh
spec:
mode: all
selector:
namespaces:
- production
labelSelectors:
app: api-server
stressors:
cpu:
workers: 4
load: 80
memory:
workers: 2
size: '512MB'
duration: '5m'
containerNames:
- api-server
GameDay Process
A GameDay is an organizational event for conducting Chaos Engineering experiments. Beyond simple technical testing, the core purpose is to validate the team's incident response processes and communication in a realistic setting.
Phase 1: Preparation (1-2 Weeks Before)
- Define Scope: Finalize the target services, blast radius, and experiment types.
- Establish Hypotheses: Define steady state hypotheses based on SLOs. For example, formalize them as: "Even if 50% of order service Pods are terminated, p99 response time should remain under 1 second and error rate should stay below 1%."
- Prepare Observability Tools: Pre-configure dashboards (Grafana), log systems (ELK/Loki), and tracing systems (Jaeger/Tempo) for monitoring during the experiment.
- Rollback Plan: Document emergency abort procedures and recovery steps for unexpected situations during the experiment.
- Notify Stakeholders: Share the experiment schedule and expected blast radius with relevant teams (operations, business, customer support) in advance.
Phase 2: Experiment Execution (Day Of)
- Pre-Flight Check: Verify that the current system state is healthy before the experiment. Never run chaos experiments while an existing incident is in progress.
- Fault Injection: Execute the pre-defined ChaosExperiments sequentially. Start with lightweight experiments and progressively increase intensity.
- Real-Time Observation: Monitor steady state hypothesis metrics in real time and immediately record any anomalies.
- Abort Criteria Evaluation: Immediately halt the experiment if pre-defined abort conditions are reached (e.g., error rate exceeds 5%, response time exceeds 5 seconds).
Phase 3: Post-Analysis (Within 1 Week After the Experiment)
- Document Results: Record each experiment's hypothesis, actual results, and observed anomalies in detail.
- Identify Improvements: When a hypothesis fails (i.e., the system did not recover as expected), assign specific improvement items with owners.
- Track Action Items: Continuously track the implementation status of identified improvements and re-validate them in the next GameDay.
SLO-Based Steady State Hypothesis Validation
The success or failure of a Chaos Engineering experiment depends on the definition and validation of the Steady State Hypothesis. Defining steady state based on SLOs (Service Level Objectives) enables deriving experiment results that are meaningful from a business perspective.
SLO Definition Examples
| Service | SLI (Indicator) | SLO (Target) | Measurement Method |
|---|---|---|---|
| API Gateway | Availability | 99.9% (monthly) | Prometheus up metric |
| Order Service | Response time p99 | Under 500ms | Histogram http_request_duration_seconds |
| Payment Service | Error rate | Below 0.1% | http_requests_total{status=~"5.."} / total requests |
| Search Service | Throughput | Over 1000 requests/sec | rate(http_requests_total[5m]) |
| Database | Query latency p95 | Under 100ms | pg_stat_statements |
Validation with LitmusChaos Probes
LitmusChaos automatically validates steady state hypotheses during experiment execution through its Probe mechanism. It supports various probe types including HTTP Probe, CMD Probe, Prometheus Probe, and Kubernetes Probe. If experiment results fail to meet the hypothesis, the experiment is marked as "Failed."
HTTP Probe can verify an endpoint's response code and response time at three stages: before the experiment (SOT), during the experiment (Continuous), and after the experiment (EOT). Prometheus Probe executes Prometheus queries to verify that SLI metrics do not breach SLO thresholds. This enables objective determination of experiment success or failure.
Validation with Chaos Mesh StatusCheck
In Chaos Mesh, steady state validation can be automated by combining StatusCheck CRDs with Workflows. HTTP requests or custom scripts are executed before and after experiment runs to verify system state, and Grafana dashboard integration provides visual tracking of SLO metric changes.
Failure Case Studies and Recovery Procedures
Case 1: Chaos Experiment Fails to Clean Up
Symptom: Network latency persists even after the NetworkChaos experiment's duration has expired, causing ongoing impact to production services.
Root Cause: The Chaos Daemon was OOM-killed or the node restarted, preventing cleanup of tc (traffic control) rules. Alternatively, the Chaos Mesh Controller Manager failed to process the deletion event.
Recovery Procedure:
# 1. Force delete the in-progress Chaos resource
kubectl delete networkchaos network-delay-between-services -n chaos-mesh
# 2. Verify the Chaos Daemon is running normally
kubectl get pods -n chaos-mesh -l app.kubernetes.io/component=chaos-daemon
# 3. Restart the Chaos Daemon if it is unhealthy
kubectl rollout restart daemonset chaos-daemon -n chaos-mesh
# 4. Manually clean up tc rules (on the affected node)
# After SSH-ing into the node
tc qdisc show dev eth0
tc qdisc del dev eth0 root netem 2>/dev/null || true
# 5. Clean up iptables rules (for network partition experiments)
iptables -L -n | grep CHAOS
iptables -F CHAOS-INPUT 2>/dev/null || true
iptables -F CHAOS-OUTPUT 2>/dev/null || true
Preventive Measures: Set sufficient resource requests/limits for the Chaos Daemon, and configure monitoring alerts to verify automatic cleanup after experiments. In production environments, always set the duration field to short values and increase gradually.
Case 2: Chaos Experiment Affects Unintended Pods
Symptom: Due to label selector errors, the chaos experiment injects faults into Pods belonging to services other than the intended target, causing cascading service failures.
Root Cause: The label selector was configured too broadly, or the namespace was omitted, causing Pods across the entire cluster to be included as targets.
Recovery Procedure:
- Immediately delete the Chaos resource to halt the experiment.
- Check the status of affected Pods and perform a rollout restart of Deployments if necessary.
- Modify the experiment's selectors to target only the correct Pods.
Preventive Measures: Before running experiments, execute a --dry-run or a script that pre-validates the target Pod list. Always explicitly specify namespaces, and enable annotationCheck to ensure only Pods with chaos-target annotations are selected.
Case 3: StressChaos Destabilizes an Entire Node
Symptom: A CPU/memory stress experiment affects not only the target Pod but also other Pods on the same node, causing the entire node to enter a NotReady state.
Root Cause: The stress experiment ran without cgroup limits, causing node-level resource exhaustion. Alternatively, the target Pod had no resource limits set, allowing the stress to propagate across the entire node.
Recovery Procedure:
- Immediately delete the Chaos resource.
- If the node is in a NotReady state, restart kubelet or drain the node and reboot it.
- Verify the recovery status of affected workloads.
Preventive Measures: Always set resource limits on Pods targeted by StressChaos experiments. Use the containerNames field to inject stress into specific containers only, and start with low load levels (CPU load 20-30%) before gradually increasing.
Case 4: Data Integrity Issues After IOChaos Experiment
Symptom: After an I/O fault injection experiment, database WAL (Write-Ahead Log) files become corrupted, preventing the database from starting normally.
Root Cause: I/O error injection (action: fault) was applied to a critical database path, causing transaction logs to be written incompletely.
Recovery Procedure:
- Delete the database Pod and restart from the PVC to attempt automatic recovery.
- Use WAL recovery tools to restore the corrupted logs.
- If automatic recovery is not possible, restore data from the most recent backup.
Preventive Measures: When targeting databases with IOChaos experiments, always inject faults only on read-only paths. Use the path field to exclude WAL directories, and set the percent value low (10-20%) to simulate only partial I/O failures. Always verify that a recent database backup exists before running the experiment.
Case 5: LitmusChaos ChaosEngine Fails to Complete
Symptom: The ChaosEngine resource status remains stuck at Running and the experiment appears to run indefinitely.
Root Cause: The Chaos Runner Pod entered a crash loop, or the experiment execution Pod failed to pull its image, preventing the experiment from starting.
Recovery Procedure:
- Check the ChaosEngine status and related Pods:
kubectl describe chaosengine <name> -n <namespace> - Examine the logs of the Chaos Runner and experiment Pods.
- Change the ChaosEngine's
engineStatetostopto halt the experiment. - After resolving the issue, create a new ChaosEngine to retry.
Preventive Measures: Pre-pull the container images used in experiments onto nodes, and set timeouts on ChaosEngines so they automatically abort if not completed within the specified time.
Operational Checklist
Experiment Design Checklist
- Is the Steady State Hypothesis defined with measurable metrics?
- Is the experiment's blast radius clearly bounded?
- Have label selectors and namespaces been pre-validated to target only the intended Pods?
- Are abort criteria defined in advance?
- Are rollback/recovery procedures documented and understood by team members?
Production Deployment Checklist
- Has the experiment been thoroughly tested in a staging environment before applying to production?
- Has the current system state been verified as healthy before starting the experiment?
- Is real-time monitoring (Grafana dashboards, alerts) configured for the experiment duration?
- Is the experiment scheduled to avoid business-critical time windows (payment peaks, promotional events)?
- Have the experiment schedule and blast radius been shared with relevant teams in advance?
- Are experiment execution permissions appropriately restricted via Chaos RBAC?
During Experiment Checklist
- Are all SLI metrics being monitored in real time?
- Is the team prepared to immediately halt the experiment if abort conditions are reached?
- Are experiment results (success/failure) being recorded?
- Are unexpected side effects being reported immediately upon discovery?
Post-Experiment Checklist
- Has it been confirmed that all injected faults have been fully cleaned up?
- Has it been verified that system-level changes such as tc rules and iptables rules have been reverted?
- Have experiment results been documented and improvement items identified?
- Have owners and deadlines been assigned to identified improvement items?
- Has the next GameDay schedule and re-validation plan been established?
References
- LitmusChaos Official Documentation
- LitmusChaos GitHub Repository
- Chaos Mesh Official Documentation
- Chaos Mesh GitHub Repository
- Principles of Chaos Engineering
- CNCF - LitmusChaos Q4 2025 Update
- Running Chaos Experiments in Kubernetes with Chaos Mesh - Hands-on Guide
- Top 5 Chaos Engineering Platforms Compared - Loft Labs
- AWS Blog - Chaos Engineering with LitmusChaos on Amazon EKS