Incident Library
  • 원인
  • 구성 요소
  • 증상
  • 기여 요인
  • 사례

사례13건

13건 중 6~10번째

  1. 증상

    2019년 4월 3일 2:30 am CEST 부터 updown.io 의 주 MongoDB 서버가 쿼리에 평소보다 약 200배 느리게 응답했다. 웹사이트와 모니터링 데몬이 거의 전부 멈췄다.

    촉발

    주 MongoDB 서버의 RAID5 를 이루는 SSD 3개 가운데 하나가 고장 나기 시작해 디스크 I/O 가 크게 느려졌다.

    원인
    구성 요소
    기여 요인
    –
    감지

    MongoDB 의 자동 페일오버는 하트비트가 계속 빠르게 응답해 문제를 감지하지 못했다. 운영자는 자고 있다가 8:45 am CEST 에야 문제를 알아챘다.

    조치
    • 보조 서버가 넘겨받을 준비가 됐는지 확인한 뒤 주 서버를 강제로 step down 시켰다. 8:56 am CEST 에 웹과 데몬 전체가 돌아왔지만, 보조 서버의 사양이 낮아 성능은 떨어졌다.
    • I/O 문제를 일으킨 SSD 를 RAID 어레이에서 빼자 서버가 원래 성능으로 돌아왔다.
    • 호스팅 업체에 SSD 교체 일정을 잡는 티켓을 열었다.
    • 4월 6일 12:48 pm 에 보조 서버를 더 높은 사양의 서버로 바꿨고, 그 뒤 응답 시간이 정상으로 돌아왔다.
    후속 조치
    • MongoDB 팀이 이 문제를 곧 고칠 것 같지 않아, MongoDB 가 살아 있지만 응답하지 않는 상황을 찾아 자동으로 step down 시키는 스크립트를 만든다.
    • 더 조사할 것이 없다고 확인되면 옛 보조 서버를 내리고 지운다.
    • 새 보조 서버가 며칠 동안 주 서버 역할을 버틸 수 있는지, clamscan 이 도는 밤까지 포함해 확인한다.
    • 주 서버가 정상으로 돌아오면 자동 step down 스크립트를 시험한다.
    • updown.io 의 제대로 된 상태 페이지를 만든다.
    • MongoDB 가 Storage Node Watchdog 을 커뮤니티 에디션에도 제공하자 이를 켜서 한동안 시험했다. 잘 동작해 직접 만든 스크립트는 지웠다.
  2. 증상

    2018년 10월 21일 22:54 UTC 에 내부 모니터링 시스템이 여러 시스템에서 장애가 났다는 알림을 쏟아내기 시작했다. 23:02 UTC 에 첫 대응 팀은 여러 데이터베이스 클러스터의 토폴로지가 예상하지 못한 상태라는 것을 확인했다.

    촉발

    10월 21일 22:52 UTC 에 고장 난 100G 광 장비를 교체하는 정기 유지보수 작업 중 미국 동부 네트워크 허브와 동부 주 데이터센터 사이의 연결이 끊겼다. 연결은 43초 만에 돌아왔다.

    원인
    구성 요소
    기여 요인
    감지

    22:54 UTC 에 내부 모니터링 시스템이 알림을 내기 시작해 여러 엔지니어가 알림을 분류했다. 23:02 UTC 에 첫 대응 팀이 Orchestrator API 를 조회해 복제 토폴로지에 서부 데이터센터 서버만 남은 것을 확인했다.

    조치
    • 23:07 UTC 에 내부 배포 도구를 수동으로 잠가 더는 변경이 들어오지 않게 했다.
    • 푸시 같은 메타데이터를 쓰는 작업을 멈추려고 웹훅 전송과 GitHub Pages 빌드를 일시 중지했다.
    • 10월 22일 06:51 UTC 까지 여러 클러스터를 미국 동부 데이터센터에서 백업으로 복원했고, 복원된 서버는 서부에서 새 데이터를 복제받기 시작했다.
    • 외부 저장소에서 내려받는 처리량 한계를 피하려고 서부 데이터센터에서 직접 복원하는 방법을 찾았다.
    • 11:12 UTC 에 모든 데이터베이스 프라이머리를 다시 미국 동부에 세웠다.
    • 미국 동부 퍼블릭 클라우드에 MySQL 읽기 복제본을 추가로 띄워 읽기 요청을 더 많은 서버로 나눴고, 복제본 전체의 사용률이 내려가 복제가 따라잡았다.
    • 복제본이 맞춰진 뒤 16:24 UTC 에 원래 토폴로지로 페일오버했다.
    • 밀린 웹훅 이벤트와 Pages 빌드를 처리했다. 웹훅 페이로드 약 200,000건이 내부 TTL 을 넘겨 버려진 것을 발견하자 처리를 멈추고 TTL 을 당분간 늘리는 변경을 배포했다.
    후속 조치
    • 각 클러스터에서 서부로 복제되지 않은 쓰기를 담은 MySQL 바이너리 로그를 분석해, 자동으로 맞출 수 있는 쓰기와 사용자에게 연락해야 하는 쓰기를 가린다.
    • GitHub Pages 빌드가 멈춘 상황에서도 공지 글을 낼 수 있게 한다.
    • 장애 중 복구 예상 시간을 더 정확하게 알린다.
    • Orchestrator 설정을 고쳐 데이터베이스 프라이머리가 리전 경계를 넘어 승격되지 않게 한다.
    • 녹색, 노란색, 빨간색 세 단계만 있던 상태 표시를 새 상태 보고 방식으로 옮겨 플랫폼 구성 요소마다 상태를 보여 준다.
    • 여러 데이터센터에서 트래픽을 받는 active/active/active 구성으로 옮기는 일을 앞당겨, 시설 단위 N+1 이중화로 데이터센터 하나가 통째로 망가져도 사용자에게 영향이 없게 한다.
    • 시스템이 기대는 가정을 더 적극적으로 시험한다.
    • 장애 시나리오를 사용자에게 닿기 전에 검증하는 관행을 들이고, 장애 주입과 카오스 엔지니어링 도구에 투자한다.
    교훈

    GitHub 은 Orchestrator 가 설정대로 움직였지만 애플리케이션 계층은 그 토폴로지 변경을 견디지 못했다고 봤다. 리전 안의 리더 선출은 대체로 안전하지만, 갑자기 생긴 대륙 간 지연이 이번 장애를 키운 큰 요인이었다. 자동 페일오버 설정은 애플리케이션이 기대하는 것과 맞춰야 한다. GitHub 은 이만큼 복잡한 서비스 체계에서는 운영 통제를 조이거나 대응을 빠르게 하는 것만으로는 안정성을 지킬 수 없다고 판단했다. 그래서 가정을 더 적극적으로 시험하고, 장애 시나리오를 사용자에게 닿기 전에 검증하기로 했다. 복구 예상 시간은 모든 변수를 고려하지 못해 틀렸다.

  3. 증상

    2017년 10월 13일 14:01 PDT 에 실시간 지표와 모니터링이 이상을 알렸다. API 서비스가 쓰는 Redis 고가용 클러스터에서 primary 노드가 완전히 사라졌다. 클러스터는 secondary 노드로 제대로 failover 했지만, 일부 API 인스턴스가 failover 를 제대로 처리하지 못했다.

    촉발

    14:01 PDT 쯤 Google Cloud Platform 이 API 서비스용 Redis 고가용 클러스터의 primary 인스턴스를 자동으로 마이그레이션했다. 이 마이그레이션으로 노드가 잘못 오프라인이 되면서 클러스터가 재조정됐고, API 인스턴스의 Redis failover 처리에 있던 알려진 문제가 드러났다.

    원인
    구성 요소
    기여 요인
    감지

    14:01 PDT 에 실시간 지표와 모니터링이 이상을 알렸다. 15:41 에 모니터링에서 다시 이상이 보였고, 15:42 에 서버 일부가 오프라인으로 보인다는 사용자 신고가 엔지니어링 팀에 들어왔다.

    조치
    • Redis 연결 문제를 풀려고 14:11 PDT 에 모든 API 인스턴스를 롤링 재시작했다. 재시작은 14:15 에 끝났지만 API 지연은 계속 높았다.
    • 비용이 큰 API 경로에 잘못 걸린 엣지 캐시 규칙을 고쳤다.
    • 엔드포인트를 쓸 수 없는 동안에는 응답을 캐시할 수 없어서, 문제를 일으킨 API 엔드포인트를 상위 엣지 네트워크에서 막았다.
    • 부하로 쓰러진 Cassandra 클러스터를 되살려 정상 서비스로 돌렸다.
    • Cassandra 클러스터 문제로 생긴 지연을 풀려고 모든 API 인스턴스를 다시 롤링 재시작했다. 14:57 에 API 가 정상으로 돌아왔다.
    • 15:50 PDT 에 이상하게 동작하는 "guilds" 노드를 서비스 해시링에서 강제로 빼서, 그 서버가 스스로 제대로 내려가기를 기대했다.
    • 15:52 PDT 에 그 guilds 노드를 강제로 재시작했고, 재시작은 성공했다.
    • 16:07 PDT 에 전체 서비스를 재시작하기로 하고, 모든 사용자를 다시 접속시켜 여러 서비스의 잘못된 상태를 초기화했다.
    • "push" 구성 요소의 부하를 줄이려고 이 구성 요소에 기대는 트래픽 여러 갈래를 차단 목록에 넣었다.
    • 사용자가 빠르고 안전하게 다시 접속하게 해 주는 API 설정이 사람의 실수로 잘못 들어가 있던 것을 고쳤다. 16:33 부터 서비스가 천천히 회복했다.
    후속 조치
    • Redis failover 의 알려진 문제를 고치는 일의 우선순위를 올려, 앞으로 몇 주 안에 끝내려 한다. 노드 하나의 장애로 문제가 더 생기지 않게 하려는 것이다.
    • 캐시가 잘못 걸렸던 경로의 동작을 바꿔, 앞으로 이런 오류가 나도 다른 서비스를 망가뜨리지 않고 제대로 처리하게 했다.
    • 연쇄 장애를 미리 알려 줄 수 있었던 신호 일부에 모니터링을 더했다. 엔지니어가 조사하고 대비할 시간을 벌려는 것이다.
    • 이번 장애에 영향을 받은 서비스들의 전반적인 신뢰성과 장애 처리를 개선할 계획을 이어 간다.
    • 문제가 된 서비스가 쓰는 라이브러리에서 결함으로 보이는 것을 찾았고, 이를 고칠 것으로 보는 업데이트를 배포하고 있다.
  4. 증상

    2017년 10월 10일 15:09 BST 에 모니터링이 API 와 대시보드가 완전히 멈춘 것을 찾았다. 그동안 들어온 요청은 모두 실패하고 오류를 받았다.

    촉발

    10월 10일 오후 Postgres 프라이머리 노드의 RAID 컨트롤러가 디스크 3개를 동시에 잃어 디스크 어레이가 망가졌다. 거의 같은 때 동기 복제본에서 Postgres 하위 프로세스 하나가 죽었다.

    원인
    구성 요소
    기여 요인
    감지

    15:09 BST 에 모니터링이 API 와 대시보드의 완전한 중단을 찾았고 엔지니어들이 조사를 시작했다.

    조치
    • 15:17 BST 에 디스크 어레이가 망가진 채 켜져 있는 노드를 클러스터에 두지 않으려고 망가진 Postgres 프라이머리 노드의 전원을 껐다. 클러스터는 여전히 새 프라이머리를 승격하지 않았다.
    • 15:18 BST 에 Pacemaker 가 Postgres 인스턴스 상태를 다시 파악하게 하려고 crm resource cleanup 으로 오류 횟수를 지웠지만 효과가 없었다.
    • Pacemaker 클러스터를 유지보수 모드로 두고 동기 복제본의 recovery.conf 에서 복제본 설정을 지운 뒤 유지보수 모드를 풀어 직접 승격하려 했지만, 매번 원래 recovery.conf 로 돌아갔다.
    • 16:18 BST 에 클러스터를 마지막으로 유지보수 모드로 두고 동기 복제본을 프라이머리로 설정해 Postgres 를 직접 띄웠다.
    • 클러스터가 유지보수 모드라 가상 IP 를 옮길 수 없었으므로 백엔드 애플리케이션이 새 프라이머리의 실제 IP 주소로 접속하게 다시 설정했다.
    • 평소 수준의 이중화를 되찾으려고 세 번째 노드를 비동기 복제본으로 띄웠다.
    • Pacemaker 가 유지보수 모드라 자동 페일오버가 없었으므로 인프라 팀이 손으로 관리할 가상 IP 를 하나 더 두어, 프라이머리가 망가지면 동기 복제본을 승격하고 가상 IP 를 직접 옮길 수 있게 했다.
    • 디스크 어레이 장애였으므로 생각할 수 있는 모든 시험으로 데이터 무결성을 확인했고 데이터 손상의 증거는 없었다.
    • Pacemaker 가 다시 관리하는 새 데이터베이스 클러스터를 만들고, 유지보수 시간을 공지한 뒤 문제없이 옮겼다. 옛 클러스터는 내렸다.
    후속 조치
    • Backup VIP 의 colocation 규칙을 Postgres 프라이머리와의 -INF 선호 대신 복제본과의 INF 선호로 바꿔, 같은 장애 조건에서도 동기 복제본이 승격되게 했다.
    • 특정 Postgres 인스턴스로 트래픽을 보내는 가상 IP 를 없애고, 애플리케이션 서버에서 클러스터 상태에 따라 알맞은 노드로 트래픽을 보내는 프록시를 돌려 Pacemaker 가 관리하는 자원 수를 줄인다.
    • Postgres 클러스터를 더 거칠게 시험하고, Chaos Monkey 처럼 계속 장애를 주입하는 자동화를 검토한다.
    • 장애 대응 훈련인 게임 데이에 임의의 제약을 넣는 방안을 검토한다. 예를 들어 자동화가 실패하고 원인도 찾을 수 없는 상황에서 다른 방법으로 서비스를 되살리게 한다.
    교훈

    GoCardless 는 단순해 보이는 Pacemaker 설정이 매우 이상한 동작을 부를 수 있다는 것을 배웠다. 두 자원이 함께 돌면 안 된다는 규칙과 함께 돌아야 한다는 규칙은 반대말처럼 보이지만, 특정 장애 조건에서는 시스템이 완전히 다르게 움직였다. 프로세스 두 개가 거의 동시에 죽을 때만 드러나는 설정 오류는 기본 시험이나 평소 운영으로는 찾을 수 없고, 장애 주입으로만 드러나는 버그가 있다. 자동화가 2년 동안 장애를 잘 처리하자 그 아래 인프라를 손으로 다루는 기술이 녹슬었다. 런북을 써 두어도 몇 년 뒤에 꺼내 보면 거의 확실히 낡아 있다.

  5. 증상

    2017년 1월 24일 17:53 UTC 부터 Stack Exchange 네트워크가 약 5분 동안 읽기 전용으로 동작했다. 그 뒤 Stack Overflow 를 포함한 사이트 전체가 12분 동안 내려갔다.

    촉발

    주 SQL Server 인 NY-SQL02 에서 SQL Server 프로세스가 bugcheck 를 일으켰다.

    원인
    구성 요소
    기여 요인
    조치
    • NY-SQL02 의 SQL 서비스를 재시작해 네트워크를 읽기 전용으로 되살렸다.
    • SQL 상태를 점검한 뒤 사이트를 읽기·쓰기 모드로 되돌렸다.
    • 메모리가 384GB 라서 메모리 덤프가 끝나기를 기다리지 않고 네트워크를 먼저 살렸다.
    • NY-SQL02 를 운영에서 빼 메모리 시험을 포함한 점검에 들어갔다. 평소 부하는 모두 NY-SQL01 이 받게 했다.
    • 이 기회에 SQL 클러스터를 2016 SP1 CU1 로 올렸다.
