사례5건
5건 중 1~5번째
- 증상
2023년 8월 9일 09:55 UTC 부터 DigitalOcean 의 AMS3, LON1, SFO2 데이터 센터가 인터넷 연결을 잃었다. 끊김은 세 차례 일어났다. 한 번에 10~15분씩 이어졌고, 끊김 사이의 간격은 한 시간쯤이었다.
- 촉발
에지 라우터가 RPKI 관련 라우팅 갱신을 받으면서, 일부 에지 라우터에서 돌던 운영체제 소프트웨어 버전의 버그가 라우팅 프로세스를 죽였다.
- 원인
- 구성 요소
- 기여 요인
- 조치
- 장비 업체의 조사 뒤 문제의 운영체제 버전을 쓰는 에지 라우터에 소프트웨어 업데이트를 긴급히 내보냈다. 회선에서 트래픽을 빼고 라우터가 인터넷에 다시 붙는 동안 연결 문제가 더 났다.
- AMS3 와 FRA1 사이 경로의 혼잡을 줄이려고 트래픽을 다시 나눴다.
- 장애 전환이 일어나도 같은 문제를 겪지 않도록 이중화된 네트워크 장비에도 수정을 내보냈다. 14:58 UTC 공지에서 AMS3, LON1, SFO2 의 모든 네트워크 장비를 패치했다고 알렸다.
- 후속 조치
- 전 세계 모든 에지 라우터를 버그를 피하는 버전으로 업그레이드했다.
- 네트워크의 안정성과 보안을 높이는 네트워크 업그레이드를 진행한다. 아시아는 이미 업그레이드를 마쳤고, 유럽과 북미는 올해 말과 2024년 초에 업그레이드한다.
- 증상
2023년 7월 24일 밤 저장소와 쿼리 엔진인 Retriever 의 클러스터를 바꾼 지 몇 시간 뒤 수집 서비스 Shepherd 의 내부 SLO 에러 버짓이 천천히 소진되기 시작했다. 엔지니어들은 소진이 느리고 들쭉날쭉하며 뚜렷한 설명이 없어서 아침에 조사해도 되는 작은 문제라고 판단했다.
- 촉발
7월 24일 밤 미묘한 버그를 피하려고 Retriever 클러스터 두 개 사이를 전환했다. 전환 뒤 Retriever 가 마지막 쓰기 시각 기록을 데이터베이스에 쓰지 않았고, 그 뒤 쓰기만 되돌리려고 기능 플래그를 바꾸자 남은 쓰기마저 완전히 멈췄다.
- 원인
- 구성 요소
- 기여 요인
- 감지
Shepherd 의 내부 SLO 에러 버짓이 천천히 소진되는 것을 엔지니어들이 봤지만 작은 문제로 판단해 아침으로 미뤘다. 아침에 Retriever 의 데이터베이스 호출이 끊긴 차트를 찾아 성능 문제의 원인을 알았다.
- 조치
- 클러스터의 쓰기에 문제가 있다고 보고 자주 쓰던 기능 플래그를 바꿔 쓰기만 다른 클러스터로 되돌렸지만 고쳐지지 않았다.
- 데이터베이스를 보호하려고 서킷 브레이커를 걸어 모든 Shepherd 트래픽을 5xx 오류로 거부했다.
- 데이터베이스 호스트가 완전히 잠겨 살릴 수 없자 복제본으로 페일오버했고, 데이터베이스와 그에 기대는 서비스들이 돌아왔다.
- 데이터베이스가 살아난 뒤 캐시에 데이터를 채우려고 Retriever 호스트를 모두 재시작했다.
- 지난 하루 동안 트래픽이 있던 모든 스키마의 마지막 쓰기 시각을 지금으로 손으로 바꿔 스키마 저장소가 캐시를 모두 다시 읽게 했다.
- 서킷 브레이커를 풀어 수집을 완전히 되살렸고, 데이터베이스 오류로 내부 점검에 실패한 호스트를 다시 재시작해 쿼리 용량을 되찾았다.
- 후속 조치
- 클러스터 이전을 마쳤고, 캐시 뒤의 쓰기를 끌 수 있는 코드를 모두 지웠다.
- 캐시를 더 튼튼하게 하는 방법을 찾는다.
- 새 스키마로 갱신이 몰릴 때 데이터베이스에 거는 경합을 줄이는 방법을 찾는다.
- 시스템 안 일부 작업의 성능 비용이 들쭉날쭉하지 않게 한다.
- 이런 드문 경우를 더 잘 찾고 다루기 위한 계측과 실험 방법을 검토한다.
- 교훈
Honeycomb 은 기능 플래그, 잦은 배포, 장애 중 배포 중단, 지난 아차 사고에서 배운 것처럼 시스템을 안전하게 만드는 가장 믿는 관행들이 함께 이번 장애의 원인이 됐다고 봤다. 저마다 합리적인 결정들이 간접 의존 관계를 따라 예상하지 못하게 얽혔고, 환경 한쪽의 문제가 다른 쪽 서비스를 망가뜨렸다. 최근 여러 장애와 아차 사고에서 미묘한 버그를 피하려던 조치가 더 큰 예상 밖 장애로 이어진 일이 자주 있었다. 이런 드문 데이터베이스 잠김에는 페일오버가 가장 빠른 복구 방법이라는 것도 배웠다.
- 증상
2021년 10월 28일 13:37 PST 에 Vault 성능이 떨어지고 Consul 서버 한 대의 CPU 부하가 높아졌다. 이때는 플레이어에게 영향이 없었다.
- 촉발
10월 27일 14:00 PST 에 트래픽 라우팅을 맡는 백엔드 서비스에 Consul 의 새 streaming 기능을 켰다. 같은 롤아웃에서 연말 트래픽에 대비해 트래픽 라우팅 노드 수를 50% 늘렸고, 하루 뒤 Consul 성능이 떨어지기 시작했다.
- 원인
- 구성 요소
- 기여 요인
- 감지
10월 28일 13:37 PST 에 Vault 성능 저하와 Consul 서버 한 대의 높은 CPU 부하를 보고 Roblox 엔지니어들이 조사를 시작했다. Consul 클러스터 지표에서 KV 쓰기 지연이 올라간 것을 확인했다.
- 조치
- 하드웨어 성능 저하를 의심해 Consul 클러스터 노드 한 대를 교체했다.
- 트래픽 증가를 의심해 Consul 클러스터의 모든 노드를 128코어와 더 빠른 NVME SSD 를 단 서버로 바꿨다.
- Consul 클러스터 전체를 내리고 장애 시작 무렵인 몇 시간 전 스냅샷으로 상태를 되돌렸으며, iptables 로 접근을 막았다가 천천히 풀었다.
- 외부 트래픽을 막고, Consul 을 쓰는 서비스 목록을 모아 꼭 필요하지 않은 사용을 끄는 설정을 배포했으며, 서비스 인스턴스를 한 자릿수로 줄이고 헬스 체크 간격을 60초에서 10분으로 늘렸다.
- 경합이 128코어 서버로 옮긴 탓일 수 있다고 보고 Consul 클러스터를 다시 64코어 서버로 옮겼다.
- 트래픽 라우팅 노드를 포함한 모든 Consul 시스템에서 streaming 기능을 껐고, 설정이 15:51 PST 에 다 퍼지자 KV 쓰기의 p50 지연이 300ms 로 내려갔다.
- 느린 리더 문제의 원인을 모르는 채로, 문제가 있는 서버가 리더로 뽑힌 채 남지 않게 막았다.
- 캐시 시스템을 다시 배포했고, 틀어진 스케줄링 데이터와 끝나지 않는 배포 같은 문제를 밤새 찾아 고쳤다.
- 장애와 문제 분석 중에 내렸던 서비스들을 알맞은 용량으로 다시 띄우고 제대로 도는지 확인했다.
- DNS 조정으로 무작위로 고른 일정 비율의 플레이어만 들이고 나머지는 정적 점검 페이지로 보냈으며, 데이터베이스 부하와 캐시 성능을 보며 약 10% 씩 늘렸다.
- 후속 조치
- HashiCorp 는 시험 환경에서 이 경합 문제를 재현하는 새 벤치마크를 만들고 대규모 시험을 늘린다.
- HashiCorp 는 극한 부하에서도 경합이 생기지 않도록 streaming 시스템의 설계를 고친다.
- 기존 BoltDB 도구로 데이터베이스를 압축하는 절차를 만들어 배포했고, 이것으로 성능 문제가 풀렸다.
- 텔레메트리 시스템과 Consul 사이의 순환 의존을 없애, 텔레메트리 시스템이 감시 대상 시스템에 기대지 않게 했다.
- Consul 과 BoltDB 성능, Roblox 서비스와 Consul 사이의 트래픽 패턴을 더 잘 보이게 텔레메트리를 넓혔고, 이번 장애 상태에 가까워지는 신호에 정밀한 알림을 건다.
- 백엔드 서비스를 둘 지리적으로 떨어진 데이터센터를 하나 더 세웠고, 데이터센터 안에서 여러 가용 영역으로 옮긴다.
- 서비스들의 Consul KV 와 헬스 체크 사용을 검토해 일부 핵심 서비스를 전용 클러스터로 나눠 중앙 Consul 클러스터의 부하를 줄였다.
- Consul KV 를 데이터 저장소로 쓰던 핵심 서비스의 데이터를 더 알맞은 저장 시스템으로 옮긴다.
- 쓰지 않는 KV 데이터를 대량으로 찾아 지웠고, Consul 성능이 좋아졌다.
- HashiCorp 와 함께 BoltDB 대신 freelist 가 끝없이 커지는 문제가 없는 후속 라이브러리 bbolt 를 쓰는 새 Consul 버전을 배포한다. 연말 최대 트래픽을 피해 새해로 미뤘고 1분기에 끝낸다.
- 캐시 배포 방식을 다시 설계해 아무것도 없는 상태에서도 캐시 시스템을 빨리 올릴 수 있게 한다.
- 오래 멈춘 뒤 큰 작업을 다시 올리기 쉽게 하는 Nomad 개선 몇 가지를 HashiCorp 와 찾았고, 다음 Nomad 업그레이드에서 배포한다.
- 서버 설정을 더 빨리 바꾸는 방법을 만들어 배포했다.
- 새 streaming 구현을 Roblox 규모와 부하로 시험한 뒤에 조심스럽게 다시 들인다.
- 교훈
Roblox 는 원인 두 가지가 Consul 구현 깊숙이 묻혀 있어 진단이 어려웠던 것이 장애를 길게 만든 주된 이유라고 봤다. 원인을 보여 줄 모니터링 시스템이 장애가 난 Consul 에 기대고 있어 분석이 크게 막혔다. 모든 백엔드 서비스를 Consul 클러스터 하나에 올린 구성이 이런 장애에 취약했다. HashiCorp 는 Roblox 와 비슷한 규모에서 streaming 을 벤치마크했지만, 이 경합은 스트림 수가 많고 교체가 잦은 조건이 겹칠 때만 나타나 전에는 보지 못했다. 더 빠른 하드웨어는 도움이 되지 않았고 오히려 안정성을 해쳤을 수 있다. 오래 완전히 멈춘 상태에서 서비스를 올리는 데도 캐시 배포와 데우기 때문에 시간이 많이 걸렸다.
- 증상
2012년 11월 30일 금요일, GitHub 는 18분 동안 완전히 접속이 안 됐고, 하루 종일 응답이 이따금 느려지고 오류가 간헐적으로 났다. 파일 서버 한 쌍이 하루 대부분 내려가 있어 일부 저장소가 영향을 받았다.
- 촉발
새 애그리게이션 스위치를 들이려고 액세스 스위치를 떼어 설정을 바꾸고 다시 연결하는 작업을 했다. 11월 30일 아침 A 스위치를 옮기던 중 마지막 스위치에서 브리지 루프가 생겼다.
- 원인
- 구성 요소
- 기여 요인
- 감지
마지막 A 스위치를 연결할 때 같은 캐비닛의 B 스위치와 연결이 끊겼다. 문제를 고친 뒤에도 성능이 기대만큼 나오지 않아 들여다보다가 액세스 스위치와 애그리게이션 스위치 사이 링크가 모두 포화된 것을 봤다.
- 조치
- 마지막 A 스위치에서 난 첫 문제를 빨리 해결하고, 영향받은 B 스위치를 다시 서비스에 넣어 이전을 마쳤다.
- 액세스 스위치에서 잘못된 설정을 지웠다. 그 뒤로는 링크를 시험해도 페일오버가 기대대로 작동했고, 애그리게이션 계층이나 액세스 계층의 스위치 하나를 빼도 서버에 영향이 없었다.
- 몇 시간을 더 찾아도 설정 문제가 나오지 않자 네트워크 공급사에 다시 에스컬레이션했고, 공급사는 이 문제를 가장 높은 심각도 등급으로 올려 바로 함께 조사했다.
- 태평양 시간 토요일 오전 6시에 네트워크 점검 시간을 잡고 애그리게이션 스위치의 핵심 프로세스 일부를 재시작해 MAC 주소를 다시 학습하게 했다. 이 우회책이 통해서 트래픽과 성능이 정상으로 돌아왔다.
- 후속 조치
- 공급사가 MAC 학습 문제의 근본 원인을 찾았고, 1주일쯤 안에 최종 수정이 나오면 스위치에 소프트웨어 업데이트를 배포한다.
- 그때까지 애그리게이션 계층과 액세스 계층 사이 용량을 면밀히 지켜보고, 문제가 다시 나면 쓸 우회 절차를 둔다.
- 라우터부터 액세스 계층 스위치까지 네트워크 스택을 똑같이 한 벌 더 갖춰 스테이징 환경으로 쓰고, 이런 변경을 미리 더 충분히 시험한다.
- 비슷한 문제가 생기면 더 빨리 알림을 받도록 네트워크에 자동 모니터링을 더한다.
- 앞으로 몇 달 동안 정기적인 장애 대응 훈련을 늘리고, 한 가지 가설에 매달리지 않도록 하는 시나리오를 만든다.
- 앞으로는 네트워크에 문제 조짐이 처음 보일 때 바로 공급사 지원팀에 연락한다.
- 교훈
GitHub 는 고객에게 영향이 없도록 설계한 점검 작업이 결국 고객에게 영향을 줬다고 인정했다. 장애 대응 중에 브리지 루프라는 생각에 오래 매달려 다른 원인을 보지 못했고, 그래서 한 가지 가설에 갇히는 것을 더 경계해야 한다고 했다. GitHub 는 공급사 지원팀과 일한 경험이 좋았다며, 앞으로는 문제 조짐이 처음 보일 때 바로 지원팀에 연락하겠다고 했다.
- 증상
2012년 9월 10일 월요일, 스키마 마이그레이션이 데이터베이스에 높은 부하를 걸자 Percona Replication Manager 의 헬스 체크가 마스터에서 실패했다. Percona Replication Manager 는 'active' 역할을 다른 노드로 옮겼고, 새 노드가 느려지면서 GitHub.com 이 멈췄다.
- 촉발
무중단 MySQL 스키마 마이그레이션이 이전의 같은 종류 마이그레이션보다 높은 부하를 데이터베이스에 걸었고, 그 부하로 Percona Replication Manager 의 헬스 체크가 마스터에서 실패했다.
- 원인
- 구성 요소
- 기여 요인
- 감지
9월 11일 아침 한 개발자가 'standby' 역할을 맡은 노드에서 잘못된 쿼리 결과가 나온다고 운영팀에 알렸다. 그 뒤 운영팀은 혼자 마스터로 뽑힌 'c' 노드가 앞서 데이터가 뒤처졌다고 판단한 노드라는 것을 알아챘다.
- 조치
- 9월 10일 Pacemaker 의 maintenance-mode 를 켜서 모든 헬스 체크와 자동 페일오버 동작을 멈췄다.
- 9월 11일 8:26 AM 에 데이터가 뒤처진 'c' 노드의 전원을 꺼서 갈라진 클러스터 상태를 끝내고 데이터가 더 어긋나지 않게 했다.
- 클러스터 상태를 깨끗하게 되살리려고 'a' 와 'b' 두 노드에서 Pacemaker 와 Heartbeat 프로세스를 모두 멈춘 뒤 'a' 노드에서 다시 띄웠다.
- 'a' 노드에서 MySQL 을 띄워 'active' 역할을 맡게 했다.
- 다른 사용자의 대시보드에 새어 나간 이벤트를 모두 지우고, 그 시간에 경로가 잘못 잡힌 저장소를 모두 점검했다.
- 협업자가 아닌 사람에게 열려 있던 비공개 저장소 16개의 소유자에게 모두 직접 연락했다.
- 후속 조치
- Pacemaker 설정을 바꿔 'active' 데이터베이스 역할의 페일오버는 운영팀 사람이 시작할 때만 일어나게 한다.
- 비상시나 정기 유지보수 때 페일오버를 해도 성능이 떨어지지 않도록, 복제본 데이터베이스의 InnoDB 버퍼 풀을 미리 데우는 여러 방법을 조사하고 시험한다.
- 화요일에 segfault 를 일으킨 코드 경로를 중심으로 Pacemaker 와 Heartbeat 스택 전체를 점검한다.
- 만일에 대비해 segfault 가 난 서버에서 강도 높은 하드웨어 시험을 한다.
- 교훈
GitHub 은 이번 장애에 세 가지가 겹쳤다고 밝혔다. 일어나지 말았어야 할 'active' 역할 페일오버가 여러 번 일어났고, 클러스터 상태가 갈라져 클러스터 관리 소프트웨어가 잘못된 동작을 했으며, 그 페일오버들이 필요 이상으로 성능과 가용성을 해쳤다. 두 장애는 모두 자동 페일오버에서 시작했는데, 그 페일오버를 해야 하느냐고 운영팀 누구에게 물었어도 하지 말아야 한다고 답했을 것이다. GitHub 은 자동 페일오버가 서비스 가용성을 지키는 좋은 방법인 경우가 많지만, 주 운영 데이터베이스는 그런 경우가 아니라고 결론 내렸다.
이 5건에서 가장 많이 나오는 구성 요소: 인메모리 캐시, 데이터베이스. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.
원인별1
소프트웨어 결함5건
- 구성 요소
- 기여 요인
IL-0342DigitalOcean 의 AMS3, LON1, SFO2 데이터 센터가 에지 라우터 고장으로 인터넷 연결을 되풀이해 잃었다DigitalOcean2023IL-0217스키마 캐시가 데워지지 않아 주 MySQL 데이터베이스가 내부 교착에 빠지고 Honeycomb 전체가 68분 동안 멈췄다Honeycomb2023IL-0213Consul 클러스터의 KV 쓰기가 느려지고 리더가 뒤처지며 Roblox 전체가 73시간 동안 멈췄다Roblox2021IL-0263새 애그리게이션 스위치로 옮기는 작업 뒤 데이터센터 스위치 사이 링크가 포화되어 GitHub 가 하루 종일 느렸고 18분 동안 완전히 멈췄다GitHub2012IL-0303GitHub 의 새 3노드 MySQL 클러스터에서 자동 페일오버가 잘못 일어나고 클러스터 상태가 갈라져 GitHub.com 이 두 번 멈췄다GitHub2012