사례4건
4건 중 1~4번째
- 증상
us-central1 리전에서 Cloud Storage 업로드와 쓰기 요청의 지연과 오류율이 올라갔다. 고객은 주로 WriteObject 작업에서 HTTP 503 UNAVAILABLE 오류와 클라이언트 쪽 타임아웃을 봤다.
- 촉발
Cloud Storage 부하 분산 계층에 트래픽 정렬 최적화 설정 업데이트가 배포됐다. 이 설정은 용량을 보고 경로를 정하는 표준 로직을 의도치 않게 건너뛰었다.
- 원인
- 구성 요소
- 기여 요인
- 감지
Google 엔지니어링 팀이 시스템 텔레메트리를 지켜보다가 10월 8일 04:50에 문제를 처음 알아챘다. 장애가 시작되고 50분 뒤였다.
- 조치
- 부하가 가장 큰 스토리지 백엔드 노드를 골라 트래픽을 뺐다.
- 트래픽 정렬 최적화를 끄는 설정 변경을 배포해 스토리지 백엔드의 자원 부담을 크게 줄였다.
- 같은 시기에 난 메타데이터 문제를 막으려고 메타데이터 데이터베이스 서비스의 최근 업데이트를 롤백했다.
- 부하 불균형이 다시 일어나자 트래픽을 더 돌리고 영향받은 스토리지 구성 요소에서 트래픽을 뺐다.
- 문제의 부하 분산 설정 변경을 완전히 되돌려 용량을 보고 경로를 정하던 이전 동작을 되살렸고, 트래픽이 리전 전체에 고르게 퍼졌다.
- 트래픽과 자원 사용률이 평소 수준으로 돌아온 뒤 트래픽을 뺐던 노드를 다시 서비스에 넣었다.
- 후속 조치
- 부하 분산 로직 변경은 사용률이 높은 큰 리전에 내보내기 전에 더 작은 다른 리전에서 먼저 엄격하게 검증하도록 배포 절차를 바꾼다.
- 스토리지 부하 분산 구조가 용량 제약을 반드시 지키게 한다. 트래픽 분배 로직이 Google 이 pre-spilling 이라고 부르는 안전장치를 건너뛰어 처리 자원이 모자란 클러스터로 트래픽을 보내는 일이 없게 한다.
- 사용률이 높은 스토리지 셀 안의 내부 데이터 이동을 빠르게 해, 일시적인 부하 급증을 더 잘 견디게 한다.
- 증상
14:43 UTC 에 네트워크 스위치 하나가 ping 에 응답하지 않는다는 알림이 울리기 시작했다. 장애 동안 API 쿼리 성공률이 한때 75%까지 떨어졌고, 대시보드는 평소보다 최대 80배 느려졌다.
- 촉발
14:43 UTC 에 제어 플레인 데이터 센터의 네트워크 스위치 하나가 일부만 동작하는 상태에 빠졌다. LACP 와 BGP 는 계속 돌았지만 받은 패킷 일부를 전달하지 못했고, 스위치는 6분 뒤 스스로 회복했다.
- 원인
- 구성 요소
- 기여 요인
- 감지
14:43 UTC 에 스위치가 ping 에 응답하지 않는다는 알림이 울리기 시작했다. 그 뒤 엔지니어들이 주 인증 데이터베이스가 과부하에 걸린 것을 확인했다.
- 조치
- SSL 인증서를 엣지로 보내는 속도와 메일 발송 같은 기능을 줄여 주 인증 데이터베이스가 늘어난 부하를 감당할 여유를 만들었다.
- 읽기 복제본으로 처리할 수 있는 API 트래픽을 손으로 보조 데이터 센터로 돌렸다. API 가용성이 크게 나아졌다.
- 대시보드 사용자의 불편이 커지자 인증 호출을 모두 주 데이터 센터로 되돌렸고, 성능이 떨어진 상태에서도 최대한 버티도록 주 데이터베이스를 계속 손봤다.
- 21:20 UTC 에 첫 데이터베이스 복제본이 다시 만들어지자마자 자동으로 서비스에 투입됐고, 성능이 정상으로 돌아왔다.
- 줄였던 서비스를 모두 다시 올려 밀린 비동기 처리가 따라잡게 했고, 한동안 지켜본 뒤 장애 종료를 선언했다.
- 후속 조치
- 새 primary 를 승격하면 데이터베이스 복제본을 모두 다시 만들어야 하는 클러스터 관리 시스템의 제약을 고친다. Cloudflare 는 글을 쓸 무렵 이 결함을 이미 고쳤다고 밝혔다.
- 트래픽을 다른 데이터 센터로 돌려야 할 때 유연하게 대응하지 못하는 사용자 세션 시스템을 다시 설계한다.
- 자동 복구 조치의 설정 값을 다시 검토한다. 적어도 데이터베이스 하나에서는 복제본을 primary 로 승격하는 절차를 그렇게 빨리 시작하지 않도록 장애 직후 설정을 바꿨다.
- 이 장애에 얽힌 시스템마다 자기가 의존하는 시스템의 고장을 더 잘 견디도록 계속 조정한다.
- 교훈
모든 시스템에 이중화가 있었지만, 고장 난 시스템들은 완전히 멈추지 않고 성능이 떨어진 채로 동작했다. 그래서 뒤이어 일어난 일들을 미리 모델링하고 예상하기가 훨씬 어려웠다. 1분 만에 복제본을 승격하는 자동 조치는 Cloudflare 가 자랑하던 기능이었지만, 적어도 데이터베이스 하나에서는 그 조치가 원래 문제보다 더 큰 피해를 낼 수 있었다. 대부분의 범용 클러스터 관리 시스템은 비잔틴 장애를 견디는 프로토콜을 쓰지 않고 RAFT 처럼 단순한 프로토콜을 쓴다. 드문 장애 유형에 약하다고 알려진 단순한 프로토콜이 구현과 디버깅이 어려운 복잡한 프로토콜보다 안전한 경우가 많다고 Cloudflare 는 보았다.
- 증상
6월 3일 PagerDuty 알림 파이프라인의 성능이 떨어져 일부 알림이 늦게 갔다. 통합 API 로 보낸 이벤트의 약 3% 를 받지 못했고, 1% 에 못 미치는 일부 알림이 늦게 전달됐다.
- 촉발
6월 3일 Cassandra 클러스터의 노드 하나에서 repair 작업이 평소대로 시작됐고, 그때 걸린 높은 부하와 겹쳤다. 6월 4일에는 팀이 전날 미룬 repair 작업을 손으로 다시 시작했다.
- 원인
- 구성 요소
- 기여 요인
- 조치
- 6월 3일 Cassandra 클러스터의 부하를 줄였다.
- 6월 3일 부하를 줄이면서 repair 작업을 멈췄다.
- 클러스터를 안정시키려고 일부 노드 사이의 통신을 끊었고, 그 뒤 정상으로 돌아왔다.
- 6월 4일 알림 파이프라인에서 처리 중이던 데이터를 모두 지웠고, Cassandra 가 바로 회복했다.
- 새로 비운 상태와 데이터를 맞추도록 일부 하위 시스템을 수동으로 손봤다.
- 후속 조치
- 기존 Cassandra 노드를 더 크고 빠른 서버로 수직 확장한다. 6월 4일 이후 이 작업은 이미 끝냈다.
- Cassandra 클러스터를 여러 개로 나누고 작업량을 그 클러스터들에 나눠 싣는다. 부하와 사용 방식에 따라 클러스터를 나누는 작업이 진행 중이다.
- 시스템 부하 기준을 정해 그 기준에 닿으면 기존 Cassandra 클러스터를 미리 수평 확장한다.
- 기존 클러스터와 새 클러스터를 더 최근 버전의 Cassandra 로 업그레이드한다.
- 높은 부하에서도 Cassandra 를 통제할 수 있도록 로드 셰딩 기법을 더 넣는다.
- Cassandra 전문 인력을 사내에 더 둔다.
- 교훈
PagerDuty 는 Cassandra 클러스터의 규모가 모자랐고, 부하와 사용 방식이 서로 다른 너무 많은 서비스가 한 클러스터를 나눠 쓰고 있었다고 밝혔다. 비슷한 문제를 보고 개선을 계획했지만 효율을 기준으로 버전 업그레이드를 먼저 하려 했고, 확장을 먼저 했어야 했다고 적었다.
- 증상
2011년 4월 21일 오전 12시 47분 PDT, US East 리전의 한 가용 영역에서 EBS 볼륨 일부가 읽기와 쓰기를 처리하지 못하게 됐고, 그 볼륨을 쓰던 EC2 인스턴스도 읽거나 쓰려다 함께 멈췄다. 리전 전체에서 EBS API 의 오류율과 지연도 높아졌다.
- 촉발
US East 리전의 한 가용 영역에서 주 EBS 네트워크의 용량을 올리는 작업 중, 이중화된 라우터 하나에서 트래픽을 빼는 단계를 잘못 실행했다. 트래픽은 주 네트워크의 다른 라우터가 아니라 용량이 작은 보조 EBS 네트워크로 갔다.
- 원인
- 구성 요소
- 기여 요인
- 조치
- 잘못된 트래픽 전환을 되돌려 네트워크 연결을 살렸다. 연결이 돌아오자 노드들이 한꺼번에 재미러링할 공간을 찾기 시작했다.
- 4월 21일 오전 2시 40분 PDT, 영향받은 가용 영역의 새 Create Volume 요청을 모두 막는 변경을 배포했다. 2시 50분에 다른 EBS API 의 지연과 오류율이 회복했다.
- 오전 8시 20분부터 망가진 EBS 클러스터와 EBS 컨트롤 플레인 사이의 통신을 모두 끊었다. 그 가용 영역의 EBS API 는 전부 막혔지만 리전의 나머지 EBS API 는 정상으로 돌아왔다.
- 오전 11시 30분, 클러스터 노드 사이에 꼭 필요한 통신은 그대로 두고, 망가진 클러스터의 EBS 서버가 빈 공간도 없는 다른 서버에 헛되이 연락하지 못하게 막았다. 이 변경 뒤 클러스터는 더 나빠지지 않았다.
- 오전 11시 30분, EBS 컨트롤 플레인을 바꿔 다른 가용 영역에서 EBS 기반 EC2 인스턴스를 새로 띄울 때의 오류와 지연을 없앴다. 정오에 거의 정상으로 돌아왔다.
- 실패한 노드는 다시 쓰지 않고, US East 리전 곳곳의 여유 서버를 물리적으로 옮겨 망가진 EBS 클러스터에 설치했다.
- 새로 들인 서버와는 협상이 일어나되 기존 서버에 처리하지 못할 요청이 다시 몰리지 않도록 협상 스로틀을 조심스럽게 바꿨다.
- 리전의 다른 가용 영역에 영향이 가지 않도록 영향받은 가용 영역에만 쓰는 EBS 컨트롤 플레인을 따로 세우고 더 세밀한 스로틀을 만든 뒤, 밀린 상태 변경을 처리했다.
- 장애 초반에 데이터 손실에 대비해 남은 2.2% 의 볼륨을 S3 백업에 스냅샷으로 떠 두었다. 그 스냅샷에서 볼륨을 복구하는 코드를 만들고 시험한 뒤 밤새 묶음으로 처리했다.
- 기계 고장을 겪어 스냅샷도 뜨지 못한 나머지 볼륨을 포렌식으로 조사했고, 4월 24일 오후 3시부터 복구했다.
- 자동 장애 전환을 하지 못하고 고립된 RDS multi-AZ 인스턴스의 primary 복제본은 데이터 손실 위험 때문에 사람이 직접 개입해 처리했다.
- 후속 조치
- 변경 절차를 감사하고 자동화를 늘려 이번 같은 실수가 다시 나지 않게 한다.
- 큰 장애 복구에 필요한 안전 여유 용량을 늘 갖도록 용량 계획과 알람을 바꾼다. 용량 여유분은 이미 크게 늘렸고, 필요한 새 용량은 몇 주 안에 갖춘다.
- EBS 서버 노드의 재시도 로직을 바꿔, 큰 중단이 나면 더 적극적으로 백오프하고 새 노드를 헛되이 찾기보다 이전 복제본과 연결을 되살리는 데 집중하게 한다.
- EBS 노드를 죽인 경쟁 조건의 원인을 찾았고, 고친 코드를 시험해 몇 주 안에 클러스터에 배포한다.
- RDS multi-AZ 인스턴스가 자동 장애 전환을 하지 못하게 만든 버그를 고치고 있다.
- 한 가용 영역의 클러스터가 요청을 너무 오래 처리할 때 스레드가 고갈되지 않도록 타임아웃 로직을 바로 고친다.
- EBS 컨트롤 플레인이 가용 영역을 더 잘 구분하고, 용량을 넘었을 때 부하를 골라서 덜어 내게 한다.
- EBS 컨트롤 플레인의 기능을 더 많이 떼어 내, 지원하는 EBS 클러스터와 같은 가용 영역에서 도는 클러스터별 서비스로 옮긴다.
- 로드맵을 조정해 지금은 가용 영역 하나만 쓸 수 있는 VPC 고객이 되도록 빨리 여러 가용 영역을 쓰게 한다.
- 가용 영역 하나를 통째로 잃어도 애플리케이션 가용성이 유지되는 multi-AZ 애플리케이션을 만들 수 있도록 더 나은 도구를 고객에게 준다.
- 클라우드 설계 모범 사례를 다루는 무료 웨비나를 5월 2일 월요일부터 열고, 모범 사례 백서와 함께 AWS 웹사이트의 새 Architecture Center 에 둔다.
- 팀이 클러스터를 복구할 때 쓴 세밀한 제어와 스로틀을 EBS 노드 안에 바로 넣고, 여러 종류의 볼륨 복구에 쓴 방식을 자동화한다.
- 클러스터가 나빠진 동안에도 볼륨 기능을 지키는 방법을 찾고, stuck 볼륨의 스냅샷을 뜨는 기능을 넣는 것을 검토한다.
- 장애 도중부터 늘린 업데이트 빈도를 앞으로도 같은 수준으로 이어 간다. 또 이런 장애 때 개발자 지원 팀 인력을 더 넓게 배치하고, 짐작은 피하면서 이르고 쓸모 있는 정보를 내도록 조직하는 방법을 준비하고 있다.
- 고객이 API 로 자기 인스턴스가 손상됐는지 볼 수 있는 도구를 만들고 있다.
- 교훈
AWS 는 이 사고를 촉발한 것은 네트워크 설정 변경이었지만, 앞으로의 일은 비슷한 실패가 나도 EBS 가 견디게 만드는 데 둔다고 했다. 여유 용량이 더 있었다면 망가진 클러스터가 재미러링 요청을 빨리 흡수해 폭주를 피했을 것이라고 봤다. 가용 영역들을 완전히 독립된 것처럼 만들려면 더 투자해야 한다는 것을 이 사고로 배웠다고 했다. 장애 중에 고객이 영향받은 자원을 다른 정상 가용 영역에서 바꾸기 어려웠던 일이 다시 일어나지 않게 하는 것을 최우선으로 꼽았다. 여러 가용 영역에 걸친 배포를 쉽게 설계하고 운영하도록 고객을 돕는 일도 더 잘해야 한다고 했다. 여러 종류의 볼륨 복구에 쓴 방식을 자동화해 두었다면 복구 시간을 크게 줄였을 것이라고 했다. 장애 중 고객 소통은 더 자주, 더 많은 정보를 담아야 한다고 봤다.
이 4건에서 가장 많이 나오는 구성 요소: 데이터베이스, 클라우드 블록 스토리지. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.