LLM WikiAccess-protected knowledge portal
← 스터디 홈
6편 · 약 27분

카오스 엔지니어링: 실패 주입과 복원력 검증

복원력은 가정이 아니라 실험이다

"우리 DB가 죽으면 replica가 자동으로 primary로 승격된다"는 말을 팀 전체가 믿고 있다. 그런데 마지막으로 그 failover를 실제로 테스트해 본 것은 언제인가? 아니면 한 번도 테스트하지 않은 채 이론을 믿고 있는가?

카오스 엔지니어링(Chaos Engineering)은 이 질문에 정직하게 답하기 위해 만들어진 실천 방법이다. 시스템에 의도적으로 실패를 주입하고, 그 결과를 관찰하여 실제 복원력을 검증한다. "잘 된다고 믿는 것"과 "실제로 잘 되는 것" 사이의 간격을 좁히는 작업이다.


카오스 엔지니어링의 역사

Netflix의 Chaos Monkey

2011년 Netflix는 AWS로 인프라를 전면 이전하면서 한 가지 도구를 함께 만들었다. Chaos Monkey다. 이 도구는 프로덕션 환경에서 무작위로 가상 서버 인스턴스를 종료한다. 개발자들이 단일 장애점(SPOF)을 설계 단계에서 제거하도록 강제하기 위해서였다.

처음에는 팀 내부에서 반발이 컸다. "왜 멀쩡한 서버를 일부러 끄는가?" 하지만 Chaos Monkey가 발견한 취약점들이 실제 장애 전에 수정되기 시작하면서 인식이 바뀌었다.

Netflix는 Chaos Monkey를 Simian Army로 확장했다. Chaos Gorilla(가용 영역 전체 장애 시뮬레이션), Latency Monkey(네트워크 지연 주입), Security Monkey(보안 설정 검사) 등이 포함된다. 2012년 Netflix는 Chaos Monkey를 오픈소스로 공개했다.

Principles of Chaos Engineering

2016년 Netflix, Gremlin 등 업계가 함께 카오스 엔지니어링의 원칙(Principles of Chaos Engineering)을 발표했다. principlesofchaos.org에 공개된 이 원칙이 오늘날 카오스 엔지니어링의 표준 정의다.


카오스 엔지니어링의 다섯 가지 원칙

1. 정상 상태(Steady State) 동작에 관한 가설을 세운다

실험 전에 시스템이 "정상적으로 동작하는 상태"를 정의한다. CPU, 요청 성공률, 응답시간, 에러율 등 측정 가능한 지표로 표현한다. 가설은 구체적이어야 한다.

나쁜 가설: "시스템이 잘 돌아간다" 좋은 가설: "primary DB가 종료되면 30초 이내에 replica가 승격되고 쓰기 요청의 99%가 재개된다"

2. 실제 프로덕션 이벤트를 실험 변수로 사용한다

실험은 현실과 닮아야 한다. 이론적인 장애가 아닌 실제로 발생할 수 있는 이벤트를 선택한다. 하드웨어 장애, 네트워크 단절, 프로세스 중단, 디스크 포화, 의존 서비스 지연 등이 해당된다.

3. 프로덕션에서 실험한다

스테이징 환경은 프로덕션의 축약판이다. 트래픽 패턴, 데이터 분포, 서비스 의존성 모두 다르다. 진짜 복원력은 실제 트래픽 하에서만 검증할 수 있다. 물론 안전 장치가 필요하다.

4. 자동화하여 지속적으로 실험한다

일회성 GameDay보다 CI/CD 파이프라인에 통합된 자동 실험이 더 신뢰할 수 있다. 배포마다 또는 정기 스케줄로 실험이 실행되어야 한다.

5. 폭발 반경(Blast Radius)을 최소화한다

실험은 통제 하에 이루어진다. 모든 실험에는 명확한 중단 조건과 자동 롤백(kill switch)이 있어야 한다. 작은 범위에서 시작해 안전이 확인된 후 점차 범위를 넓힌다.


실험 설계 방법론

카오스 실험은 5단계로 진행한다.

1. 정상 상태 정의 측정 지표 확정 베이스라인 수집 2. 가설 수립 실험 "X가 실패해도 Y는 N초 내 복구" 3. 폭발 반경 최소화 단일 인스턴스 kill switch 준비 4. 실험 실행 및 관찰 실패 주입 메트릭 수집 5. 분석 및 개선 가설 검증/반증 취약점 수정
카오스 실험 설계 5단계

