장애 모의 훈련 그리고 배운 점
안녕하세요, SRE팀의 Ken.K입니다. Hyperconnect는 2024년에 접어들면서, 일부 국가의 사용자들에게 체감될 수 있는 장애부터 로그인 실패 같은 심각한 장애까지 여러 번의 대형 사고를 겪었습니다. 사실, 마이크로서비스 단위의 문제는 서비스 운영 중에 자주 발생하는 것이며, 각 프로덕트 팀의 온콜 대응 숙련도가 이미 높기 때문에 잘 대처하고 있습니다.
그러나 대규모 서비스 장애가 발생하면 수많은 마이크로서비스와 복잡한 인프라, 레거시 시스템, 그리고 다양한 관련 부서가 가진 고유의 컨텍스트 때문에 복구 작업이 쉽지 않습니다. 처음 계획했던 완화 전략이 제대로 작동하지 않을 때는, 장애 대응을 총괄해야 할 SRE팀과 관련된 컴포넌트의 담당자들이 당황하는 경우가 발생했습니다. SRE팀은 서비스 품질 유지와 장애 예방 및 대응에 책임을 지고 있으며, 구성원들이 장애 발생 시 더 빠르게 대응하고 문제를 완화할 수 있도록 지원해야 합니다. 저희 팀은 실제 장애와 유사한 상황에 대한 대처 훈련이 실제 상황에서 많은 도움이 될 것이라 판단하여 사내에서 장애 모의 훈련을 진행하기로 했습니다.
이 문서에서는 SRE팀이 장애 모의 훈련을 어떻게 진행했는지, 이를 통해 얻은 인사이트와 향후 더 나은 장애 대응을 위한 개선점을 공유하고자 합니다.
장애 시나리오 설계
장애 시나리오를 구체적으로 설계하기 전에, 팀 내 간단한 미팅을 통해 기본적인 훈련 개념을 마련했습니다.
- 장애 범위: Azar 서비스 아키텍처의 핵심 컴포넌트인 API 서버, 매치 서버, 매치 추천 AI 컴포넌트를 대상으로 했습니다.
- 처음 시도인 만큼 범위를 과도하게 넓히지 않기 위해 Web, Mobile 클라이언트 오류는 제외했습니다.
- Azar 앱은 WebRTC 기반의 소셜 디스커버리 앱으로, 사람 간의 P2P 매치가 핵심 기능이기 때문에, 이를 중심으로 한 장애를 우선적으로 다루기로 하였습니다.
- 훈련 대상: 핵심 컴포넌트를 담당하는 여러 팀 중 가장 최근에 입사한 엔지니어들(액티브 대상자)을 대상으로 하고, 문제 해결이 어려울 경우 팀원들에게 에스컬레이션하도록 유도했습니다(패시브 대상자).
- 장애 환경: Stage 환경에서 진행했습니다.
또한 각 팀의 팀장으로부터 시스템의 취약점을 잘 알고 있는 팀원을 추천받아 장애 시나리오 설계자로 선택했습니다. 두 번의 시나리오 회의를 통해 장애 시나리오를 구체화할 수 있었습니다. 여기서 발견한 사실은 각 팀에서 다루는 시스템을 잘 알고 있는 엔지니어는 어떻게 하면 간단하게 시스템을 망가뜨릴 수 있는 지를 너무 잘 알고 있었으며 자신의 시스템을 파괴한다는 생각에 매우 설레하며 즐겁게 임했다는 점입니다. 훈련 시나리오를 설계할 때 꼭 지키고자 했던 점은 시나리오가 실제로 일어날 법해야한다는 것이었고 그렇기에 장애의 원인은 단일 지점이 되도록 하였습니다.
만들어진 장애 시나리오는 총 4개로, 다음과 같습니다:
API 서비스 관련 Elasticache 네트워크 장애로 인한 전면 장애
Azar에서는 다양한 설정을 유저 속성에 따라 조절할 수 있게 하기 위해 로그인 시점에 다양한 방식으로 유저에게 Segment를 부여하는데, Segment를 부여하는 과정을 Segment 계산이라 하고 유저에게 부여된 Segment를 UserSegment라고 합니다.
Segment를 참조하는 설정을 조회할 때마다 UserSegment를 매번 계산하는 것은 비효율적이므로 UserSegmentCache를 Redis에 캐싱하여 활용합니다. 네트워크 장애가 발생하면 Redis로부터 데이터 가져오기에 실패하여 null이 반환되는데, 이 경우 Segment를 재계산하려고 합니다. 재계산 후 1초의 Timeout을 두고 UserSegmentCache를 다시 저장하려 시도하지만 실패하고, 이 과정에서 Thread가 모두 점유되어 API 서버의 전면 장애를 유발할 수 있습니다.
매칭 서비스 관련 Elasticache 전면 장애
매칭 풀에 대기 중인 사용자 간의 매치 스코어를 계산하기 위해 사용자 정보를 제공합니다. 이를 요청마다 전달하는 것은 비효율적이므로 Redis 캐시를 활용하게 됩니다. 그러나 Redis가 문제가 생기면 스코어 서버가 제때 매치 점수를 전달할 수 없어 매칭 대기 시간이 늘어나고 서비스 장애로 이어집니다. 저희는 Redis에 부하를 점진적으로 줘서 latency를 느려지게 만들고 결과적으로 완전히 다운시켜서 어떻게 대응하는지를 보는 것을 의도하였습니다.
매칭 알고리즘 설정 오류로 인한 매치 횟수 감소 장애
Azar의 매칭 알고리즘은 중앙화된 설정 서버에 의해 조절됩니다. 이 설정 서버는 사용자의 상황이나 선호도에 맞춰 어떤 매칭 알고리즘을 적용할지를 결정합니다. 예를 들어, “잘 맞는 상대를 만나기 위해 얼마나 오래 기다릴지” 같은 설정이 포함됩니다. 하지만 “잘 맞는 정도”에 대한 기준값을 너무 높게 설정하면, 사용자가 적합한 상대를 만나기 어렵고, 무한히 대기할 수 있습니다. 이렇게 되면 매치가 불가능해질 뿐만 아니라, 매치 요청이 계속 쌓여 트래픽 과부하로 다른 시스템에도 장애를 일으킬 수 있습니다.
문제는 이 설정이 코드에 기록되어 있지 않고, 런타임에 바꿀 수 있다는 점입니다. 그래서 이런 문제가 발생했을 때 배포나 인프라 문제를 먼저 의심하게 되는데, 이 상황은 단지 설정값이 잘못 입력된 것이기 때문에 코드나 인프라에는 문제가 없습니다. 따라서 매커니즘에 대한 깊은 이해가 없으면 원인 파악과 문제 해결이 어렵습니다.
Availability Zone 장애로 서비스 전면 장애
장애 시나리오 설계 시 실제로 발생 가능성이 있는 상황인지, 원인이 간단한지, 시스템상 SPOF(단일 장애점)의 취약한 부분인지에 중점을 두고 고민했습니다.
장애 훈련 환경 준비
현재 Hyperconnect에서 사용하고 있는 stage 환경은 UI/UX단에서의 기능 검증을 마치고 production과 유사한 하드웨어 환경에서 production과 유사한 트래픽에서도 문제없이 동작하는지를 최종적으로 검증하는 곳입니다. 이 환경이 production과 유사하게 준비가 되어있었기 때문에 이 환경을 모의 훈련을 위해 사용하기로 하였지만 정말 실제처럼 느껴지게 하기 위해서는 몇 가지 추가 작업이 필요했습니다.
이용하지 않고 있던 컴포넌트 띄우기 및 가상의 트래픽 준비
Azar 서비스를 구성하는 마이크로서비스는 매우 많아서, stage 환경에서도 모든 컴포넌트를 띄워서 테스트할 필요는 없었습니다. 의존성이 잘 격리되어 있었기 때문에 전체 컴포넌트를 관통하는 E2E 테스트는 진행하지 않았습니다. 하지만 이번 훈련에서는 실제 상황과 유사한 경험을 제공해야 했기에 모든 컴포넌트를 연결해야 했고, 장애 시나리오에 포함된 부분의 트래픽이 흐르는 환경을 마련해야 했습니다. 이를 위해 N개의 컴포넌트를 추가로 배포하고, 실제 트래픽과 유사한 트래픽을 분산 환경에서 높은 부하로 발생시키기 위해 K6 기반의 스크립트를 제작했습니다. 또한, 지표가 섞이는 것을 방지하기 위해 원래는 non-prod 용으로 사용하던 Kafka 클러스터를 stage 전용으로 분리했습니다.
모니터링 환경 준비
Production 환경은 실제 트래픽을 받기 때문에 국가마다 비즈니스 지표가 조금씩 달랐습니다. 문제 발생 시 빠르게 대응하기 위해 비즈니스 메트릭을 확인할 수 있는 Grafana 대시보드가 있었지만, Stage 환경에는 실제 고객이 발생시키는 국가별 지표가 없었습니다. 그래서 이러한 대시보드가 필요하지 않았습니다. 그러나 이번 모의 훈련을 위해 각 팀에서 중요하게 지켜보는 대시보드를 전수 조사하여, 실제 트래픽을 모사했을 때 메트릭을 보며 판단할 수 있도록 업데이트했습니다. 이 과정에서 SRE팀은 각 팀이 주요하게 보는 메트릭을 한 번 더 배우는 좋은 경험이었습니다.
장애 주입 테스트
장애 시나리오를 설계했다면, 설계 의도대로 장애가 주입되는지를 테스트하는 것이 필요합니다. 여기서 고려해야 할 사항은 다음과 같습니다:
- 장애를 어떻게 주입할 것인가?
- 장애를 주입했을 때, 관련된 지표들이 예상한 방향으로 움직이는가?
- 시나리오 설계 시 적어놓은 모범 대처 방안대로 행동했을 때, 장애가 잘 완화되는가?
가장 고민이 되었던 부분은 Elasticache 장애를 어떻게 모사할 것인가였는데, SG를 막거나 클러스터를 삭제하는 방향 등을 고려했으나, 이런 방식은 장애를 발견하기 쉬워 대처도 직관적이었습니다. Chaos Mesh 등을 활용하여 트래픽이 불안정한 상황을 모사하는 방안도 논의했으나, 기전을 추가로 준비해야 했기 때문에 시간이 부족했습니다. 결국, 예측하기 어려운 곳에서 primary 인스턴스에 DDoS 공격을 가하여 클러스터가 새 연결을 수락할 수 없는 상태를 만드는 것이 최선이라는 결론을 내렸고, 강한 부하를 가하는 스크립트를 작성하여 해결했습니다.
마지막으로, Availability Zone (AZ) 장애를 구현할 때는 오히려 AWS의 도움을 받아 쉽게 해결할 수 있었습니다. AWS Resilience Hub에서 AZ 장애를 위한 템플릿을 제공받아 이를 우리 입맛대로 미세 조정하여 손쉽게 장애를 구현할 수 있었습니다. AZ 장애는 SRE팀에서 사전에 어떻게 완화할지 예측하고 진행했지만, 실제로는 더 복잡했으며, 테스트를 통해 몇 가지 배운 점은 다음과 같습니다.
- Quorum이 깨지는 컴포넌트는 애매하게 살리려 하기보다 완전히 제거하고 새로 시작하는 것이 빠릅니다.
- AZ 장애가 발생하면 AZ 간 통신이 막히기 때문에, 여러 AZ에 걸쳐 있더라도 RDS, Elasticache 등은 failover를 통해 primary 인스턴스를 동일한 AZ로 몰아야 합니다.
- 대규모 노드 장애 상황에서는 kubelet이 pod 상태조차 보고하지 못하므로, K8s 지표만으로는 장애 상황을 빠르게 파악하기 어렵습니다. 따라서 비즈니스 지표의 움직임을 먼저 살펴야 합니다.
훈련 진행
Hyperconnect의 장애 대응 프로세스를 모두 소개하기에는 이 글의 범위를 벗어나기 때문에 훈련과 관련된 내용에 집중하겠습니다. 심각한 장애가 발생했을 때, 바로 해결할 수 없는 경우 내부 봇을 이용하여 장애를 선언하고, 관련 채널을 생성한 후 담당자를 초대합니다.
훈련 당시에도 실제 장애 상황처럼 채널을 생성하여 대응을 시작했고, 설계자들은 회의에 참관하여 진행 상황을 관찰하고 필요한 인사이트를 기록했습니다. 실제 상황과 유사하게 만들기 위해 미리 테스트에서 수집한 악화되는 지표에 따른 경고를 준비하고 알림을 발생시켰습니다. 만약 장애 원인 파악이나 완화에 어려움을 겪을 경우, 추가적인 경고를 통해 힌트를 제공했습니다.
예시 Alert 사례들
-
Pagerduty OnCall 예시
-
별도로 관리하는 매치 트렌드 alert 예시
총 4개의 시나리오 중 처음 2개의 시나리오는 시간 초과로 인해 대응에 실패했지만, 이후 2개의 시나리오는 장애 완화에 성공하여 마무리할 수 있었습니다. 웃픈점은 설계자들이 장애 시나리오를 설계할 때 생각했던 모범답안으로 장애를 완화한 사례가 단 한 번도 없었습니다. 그리고 패닉 상황에서 잘못 완화작업을 해서 문제가 악화되는 사례도 있었습니다. 훈련을 마치고 장애 대응 과정에서 발견한 우리의 부족한 점과 이를 어떻게 개선할 것인지를 내부적으로 정리하였고 이를 공유합니다. 이를 공유하는 것이 매우 중요하다고 생각하는 이유는, 이러한 부족한 행동 패턴이 우리 회사만의 문제가 아닐 것이며 이 내용을 숙지하는 것만으로도 장애 대응에 큰 도움이 될 것이기 때문입니다.
공통 개선사항
- 근본 원인 파악보다는 손상된 부분을 빠르게 파악하고 완화하는 데 초점을 맞춰야 합니다. 초기 상태로 복구하는 것은 천천히 진행해도 됩니다.
- 완화 과정에서 가장 중요한 기능이 무엇인지 빠르게 판단하고, 해당 부분을 우선 복구합니다.
- 잘못된 작업으로 인해 장애 상황이 더 심각해지면 롤백을 최우선으로 해야 합니다.
- 서로 다른 팀 간에 운영 중 어떤 지표를 보는지에 대한 대화가 더 필요합니다. 장애 상황에서 지표에 대한 의미를 물어보는 데 시간을 많이 낭비하고 있습니다.
SRE 대상
- 장애를 감독하는 팀으로서, 전체 장애 완화 상황을 전반적으로 파악하는 데 집중해야 하며, 모든 참여자가 세부적인 문제 해결이나 운영에 매몰되지 않도록 해야 합니다.
- 허들에서의 대화가 특정 팀에 의해 너무 지배되지 않도록 관리하고, 필요한 의사소통만 이루어지도록 해야 합니다.
- 장애 대응 기록을 잘 유지하고 유관 팀에 전파하는 과정을 철저히 합니다.
- OOM 문제 등 즉각적인 대응이 필요한 부분은 기존 배포 파이프라인을 거치지 않고 수동으로 조치를 취합니다.
- 초기 단계에서 관련 인원이 채널에 잘 초대되도록 자동화 시스템을 점검합니다.
Azar 팀 대상
- 팀에서 다루고 있는 서비스 지표에 이상이 없다면 이를 빠르게 알려 문제를 좁히는 데 도움을 줍니다.
- 문제 해결이 어려울 때 혼자 해결하려 하지 않고 빠르게 에스컬레이션합니다.
- 모니터링 지표에 지나치게 의존하지 않고, 핵심 기능이 실제로 동작하는지 지속적으로 테스트합니다.
- 중요한 비즈니스 메트릭을 전반적으로 이해하고 자주 확인합니다.
- 장애 상황에서 담당 컴포넌트의 상태가 정상인지 지속적으로 체크합니다.
회고 및 개선점
처음으로 장애 모의 훈련을 진행한 후 훈련에 대한 피드백을 받기 위해 설문 조사를 실시하였습니다. 또한 모의 훈련 자체와 팀별 장애 대응의 현주소를 다시 살펴보기 위해 각 팀 별로 회고를 진행했습니다. 아래는 주요 피드백입니다.
설문 조사 결과
그 이유는?
- 서비스 수준에서 인프라 문제를 우회하는 방법이 쉽지 않았습니다.
- 장애 발생 직전에 예시 트래픽이 유입되어 정상 트래픽 판별이 어려웠습니다.
- 문제 해결에 집중하느라 도움 요청이 늦어졌습니다.
- 훈련 중 다른 컴포넌트의 상황 파악이 매우 어려웠습니다.
그 이유는?
- 특정 팀에서 장애가 났을 때 서비스 전반에 미치는 영향을 알 수 있었습니다.
- 실제 발생할 수 있는 장애여서 좋았습니다.
- 시스템의 부족한 점을 파악하고 개선 방향을 설정할 수 있어 유익했습니다.
- 다른 팀의 대응 과정을 지켜보며 무엇을 더 잘할 수 있을지를 고민하게 되었습니다.
그 이유는?
- 기여할 부분이 적어 아쉬웠습니다.
- 집중하는 시간이 길어 피곤했지만, 문제를 해결하니 뿌듯했습니다.
- 문제를 추적하는 과정을 배우면서 즐겁게 느꼈습니다.
- 다른 팀원들과 의사소통하는 것이 즐거웠습니다.
모의 훈련에 대한 피드백
첫 장애 모의 훈련은 어렵고, 유익하며, 즐거웠다는 평가를 받았습니다. 훈련이 성공적으로 평가받았지만, 더 나은 모의 훈련을 위해 다양한 피드백을 수집했습니다.
- 모의 환경의 로그, 모니터링 지표, 트래픽을 production 환경과 더 유사하게 만들 필요가 있습니다.
- 불필요한 노이즈를 유발하는 로그들이 많았습니다.
- 실제 production 환경과 사용자 지표가 달랐습니다.
- Stage 환경의 대시보드가 production 환경을 완전히 따라가지 못한 점이 아쉬웠습니다.
- 마케팅에 의한 사용자 폭증, 어플리케이션 코드의 결함 같은 시나리오도 다루고 싶습니다.
- 가상의 트래픽이 항상 흐르지 않아 장애 직전에 유입되자 혼란스러웠습니다.
현재 모니터링, 운영 시스템의 한계
훈련을 통해 SRE팀이 관리하는 모니터링 시스템과 운영의 한계도 확인할 수 있었습니다.
- AWS Elasticache, RDS 상태나 메트릭을 Grafana에서 바로 확인할 수 없는 점이 아쉬웠습니다 (마이크로서비스와의 연결성 부족).
- Failover 등 작업을 AWS 콘솔에서 직접 수행해야 하는 점이 대응을 느리게 했습니다.
- 피처 단위에서 더 신속하게 상태를 확인할 수 있는 대시보드가 필요합니다.
장애 대응을 더 잘하려면?
- 공통: 장애의 근본 원인 파악보다는 빨리 의존성을 끊어내고 완화에 중점을 둬야 합니다.
- SRE팀: 장애를 감독하는 팀으로서 디렉션 능력을 강화해야 합니다.
- SRE팀: 장애 상황에서 행동 방식이나 가이드라인에 대한 교육을 강화해야 합니다.
- Azar 팀: 컴포넌트에 문제가 없다면 자신 있게 없다고 보고하여 문제의 범위를 줄여야 합니다.
- Azar 팀: 지속적으로 서비스 상태, 메트릭, 로그 지표를 확인하고 보고해야 합니다.
- Azar 팀: 에스컬레이션 판단을 빠르게 하고 실행해야 합니다.
이번 장애 모의 훈련은 여러 부족한 점과 개선점을 파악할 수 있는 기회를 제공했고, Hyperconnect의 엔지니어들이 장애 상황에 어떻게 대응해야 하는지 체감하면서 자신감을 높일 수 있었습니다. 이번 훈련을 통해 SRE 팀은 훈련의 필요성에 대한 확신을 얻었고, 더 나은 시나리오와 모의 훈련 환경을 준비하여 지속적으로 훈련을 진행하고, 엔지니어들의 대응 능력을 높이기 위해 최선을 다할 예정입니다. 또한 모니터링과 운영 시스템의 한계를 극복하기 위해 다양하게 노력할 계획입니다.
더 나은 서비스 품질, 더 빠른 장애 대응을 위해 달리고 있는 SRE 팀과 함께 일하고 싶지 않으신가요? 많은 지원 부탁드립니다!
Read more
-
글로벌 서비스에서 지역 통신사 네트워크 이슈 트러블슈팅하기
글로벌 서비스를 이용할 때 지역 통신사 네트워크 이슈를 어떻게 해결할까요? Azar에서의 트러블슈팅 경험을 소개합니다.