장애 시나리오 - Team-likelion-3rd-Project/likelion-devops-7th-3rd-team01 GitHub Wiki

장애 시나리오

1주차(M1)에는 무엇을 어떻게 시험할지만 적는다. 실행 결과는 6주차(M6)에 채운다. 담당: ON 김상협 / CL 김차니 / BE 이용민

ON (온프레미스) 장애 시나리오

김상협 작성. 워커 노드 다운, etcd 복구, MySQL 백업 복원, 복구 시간 측정 등

시나리오 목록

# 장애 유형 영향 탐지 방법 대응 목표 복구 시간
O1 노드 다운

백업 정책

대상 주기 보관 기간 저장 위치

복구 절차

CL (클라우드) 장애 시나리오

2026-10-14: 클라우드 시험 계획과 백업·복구 초안 등록. 실제 시험 결과는 6주차에 기록합니다.

시험 공통 기준

  • 4주차 EC2+kubeadm과 5주차 이후 EKS를 구분해 기록한다. 제어 노드 1대인 kubeadm 구성의 한계는 별도로 남긴다.
  • 테스트 데이터와 AI mock을 사용한다. 시험 전 정상 응답·백업·잔여 노드 용량을 확인한다.
  • 한 번에 한 장애만 시험하고, 대상·시작 시각·복구 방법을 기록한다. 데이터 삭제나 실제 장애 주입은 이 문서 작성 작업에 포함하지 않는다.
  • 복구 시간은 장애 주입부터 정상 응답이 연속 확인될 때까지 측정한다. 장애 전환 시간과 앱 재연결 시간을 구분한다. 목표 시간의 숫자는 팀 협의 후 확정하며 지금은 실측값을 기입하지 않는다.
  • 오류율·응답 시간·파드 상태·ALB 정상 대상·DB/Redis 이벤트와 앱 로그를 함께 확인한다.
ID 장애와 시험 방법 예상 영향·탐지 대응·복구 성공 기준
C1 테스트 작업 노드 1대를 중지해 비정상 종료를 가정한다. 정상 drain 시험과 구분한다. 해당 노드의 파드 중단. 노드 NotReady, 정상 파드 수와 ALB 정상 대상 감소를 관찰한다. 남은 노드에서 파드가 재생성되는지 확인하고 원래 노드를 복구한다. 남은 용량으로 조회가 재개되고 파드 수가 정상화된다. 오류율·복구 시간을 기록한다.
C2 한쪽 AZ의 앱 작업 노드를 모두 중지한다. 실제 AZ 전체 장애가 아닌 앱 계층 부분 모의 시험이다. 한쪽 AZ 앱 중단. ALB 정상 대상과 반대 AZ 앱의 부하를 확인한다. 반대 AZ 앱의 요청 처리와 해당 AZ NAT를 통한 외부 연결을 확인한 뒤 노드를 복구한다. 반대 AZ에서 조회와 외부 통신이 가능하다. 결과를 전체 AZ 장애 검증으로 표현하지 않는다.
C3 테스트 RDS Multi-AZ에서 지원되는 강제 장애 전환 기능으로 전환을 시험한다. 일시적인 DB 연결 실패, readiness 변화와 RDS 이벤트를 관찰한다. 앱이 서비스 엔드포인트로 재연결하도록 한다. 실패하면 연결 풀·DNS 갱신·설정을 확인한다. 전환 후 앱 재배포 없이 읽기·쓰기가 정상화되고 시험 데이터가 유지된다.
C4 시험 데이터 저장 후 만든 RDS 스냅샷을 별도 테스트 DB로 복원한다. 원본 DB는 유지한다. 복원 상태와 소요 시간을 확인한다. 복원 DB의 접근 설정을 확인하고 테스트 앱만 새 엔드포인트에 연결한다. 표본 데이터·건수와 앱 조회를 검증한다. 복원 시점 이후 데이터 차이를 기록하고 임시 DB를 정리한다.
C5 테스트 Redis 복제 그룹의 지원되는 장애 전환 기능으로 Primary 전환을 시험한다. 일시적인 캐시·큐 연결 실패. 복제 그룹 이벤트, 연결 오류, 질문 상태를 확인한다. 앱 재연결, 조회의 DB 대체 응답, DB 상태를 기준으로 한 대기 질문 재투입을 확인한다. 조회와 질문 처리가 회복된다. 이미 FAILED인 질문은 임의로 재실행하지 않으며 중복 처리와 유실 여부를 기록한다.