실험 예시: DB Primary 장애

1. 정상 상태 정의
   - 쓰기 성공률 ≥ 99.9%
   - p95 응답시간 ≤ 50ms
   - 초당 쓰기 요청 = 500 TPS

2. 가설 수립
   - "Primary가 갑자기 종료되면 30초 이내에 replica가
     primary로 승격되고 쓰기 성공률이 99%로 회복된다"

3. 폭발 반경 최소화
   - 스테이징 환경에서 먼저 실험
   - 트래픽 5%만 해당 클러스터로 라우팅
   - kill switch: 즉시 원복 스크립트 준비

4. 실험 실행
   - Primary 프로세스 강제 종료 (kill -9)
   - 메트릭 수집 시작 (에러율, 응답시간, TPS)
   - 30초 간격으로 상태 체크

5. 분석
   - 실제 failover 시간 측정
   - 정상 상태 회복 여부 확인
   - 예상과 다른 동작 기록

주요 카오스 엔지니어링 도구

Chaos Toolkit

Python 기반의 오픈소스 프레임워크다. YAML로 실험을 정의하고 플러그인으로 다양한 환경을 지원한다. AWS, Kubernetes, Prometheus와의 통합이 잘 되어 있다.

chaostoolkit 실험 YAML 구조
experiment.yaml
├── title: "DB Primary Failover"
├── description: "primary 종료 후 30초 내 복구 검증"
├── steady-state-hypothesis:
│   └── probes: [에러율 < 1%, 응답시간 < 100ms]
├── method:
│   └── action: DB primary 프로세스 종료
└── rollbacks:
    └── action: primary 재시작

Gremlin

상용 카오스 엔지니어링 플랫폼이다. GUI와 API를 모두 제공하며, 실험 템플릿과 안전 장치가 잘 갖춰져 있다. CPU 부하, 메모리 포화, 네트워크 지연, 패킷 손실, 디스크 I/O 포화, 프로세스 종료 등 다양한 공격 유형을 지원한다.

LitmusChaos

Kubernetes 네이티브 카오스 엔지니어링 플랫폼이다. 2017년 시작되어 CNCF incubating 프로젝트로 채택되었다. ChaosExperiment CRD로 실험을 정의하고, Argo Workflows로 오케스트레이션한다.

Litmus ChaosExperiment 예시
kind: ChaosExperiment
metadata:
  name: pod-delete
spec:
  definition:
    args:
      - -c
      - ./experiments/pod-delete
    env:
      - TOTAL_CHAOS_DURATION: "30"
      - CHAOS_INTERVAL: "10"
      - FORCE: "false"

AWS Fault Injection Simulator (FIS)

AWS 관리형 카오스 엔지니어링 서비스다. RDS 장애, EC2 종료, AZ 중단 시뮬레이션 등을 IAM 권한으로 제어하며 AWS 콘솔에서 실험을 정의하고 모니터링한다.


데이터베이스 카오스 실험

DBA와 데이터 플랫폼 엔지니어에게 특히 중요한 실험 유형이다.

Failover 검증

실험: MySQL Primary 갑작스런 종료
목표: replica auto-promotion 시간 측정
가설: 30초 이내 새 primary 선출, 애플리케이션 자동 재연결

주입 방법:
  kill -9 <mysqld_pid>           # 또는 AWS RDS reboot with failover

관찰 지표:
  - 쓰기 에러 발생 시간 구간
  - Replica promotion 소요 시간
  - 애플리케이션 재연결 시간
  - 데이터 유실 여부 (gtid_executed 비교)

흔히 발견되는 문제:
  - read_only 플래그 자동 해제 실패
  - 애플리케이션 connection pool이 구 primary에 고착
  - VIP 전환 지연

복제 지연 시뮬레이션

실험: replica에 인위적 지연 주입
목표: 복제 지연 시 읽기 부하 동작 확인
가설: 복제 지연 > 5초 시 알림 발생, 읽기가 primary로 자동 전환

주입 방법:
  SET GLOBAL SQL_DELAY = 30;    # MySQL 복제 지연 30초 설정

관찰 지표:
  - Seconds_Behind_Master 모니터링
  - 알림 발화 시점
  - 애플리케이션의 stale read 감지 여부

디스크 포화 시뮬레이션

실험: DB 서버 디스크 90% 포화
목표: 디스크 임계 알림과 자동 조치 확인
가설: 디스크 80% 도달 시 알림 발화, 90% 시 자동 오래된 binlog 삭제 실행

