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

사례16건

16건 중 11~15번째

  1. 증상

    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년 동안 장애를 잘 처리하자 그 아래 인프라를 손으로 다루는 기술이 녹슬었다. 런북을 써 두어도 몇 년 뒤에 꺼내 보면 거의 확실히 낡아 있다.

  2. 증상

    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 로 올렸다.
  3. 증상

    2016년 2월 8일 17:45 UTC 에 Google Cloud Platform 의 Redis Cloud 클러스터 us-central1-1-1.gce.garantiadata.com 에서 큰 장애가 났다. 데이터베이스 엔드포인트가 us-central1-1-1.gce.garantiadata.com 으로 끝나는 사용자들이 데이터베이스를 쓰지 못했다.

    촉발

    2016년 2월 8일 17:30 UTC 에 서비스 소프트웨어의 주간 업그레이드가 GCP 클러스터 us-central1-1-1.gce.garantiadata.com 에 처음 배포됐다.

    원인
    구성 요소
    기여 요인
    조치
    • 클러스터의 모든 노드를 내리고 종료했다.
    • 클러스터의 모든 엔드포인트를 클러스터의 DNS 영역에서 지웠다. DNS 제공자가 삭제 요청을 스로틀링해 남은 항목은 손으로 지웠다.
    • 주간 업데이트를 뺀 새 클러스터 노드를 처음부터 만들었다.
    • 원래 노드가 쓰던 저장소를 새 노드에 다시 붙여, 영속성이 있는 데이터베이스를 복구할 수 있게 했다.
    • 데이터베이스를 모두 띄웠고, 영속성이 있는 데이터베이스는 저장소에서 복구했다.
    후속 조치
    • 이번 같은 장애를 막는 절차를 갖출 때까지 자동 주간 업그레이드를 모두 멈춘다.
    • DevOps 코드 배포의 QA 절차를 다시 검증한다.
    • DNS 요청이 스로틀링될 때 도구가 이를 처리하도록 개선한다.
  4. 증상

    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. 증상

    오전 8시 15분 EDT 무렵 주 MySQL 서버의 디스크 공간이 바닥나 메일 발송, API, 웹 화면이 지연됐다. 디스크 공간 알림을 알아챘을 때 MySQL 은 이미 제대로 동작하지 못하고 있었다.

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

    서버마다 디스크 공간을 감시해 알리는 시스템이 있었다. 이번에는 공간이 평소보다 훨씬 빨리 차서, 알림을 알아챘을 때 MySQL 은 이미 제대로 동작하지 못하고 있었다.

    조치
    • 로그를 지워 디스크 공간을 확보하려 했지만 쉽게 되지 않았다.
    • 약 30분 뒤 두 번째 서버로 직접 장애 조치했고, 그 뒤 서비스가 정상으로 돌아왔다.
    • 장애 조치 뒤 실패한 작업을 복구했다.
    • 데이터베이스를 쓸 수 없는 동안 각 서버가 메일을 로컬 큐에 쌓아 두었다가 복구 뒤 보냈으므로 잃어버린 메일은 없었다.
    후속 조치
    • 가용성과 성능에 초점을 맞춰 클러스터를 업그레이드한다.
    • 문제를 더 일찍 잡도록 알림을 조금 더 민감하게 바꾼다.
    교훈

    돌아보면 처음부터 바로 두 번째 서버로 장애 조치했어야 했다. 팀은 복제가 정상인지 먼저 확인하려다가 약 30분을 썼다.

내 클러스터에도 있는지 확인하기

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

원인별9

소프트웨어 결함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-0291 GitLab.com 의 redis-sidekiq Sentinel 이 쿼럼을 만들지 못해 Sidekiq 이 30분 동안 멈추고 500 오류가 늘었다
    GitLab2023
  2. IL-0588 AppOptics 와 Librato 의 메트릭 API 가 대부분의 데이터에 5xx 를 내고 Kafka 파티션이 리더 없이 오프라인으로 남았다

하드웨어 고장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-0278 주간 소프트웨어 업데이트 뒤 GCP 의 Redis Cloud 클러스터 노드 대부분이 동시에 응답하지 않아 그 클러스터의 데이터베이스가 내려갔다
    Redis2016

운영 실수1건

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