백업 정책 제안

아래 보관 기간은 초안이며 실제 설정 완료를 의미하지 않는다.

대상 주기·보관 제안 복구 용도
RDS 자동 백업 보관 7일, 주요 변경·장애 시험 전 수동 스냅샷 별도 DB로 복원 후 데이터 검증. 수동 스냅샷은 시험 종료 시 보관 필요성을 확인
Redis 캐시·질문 큐의 복구 기준은 MySQL의 질문 상태 캐시는 재생성하고 미완료 질문은 앱 정책에 따라 재투입. Redis 복제를 영구 데이터 백업으로 간주하지 않음
배포·인프라 구성 변경 시 Git에 버전 기록, Terraform 도입 시 상태 파일의 접근 통제·버전 보관 별도 구성 해당 버전으로 재구성. 비밀값은 Git에 기록하지 않음

복구 절차 공통

  1. 장애 대상과 영향을 확인하고 다른 변경을 멈춘다.
  2. 자동 복구·장애 전환 이벤트를 관찰한다.
  3. 자동 복구가 되지 않으면 원인과 접근·연결 설정을 확인한다.
  4. 데이터 복원이 필요하면 원본을 유지한 채 별도 DB로 복원·검증한다.
  5. 조회·로그인·질문 상태와 오류율을 확인한다.
  6. 시험 변경을 원복하고 임시 자원 정리 및 결과를 기록한다.

실행일·실제 복구 시간·성공 여부는 모두 미실행으로 남긴다. 온프레미스 상세는 담당자 내용 취합 후 보완한다.

BE (백엔드) 장애 시나리오

앱이 의존 서비스 장애를 어떻게 견디는지 시험한다. 인프라 복구(백업·복원)는 ON·CL 부분을 따른다.

원칙

  • MySQL이 데이터의 기준이다. Redis는 캐시와 질문 대기열로만 쓰고, Redis에만 있는 데이터는 사라져도 된다.
  • 외부 서비스(AI, 뉴스 RSS)가 실패해도 사용자 요청이 500으로 끝나지 않는다. 요약은 직전 것을 계속 보여주고, 질문은 FAILED로 끝난다.
  • 앱 Pod는 2개 이상 띄우고, 상태를 Pod 안에 두지 않는다. 어느 Pod가 죽어도 다른 Pod가 이어받는다.
  • readiness는 DB만 본다. Redis가 죽어도 Pod가 트래픽에서 빠지지 않는다.

시나리오 목록