주입 방법:
  dd if=/dev/zero of=/tmp/filler bs=1G count=<N>   # 더미 파일 생성

관찰 지표:
  - 알림 발화 시점 (임계값 80%)
  - Auto-cleanup 동작 여부
  - InnoDB 쓰기 지연 증가 패턴

커넥션 폭주 시뮬레이션

실험: max_connections 한계 도달
목표: connection exhaustion 시 애플리케이션 동작 확인
가설: pool 초과 요청은 적절한 에러로 처리되고 circuit breaker가 동작한다

주입 방법:
  # max_connections에 가까운 연결 대량 생성
  for i in $(seq 1 500); do mysql -h <host> -e "SELECT SLEEP(60)" & done

관찰 지표:
  - Too many connections 에러 발생 시점
  - 애플리케이션 에러율 변화
  - circuit breaker 동작 여부

Kubernetes 카오스 실험

Pod 삭제

실험: 특정 서비스 Pod 무작위 삭제
목표: Pod 재시작 중 서비스 가용성 확인
가설: Pod 삭제 후 10초 이내 새 Pod가 Ready 상태로 전환된다

kubectl delete pod -l app=my-service --force

네트워크 지연 주입

실험: 특정 서비스 간 네트워크 지연 100ms 주입
목표: timeout 설정과 retry 동작 검증
가설: 100ms 지연 시 정상 동작, 500ms 지연 시 timeout 에러 발생

tc qdisc add dev eth0 root netem delay 100ms  # Litmus Chaos로 자동화

GameDay 개념과 운영

GameDay는 팀 전체가 참여하는 카오스 실험 훈련이다. 실제 장애를 시뮬레이션하고 대응 절차를 연습한다.

GameDay 진행 순서

1. 사전 준비 (1~2주 전)
   - 실험 시나리오 선정 (실제 발생 가능성 높은 것)
   - 참가자 역할 배정 (IC, 관찰자, 실험자)
   - 안전 장치 준비 (kill switch, rollback 절차)

2. 당일 진행
   - 정상 상태 확인 후 실험 시작
   - 실시간 관찰 및 팀 대응
   - 필요 시 kill switch 실행

3. 사후 회고
   - 가설 검증 결과 정리
   - 예상과 다른 동작 분류
   - 취약점 수정 계획 수립

GameDay 빈도

  • 초기 도입: 분기 1회, 스테이징 환경에서 시작
  • 성숙 단계: 월 1회 자동화 실험 + 분기 1회 GameDay
  • 고도화 단계: 프로덕션 자동 실험 + 대규모 GameDay

복원력 성숙도 단계

레벨 1 — 수동 실험
스테이징 환경에서 수동으로 failover 테스트 · 분기 GameDay 실시
기준 지표: MTTR 측정 시작, 주요 failover 시나리오 1회 이상 검증
레벨 2 — 자동화 실험
CI 파이프라인 통합 · 정기 자동 실험 실행 · Litmus/Chaos Toolkit 도입
기준 지표: 실험 자동화율 > 50%, 취약점 발견-수정 사이클 < 1주
레벨 3 — 프로덕션 지속 실험
프로덕션 자동 실험 · 실험 결과 대시보드 · 신규 기능에 카오스 리뷰 포함
기준 지표: MTTR 지속 감소, 예방적 취약점 발견 > 반응적 장애 대응
카오스 엔지니어링 성숙도 모델

카오스 엔지니어링 도입 시 흔한 실수

"프로덕션은 너무 위험하다": 스테이징에서만 테스트하면 실제 복원력을 알 수 없다. 안전 장치를 갖춘 프로덕션 실험이 목표다.

"큰 실험부터": 첫 실험은 항상 작게 시작한다. 단일 Pod, 1% 트래픽, 짧은 지속 시간.

"도구만 도입하면 된다": Chaos Monkey를 설치한다고 카오스 엔지니어링이 되지 않는다. 관찰성(observability)이 먼저다. 메트릭이 없으면 실험 결과를 해석할 수 없다.

"가설 없이 실행": 목적 없는 실패 주입은 단순 파괴 행위다. 가설을 세우고 결과를 측정해야 실험이다.

"한 번 하고 끝": 시스템은 계속 변한다. 배포가 있을 때마다, 아키텍처가 바뀔 때마다 실험을 반복해야 한다.


References