내 클러스터에도 있는지 확인하기

이 13건에서 가장 많이 나오는 구성 요소: 데이터베이스, 데이터베이스 장애 조치 관리자. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별7

소프트웨어 결함4건

  1. IL-0310 Aurora PostgreSQL 의 수동 장애 조치가 스스로 되돌아가 원래 writer 가 남고 백엔드의 쓰기 쿼리가 실패했다
  2. IL-0241 데이터베이스 shard 하나가 primary 를 뽑지 못해 Stripe API 요청 대부분이 두 차례 실패했다
    Stripe2019
  3. IL-0388 Redis 고가용 클러스터의 primary 노드가 내려간 뒤 Discord API 가 느려지고 길드 일부가 오프라인으로 보이며 접속이 실패했다
  4. IL-0303 GitHub 의 새 3노드 MySQL 클러스터에서 자동 페일오버가 잘못 일어나고 클러스터 상태가 갈라져 GitHub.com 이 두 번 멈췄다
    GitHub2012

용량 한계3건

  1. IL-0544 Wasabi 전 리전의 S3 와 사용자 서비스에 이틀에 걸쳐 세 차례 장애가 났다
    Wasabi2024
  2. IL-0302 GitHub 의 공용 MySQL 클러스터 mysql1 이 최대 부하 시간대에 연결이 바닥나 쓰기 작업이 네 번 멈췄다
    GitHub2022
  3. IL-0320 주 MySQL 서버의 디스크가 가득 차 메일 발송, API, 웹 화면이 지연됐다

