사례3건
3건 중 1~3번째
- 증상
2024년 9월 18일 데이터센터 전환을 앞두고 cookbook 으로 원형 복제를 설정하던 중, 21:28 UTC 쯤 엔지니어가 x1 섹션의 primary master 가 복제를 하지 않는 것을 orchestrator 에서 먼저 알아챘다. es6 섹션도 같은 상태였다.
- 촉발
다음 주 데이터센터 전환을 앞두고 cookbook 이 핵심 데이터베이스를 eqiad 에서 codfw 로 가는 한 방향 복제에서 원형 복제로 바꿨다. ROW 기반 복제를 쓰는 x1 섹션에 codfw 에서 eqiad 로 가는 복제를 설정하고 pt-heartbeat 를 시작하자, eqiad 서버에 없는 heartbeat 행을 갱신하려다 복제가 멈췄다.
- 원인
- 구성 요소
- 기여 요인
- 감지
원형 복제의 일반 모니터링이 아직 켜지지 않아, 엔지니어가 orchestrator 에서 먼저 알아챘다. 복제 자동화가 처음 도는 날이라 평소보다 많은 사람이 데이터베이스 상태를 지켜보고 있었다. 사용자에게 영향을 준 eqiad 에서 codfw 로 가는 방향의 고장은 Icinga 알림이 잡았다. 온콜 호출을 받은 사람은 없었다.
- 조치
- SET GLOBAL Replication_wild_ignore_table='heartbeat.%'; 로 heartbeat 테이블 복제를 건너뛰게 해 복제가 다시 흐르게 했다.
- es 호스트에는 원래 고장이 난 방향에 맞춰, binlog 기록을 끈 채 eqiad 서버마다 빠진 codfw heartbeat 행을 직접 넣었다. 명령은 set sql_log_bin=0; INSERT INTO heartbeat.heartbeat (server_id, shard, datacenter) VALUES (<codfw-server-id>, 'es6' [or 'es7'], 'codfw'); 였다. es6 에서 먼저 시험했고, es7 에는 원형 복제를 설정하기 전에 미리 넣었다.
- x1 codfw 호스트마다 binlog 기록을 끈 채 빠진 heartbeat 행을 넣어, 임시로 걸어 둔 heartbeat 무시 설정을 대신했다. 명령은 set sql_log_bin=0; INSERT INTO heartbeat.heartbeat (server_id, shard, datacenter) VALUES (<eqiad-server-id>, 'x1', 'eqiad'); 였다.
- 후속 조치
- 같은 문제를 다시 겪지 않게 한다. 빠진 행을 찾으면 직접 넣는 방식을 유력하게 본다.
- 유지 보수 뒤 복제가 의도대로 양방향으로 동작하는지 확인하는 상태 점검을 cookbook 에 넣는다.
- 유지 보수를 다른 순서로, 또는 섹션마다 따로 돌릴 수 있는 옵션을 더한다.
- Phabricator 를 마지막에 한 번만 갱신하지 않고 섹션마다 갱신한다.
- 모니터링의 빈틈을 메운다.
- x1 과 ROW 를 쓰는 읽기·쓰기 es 호스트에서 pt-heartbeat-wikimedia 가 자기 세션을 STATEMENT 로 쓰도록 고쳐 배포했다.
- 교훈
원형 복제는 평소 운영 방식이 아니어서 heartbeat 테이블을 지우는 첫 조치가 문제를 eqiad 에서 codfw 로 옮기기만 했다. TRUNCATE 는 DDL 이라 늘 STATEMENT 모드로 전달되므로 이번에는 DELETE 보다 나았겠지만, 더 위험해서 고려하지 않았다. ROW 기반 복제, pt-heartbeat, 서버마다 다른 heartbeat 테이블 행이 겹친 문제는 이전 유지 보수 기록에 없었다. 자동화의 점검은 설정 직후 한 번이 아니라 모든 작업이 끝난 뒤에도 복제 채널을 확인했어야 했다. Wikimedia 는 어느 호스트에서도 sql_skip_slave_counter 를 쓰지 않아 더 큰 문제나 데이터 손실을 피한 것을 잘된 점으로 꼽았다.
IL-0367Central US 의 Azure Storage 가 VM 디스크 요청을 거부해 VM 과 그 위의 SQL Database, Cosmos DB 가 멈췄다Microsoft Azure2024- 증상
Central US 리전에서 VM 가용성이 떨어졌고, 그 VM 에 기대는 여러 Azure 서비스에서 연결 실패와 서비스 관리 작업 실패가 났다. 서비스 모니터링은 7월 18일 22:06 UTC 에 VM 가용성 하락을 잡았고, 22:14 UTC 에 Cosmos DB, SQL DB, SQL DB Managed Instance 의 가용성 하락을 잡았다.
- 촉발
일상적인 VM 호스트 변경에 맞춰 스토리지 허용 목록을 새로 만들 때, 목록을 만드는 서버가 네트워크 설정이 바뀐 인프라 파일 서버 일부에 접근하지 못했다. 그래서 VM 호스트 주소 범위 일부가 빠진 목록이 Central US 의 모든 스토리지 스케일 유닛에 배포됐다.
- 원인
- 구성 요소
- 기여 요인
- 감지
허용 목록이 Central US 에 배포되는 동안 서비스 모니터링이 VM 가용성 하락을 잡았고, 엔지니어링 팀이 투입됐다. VM 가용성 하락을 잡은 시각은 22:06 UTC 로, 고객 영향이 시작되고 26분 뒤였다. SQL 모니터링은 SQL 을 쓸 수 없게 된 지 1분 안에 비정상 노드와 로그인 실패를 잡았고, 22:14 UTC 에는 모니터링이 Cosmos DB, SQL DB, SQL DB Managed Instance 의 가용성 하락을 잡았다.
- 조치
- 원인을 확인한 뒤 허용 목록 갱신 워크플로를 전 세계에서 멈췄다.
- 23:27 UTC 에 Central US 리전의 모든 배포를 멈췄다.
- 23:35 UTC 에 모든 리전의 컴퓨트 증설 배포를 멈췄다.
- Central US 리전의 모든 스토리지 스케일 유닛의 설정을 고쳐 7월 19일 02:55 UTC 에 스토리지 가용성을 되살렸다.
- 장애 1시간 안에 자동 장애 조치 정책이 있는 SQL 데이터베이스의 장애 조치를 시작했다. geo-secondary 를 새 프라이머리로 올리고 장애 조치 그룹 엔드포인트가 새 프라이머리를 가리키게 했다.
- SQL 게이트웨이 노드를 재시작해 캐시를 새로 고치고, 연결이 올바른 노드로 가게 했다.
- 끝나지 않은 SQL 장애 조치를 강제로 완료했다.
- 영향이 시작된 직후, Central US 에 쓰기 리전이 있는 다중 리전 액티브-패시브 계정을 위해 Cosmos DB 컨트롤 플레인의 장애 조치를 시작했다. 이어 고객 계정을 다른 리전으로 장애 조치했다.
- 일부 계정에서는 고객이 Azure 포털에서 시작한 "graceful switch region" 작업이 Microsoft 가 시작한 서비스 관리 장애 조치를 막고 있었다. 이런 계정에서는 그 작업을 취소했다.
- 일부 계정은 오래 도는 컨트롤 작업이 서비스 메타데이터에 잠금을 잡고 있어 장애 조치가 끝나지 않았다. 이런 계정은 그 잠금을 지워 장애 조치를 강제로 완료했다.
- 장애 조치와 함께, 비정상으로 표시된 Cosmos DB 파티션을 고치는 작업을 따로 진행했다. 이 작업으로 Central US 단일 리전 계정의 가용성을 09:41 UTC 까지 99.9% 넘게 되살렸고, 19:30 UTC 쯤 모든 데이터베이스의 영향을 완화했다.
- 08:51 UTC 부터는 백엔드 노드 수리가 진행되는 대로, Microsoft 가 장애 조치했던 Cosmos DB 계정을 Central US 로 되돌렸다. Central US 를 먼저 읽기 리전으로 추가했고, 쓰기 리전을 다시 Central US 로 옮길지는 고객이 정하게 했다.
- 후속 조치
- 허용 목록을 만드는 워크플로가 원본 정보가 빠진 것을 알아채면 멈추게 고친다.
- 스토리지 요청이 허용 목록 검사에서 거부되면 알림을 보낸다.
- 허용 목록 배포를 가용 영역과 스토리지 종류에 따라 차례로 진행하고, 배포 기간을 24시간으로 늘린다.
- 허용 목록 배포 워크플로에 VM 상태 확인을 더하고, 이상이 보이면 배포를 자동으로 멈춘다.
- Microsoft 가 SQL 장애 조치 그룹의 장애 조치를 시작하는 정책을 다시 검토하고, 고객이 장애 조치를 직접 관리하라는 권고를 다시 알린다.
- Cosmos DB 페일백 워크플로를 고친다. 이 워크플로 때문에 MongoDB API 계정 일부에서 특정 버전의 MongoDB 드라이버가 모든 리전에 연결하지 못했다.
- 프라이빗 엔드포인트가 있는 Cosmos DB 계정이 페일백 뒤 Central US 에 연결하지 못하던 문제를 고쳐, Microsoft 가 페일백을 다시 하지 않아도 되게 한다.
- 스토리지 데이터 플레인 방화벽이 잘못된 허용 목록 배포를 알아채고 마지막으로 정상이던 상태를 계속 쓰게 한다.
- Azure NetApp Files 의 여러 모니터 로직을 고쳐 영향을 주는 이벤트를 제때 잡고 알맞게 분류하게 한다.
- Azure NetApp Files 의 여러 서비스 지표를 더 모니터링해 비슷한 문제를 잡고 관련 이벤트를 더 빨리 서로 연결해 보게 한다.
- SQL 이 쓰는 Service Fabric 클러스터 위치 변경 알림 메커니즘이 부하가 클 때도 믿을 만하게 동작하게 한다.
- SQL 지역 장애 조치 워크플로를 견고하게 만들어 장애 조치가 끝까지 완료되게 한다.
- Cosmos DB 장애 조치의 5%를 늦춘 문제를 없앤다.
- Azure DevOps 의 모든 고객 메타데이터를 알맞은 지리 영역으로 옮겨, 한 장애가 여러 지리 영역에 걸쳐 영향을 주지 않게 한다.
- Azure NetApp Files 의 리전 사이 읽기와 쓰기를 분리해, 이런 종류의 문제가 한 리전 안에서 끝나게 한다.
- Azure NetApp Files 가 저장소에 둔 사용률 데이터에 덜 기대도록 캐시를 쓰는 방안을 검토한다.
- Cosmos DB 다중 리전 액티브-패시브 계정에 파티션 단위 자동 장애 조치를 넣어, 영향받은 파티션을 자동으로 처리하게 한다.
- SQL 과 Cosmos DB 를 위해 Azure Virtual Machines 가 Resilient Ephemeral OS disk 개선을 진행해, 스토리지 장애에도 VM 이 더 잘 버티게 한다.
- 증상
2019년 7월 29일 13:14 BST 에 Mastercard 카드 거래 일부가 실패한다는 자동 알림이 울렸다. 같은 시각 고객 응대 팀이 고객과 소통하는 도구가 제대로 동작하지 않아 앱 채팅으로 고객을 도울 수 없다고 알려 왔다.
- 촉발
2019년 7월 29일 13:10 BST 에 Cassandra 클러스터에 새 서버 여섯 대를 넣었다. 운영 환경의 auto_bootstrap 플래그는 false 였다.
- 원인
- 구성 요소
- 기여 요인
- 감지
13:14 BST 에 Mastercard 카드 거래 일부가 실패한다는 자동 알림이 울렸고, 같은 시각 고객 응대 팀이 고객 소통 도구가 동작하지 않는다고 알려 왔다.
- 조치
- 계획해 둔 대체 배포 방법으로 Mastercard 서비스의 수정을 배포했다.
- 새 Cassandra 서버를 한 대씩 빼서 데이터 담당을 원래 서버로 안전하게 되돌렸다.
- 새 서버 여섯 대가 읽기와 쓰기를 처리하는 동안 쓰인 데이터를, 외부에 저장한 이벤트를 재생하고 내부 정합성 확인 작업을 돌려 바로잡았다.
- 후속 조치
- auto_bootstrap 설정을 바로잡았다.
- Cassandra 의 다른 설정을 두고 내린 결정을 모두 검토하고 문서로 남겨, 확장이나 재시작 같은 작업의 런북을 늘렸다.
- 더 많은 지표를 드러내고, 'row not found' 같은 지표가 크게 바뀌면 알림을 보내는 방안을 검토한다.
- 장기적으로 큰 Cassandra 클러스터 하나를 작은 클러스터 여러 개로 나눈다.
- 교훈
Monzo 는 Cassandra 운영 지식에 빈틈이 있었다. 롤링 재시작이나 서버 업그레이드는 자주 했지만 서버 추가는 드물었다. 시험 환경에서는 운영과 같은 규모로 시험하지 않아 여섯 대 대신 한 대로 시험했고, 쿼럼을 고려하지 못했다. Cassandra 가 원인임을 보여 주는 지표가 없어 대응이 늦었다. 클러스터 하나로 모든 서비스를 돌리면 변경 하나의 영향이 넓고 장애 원인을 짚기도 어렵다. 이번에는 첫 알림부터 Cassandra 를 원인으로 짚기까지 거의 한 시간이 걸렸다.
이 3건에서 가장 많이 나오는 구성 요소: 데이터베이스, 클라우드 블록 스토리지. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.