# 장애 유형 영향 탐지 방법 대응 목표 복구 시간
B1 Redis 중단 조회가 느려짐, 질문 처리 지연 앱 로그의 Redis 연결 오류, Grafana Redis 지표 조회는 DB에서 바로 응답. 질문은 DB에 PENDING으로 남았다가 Redis 복구 후 대기열에 다시 들어감. 60초 넘으면 FAILED 조회 실패 0. Redis 복구 후 30초 안에 대기 질문 처리 재개
B2 MySQL 중단 서비스 전체 중단 (503) readiness 실패, Pod Ready 수 0 알림 DB 복구 (ON·CL 복구 절차). 앱은 Pod 재시작 없이 자동 복귀 DB 복구 후 1분 안에 정상 응답
B3 AI 실패 질문 FAILED, 요약 갱신 중단 FAILED 질문 수 지표, 요약 배치 실패 로그 질문은 실패 안내 (하루 10회에서 차감 안 함). 요약은 직전 것 유지. AI 복구 시 자동 정상화 사용자 요청 500 0건
B4 AI 응답 지연 질문이 늦게 FAILED AI 응답 시간 지표 타임아웃 후 FAILED. 워커는 다음 질문 처리 워커 멈춤 0
B5 뉴스 RSS 실패 요약이 갱신되지 않음 요약 배치 실패 로그, 홈 generatedAt이 1시간 넘게 그대로 직전 요약 유지, 화면에 갱신 지연 안내 RSS 복구 후 다음 주기(30분) 안에 갱신
B6 (제외) 네이버 검색 실패 외부 검색 API를 쓰지 않기로 해(10/16) 시나리오에서 뺀다. 번호는 다른 문서와 맞추려고 비워 둔다 - - -
B7 처리 중 워커 Pod 삭제 교체되는 동안 질문 완료가 늦어짐 Pod 재시작 이벤트 워커는 처리 중인 질문을 최대 40초 기다려 끝내고, 못 끝내면 PENDING으로 되돌려 대기열에 다시 넣은 뒤 종료 (M5-9). 쿠버네티스가 Pod 재생성. 같은 질문이 두 번 처리되지 않음 질문 FAILED 0
B8 API Pod 1개 삭제 없음 (레플리카 2개 이상) Pod 재시작 이벤트 남은 Pod가 응답, 쿠버네티스가 Pod 재생성. 로그인 유지 (모든 Pod가 같은 JWT 키) 실패 요청 0
B9 요약 배치 실패 그 회차 갱신 누락 CronJob 실패 이벤트 직전 요약 유지. 반쯤 만든 요약은 화면에 보이지 않음 다음 주기(30분) 안에 정상 갱신
B10 롤링 배포 중 요청 실패 배포 중 일부 요청 실패 가능 k6 실패율, Ingress·ALB 5xx 수 readiness 통과 전에는 트래픽을 받지 않고, 종료되는 Pod는 처리 중인 요청을 끝낸 뒤 내려감 (정상 종료) 배포 중 실패 요청 0 (M5 완료 기준)

시험 방법

성능 테스트 시나리오 1(조회)·2(질문)을 k6로 돌리는 도중에 장애를 일으키고, 복구한 뒤 1분 더 관찰한다. AI는 mock.

# 장애 일으키는 방법
B1 온프렘: Redis Pod 삭제 / AWS: ElastiCache 보안그룹에서 앱 접근 차단
B2 온프렘: MySQL Pod 삭제 / AWS: RDS 재부팅
B3 AI_MODE=fail (mock이 항상 오류 반환)
B4 AI_MOCK_DELAY=70s (질문 타임아웃 60초보다 길게)
B5 요약 배치 Job을 따로 만들고 그 Pod에서만 전자신문 도메인을 127.0.0.1로 연결 (hostAliases). RSS 주소가 코드에 있어 설정만으로 바꿀 수 없음
B6 (제외)
B7 PROCESSING 질문이 있을 때 워커 Pod 삭제
B8 kubectl delete pod (API Pod 2개 중 1개)
B9 요약 배치 Pod를 실행 중에 삭제
B10 부하 중 새 이미지로 롤링 배포 (kubectl rollout restart). 위키 "성능 테스트" 시나리오 4와 같은 시험

검증 결과 (6주차)