설정 변경1건

  1. IL-0367 Central US 의 Azure Storage 가 VM 디스크 요청을 거부해 VM 과 그 위의 SQL Database, Cosmos DB 가 멈췄다

하드웨어 고장2건

  1. IL-0289 updown.io 의 주 MongoDB 서버가 쿼리에 평소보다 약 200배 느리게 응답해 사이트와 모니터링 데몬이 거의 멈췄는데 자동 페일오버가 일어나지 않았다
  2. IL-0219 Postgres 프라이머리의 디스크 어레이가 망가진 뒤 Pacemaker 가 새 프라이머리를 승격하지 못해 GoCardless API 와 대시보드가 1시간 50분 멈췄다

DNS·네트워크 장애1건

조직
  1. IL-0210 43초 네트워크 단절 뒤 MySQL 프라이머리가 미국 서부로 넘어가 GitHub.com 이 24시간 11분 동안 느려지고 오래된 데이터를 보여 줬다
    GitHub2018

unknown1건

구성 요소
기여 요인
  1. IL-0335 주 SQL Server 의 bugcheck 로 Stack Exchange 네트워크가 읽기 전용이 됐다가 12분 동안 내려갔다

운영 실수1건

  1. IL-0337 US East 리전 한 가용 영역에서 네트워크 변경으로 EBS 노드가 복제본과 끊겨 EBS 볼륨이 멈췄다