시나리오 환경 실행일 결과 실제 복구 시간 비고
O1 온프렘
C1 AWS
B1 온프렘 10/26 성공. 조회 2,570건 실패 0, 질문 FAILED·타임아웃 0 Redis Pod 6초 Redis가 없던 동안 일부 요청이 연결 대기로 느려짐 (조회 최대 7.3초, 질문 접수 p95 2.7초). 대기열에서 사라진 질문은 30초 뒤 재투입돼 최대 35.6초에 완료
B1 AWS
B2 온프렘 10/26 성공. 중단 동안 조회 267건(8.55%) 실패, 복구 뒤 실패 0 MySQL Pod 27초, API Ready까지 38초 readiness 실패로 API Pod 2개가 약 22초 동안 트래픽에서 빠짐 (예상대로 서비스 중단). API Pod는 재시작 없이 자동 복귀. 데이터는 PVC에 남음
B2 AWS
B3 온프렘 10/26 성공. 질문 14건 모두 즉시 FAILED, HTTP 실패 0 - 배치는 새 기사가 있던 2개 분야만 AI 실패, 직전 요약 유지 (홈 generatedAt 그대로). 배치 Job이 실패로 끝나 재시도 Pod가 돌았는데, 기사는 첫 Pod가 이미 저장해 "새 기사 0건"으로 성공 처리됨. 그 2개 분야는 다음 새 기사가 들어올 때까지 요약이 갱신되지 않음 → 아래 "개선" 참고
B4 온프렘 10/26 성공. 질문 3건 모두 60초에 FAILED, HTTP 실패 0 - AI_MOCK_DELAY=70s. 워커는 다음 질문을 계속 꺼냄. 원복 후 질문 완료 2초
B5 온프렘 10/26 성공. 6개 분야 모두 수집 실패, 직전 요약 유지 - Job은 2번 시도 후 Failed (CronJob 실패 이벤트로 탐지 가능). RSS가 돌아오면 다음 주기에 갱신
B6 (제외)
B7 온프렘 10/26 성공. 질문 FAILED·타임아웃 0, HTTP 실패 0 새 워커 Ready 16초 AI_MOCK_DELAY=15s. 지워진 워커는 처리 중이던 질문을 끝내고 약 18초 뒤 종료. 교체되는 동안 질문이 대기열에서 기다려 접수→완료 p95 30.6초 (최대 46.7초, 60초 타임아웃 안)
B8 온프렘 10/26 성공. 조회 2,976건 실패 0, p95 57ms 새 API Pod Ready 16초
B9 온프렘 10/27 부분 성공. 반쯤 만든 요약은 화면에 보이지 않음 재시도 Pod 약 50초 10:00 배치를 AI_MOCK_DELAY=70s로 띄워 첫 분야(AI) 요약을 기다리는 중 Pod 삭제. Job 재시도 Pod가 나머지 분야는 정상 갱신(MOBILE_TELECOM·SCIENCE 새 요약). 다만 AI 분야는 지운 Pod가 기사를 이미 저장해 재시도 Pod가 "새 기사 0건"으로 건너뜀 → 다음 새 기사가 들어올 때까지 요약이 갱신되지 않음 (B3과 같은 원인). 수정 후 11:00 배치에서 AI·SECURITY 분야 다시 요약 확인
B10 온프렘 10/26 성공. 7,579건 실패 0 - 성능 테스트 시나리오 4 (롤링 배포 중 p95 105ms)
B10 AWS

온프렘 시험 공통: k6 조회 3040명·질문 310명 부하 중 장애 주입, AI mock. 시험 중 바꾼 설정(AI_MODE, AI_MOCK_DELAY)은 끝난 뒤 원래대로 되돌림.

개선 (B3·B9에서 발견)

항목 내용
문제 요약 배치가 "이번 회차에 새로 저장한 기사 수"로 AI 호출 여부를 정해, 기사만 저장하고 요약 전에 실패한 회차(AI 실패, Pod 삭제)가 있으면 Job 재시도 Pod와 다음 배치가 "새 기사 0건"으로 건너뜀. 그 분야 요약이 다음 새 기사가 올 때까지 멈춤
수정 기준을 "마지막 요약을 저장한 뒤에 수집한 기사가 있는지"로 변경 (백엔드 #15, #16, news_issues.created_at 추가). 새 기사가 정말 없으면 지금처럼 AI를 부르지 않음
확인 10/27 온프렘 11:00 배치에서 10/26 16:30부터 멈춰 있던 AI 분야와 SECURITY 분야가 다시 요약됨