그래프
사례2건
2건 중 1~2번째
- 증상
2026년 10월 6일 13시 30분 UTC부터 CircleCI 의 워크플로 조율 서비스가 느려져 일부 파이프라인과 잡이 이따금 조금씩 늦게 시작했다. 15시 30분부터는 지연이 계속 이어졌고 일부 잡이 실패하기 시작했다.
- 촉발
10월 6일 12시 40분쯤 데이터베이스의 가장 큰 테이블 몇 개에서 돌던 정기 유지 보수 작업인 anti-wraparound autovacuum 이 평소 작업량과 겹치면서, 데이터베이스가 트랜잭션 로그를 보관 처리하는 속도보다 빠르게 로그를 썼다.
- 원인
- 구성 요소
- 기여 요인
- 감지
10시 2분부터 모니터링이 조율 서비스의 오류 알림을 짧게 여러 번 냈지만 매번 저절로 풀렸다. 13시 35분에 여러 다른 서비스의 관련 알림과 함께 다시 울렸고, 14시 30분쯤 알림이 다시 울리자 더 조사한 뒤 14시 54분에 장애를 선언했다. 트랜잭션 로그 볼륨이 얼마나 찼는지와 보관 처리가 얼마나 밀렸는지를 보는 알림은 없었다. 상태 페이지에는 15시 58분에 공지를 올렸고 16시 20분에 주요 장애로 올렸다.
- 조치
- anti-wraparound autovacuum 이 빨리 끝나도록 설정을 바꿨다. 이 작업은 취소하면 데이터베이스가 자동으로 다시 시작하기 때문이었다.
- 트랜잭션 로그 볼륨이 거의 차자 데이터베이스가 읽기 전용이 되지 않도록 로그를 여유 공간이 많은 데이터베이스의 주 저장 볼륨으로 옮겼다. 옮기는 동안 데이터베이스가 50분 동안 내려갔다.
- 유지 보수 작업이 더 시작되지 않도록 데이터베이스 파라미터 몇 가지를 조사해 바꿨다.
- 18시 19분에 쓰기마다 저장소를 기다리는 시간을 줄이는 데이터베이스 설정을 바꿔 처리 속도를 되살렸다.
- 밀린 작업을 빨리 처리하려고 잡을 실행 플릿에 넘기는 시스템에 데이터베이스와 서버 용량을 더했다.
- 후속 조치
- 트랜잭션 로그 볼륨이 얼마나 찼는지와 보관 처리가 얼마나 밀렸는지에 알림을 건다.
- 이 두 상태를 일으키는 데이터베이스 유지 보수 작업에도 알림을 걸어 더 일찍 대응한다.
- 시끄럽거나 지나치게 민감한 알림이 실제 문제를 가리지 않도록 모든 알림을 다시 살핀다.
- 데이터베이스의 autovacuum 이 얼마나 자주, 얼마나 공격적으로 도는지를 조정한다.
- 큰 테이블들의 크기를 시간에 따라 추적해 안전한 한계 안에 두게 한다.
- 트랜잭션 로그 하나에 모든 쓰기가 몰리는 병목을 없앤다. 서비스를 각자 트랜잭션 로그를 가진 여러 데이터베이스 인스턴스로 나누는 방법과, 쓰기를 여러 노드에 나누는 분산 데이터베이스로 옮기는 방법을 검토한다.
- 다른 시스템들이 재시도 끝에 포기하지 않고 조율 서비스가 회복할 때까지 기다리도록 동작을 바꾼다.
- 긴 장애 동안 상태 페이지 공지가 구체적인 영향과 시각을 더 일찍 담도록 지침을 고친다.
- 교훈
CircleCI 는 여러 알림이 함께 울린 것을 더 일찍 알아챘어야 했다고 밝혔다. 모니터링은 느려진 것을 잡았지만 트랜잭션 로그 볼륨이 찬 정도와 보관 처리가 밀린 정도에는 알림이 없었다. 조율 서비스의 모든 쓰기가 데이터베이스 하나와 트랜잭션 로그 하나를 거치기 때문에, 그 로그가 밀리자 모든 파이프라인, 워크플로, 잡이 함께 느려졌다. 일부 잡은 다른 시스템들이 재시도 끝에 포기해서 실패했다. 고객들은 초기 상태 페이지 공지에 세부 내용이 부족했다고 알려 왔다.
- 증상
2021-05-21 13:00 UTC 에 CircleCI 엔지니어가 작업 시작이 지나치게 늦어진다는 첫 호출을 받았다. Docker, Machine executor, remote Docker 작업이 늦어지거나 막혔고, 시스템이 GCP 의 CPU 쿼터에 걸려 VM 을 띄우지 못하고 있었다.
- 촉발
2021-05-20 08:37 UTC 에 RabbitMQ 를 3.8.9 에서 3.8.16 으로 올렸다. 3.8.15 에서 들어온 변경으로, 메시지를 받고 ack 하지 않는 컨슈머에 기본 15분 ack 타임아웃이 걸렸다. 변경 기록에는 quorum queue 에만 해당한다고 적혀 있었지만 실제로는 모든 큐 종류에 적용됐다.
- 원인
- 구성 요소
- 기여 요인
- 감지
02:31 UTC 에 VM destroyer 서비스 대기열 하나에 컨슈머가 없다는 알림이 왔고, 파드를 재시작해 정상으로 돌렸다. 그 뒤 03:10 에 다시 컨슈머가 빠지기 시작한 것은 알아채지 못했다. 10:11 에 VM 을 지우는 대기열이 쌓인다는 알림이 울렸다. 이 알림은 임계값에 닿을 때 한 번만 알리게 잘못 설정돼 있었고 온콜을 호출하지 않았다. 엔지니어들은 13:00 에 작업 시작 지연 호출을 받고서야 본격적으로 조사를 시작했다.
- 조치
- 14:13 에 Linux machine 작업이 작업 대기열에 아예 들어오지 못하게 손으로 막았다.
- 13:26 에 Google Cloud 에 쿼터 증설 티켓을 열었고 14:37 에 GCP 가 쿼터를 늘렸다. 시스템은 그 뒤에도 스스로 회복하지 못했다.
- 오래된 VM 을 손으로 지우는 계획을 세우고 지우기 시작했다.
- 17:22 에 자원을 비우고 멈춘 플랫폼을 다시 움직이려고 일부 워크플로를 취소했다.
- 16:25 에 VM 을 지우는 대기열에 컨슈머가 없음을 확인하고 대기열과의 연결을 되살리려고 VM 서비스 배포를 리셋했다. 대기열이 빠지기 시작했다.
- Burst Balance 가 바닥난 RDS 데이터베이스를 재부팅해도 효과가 없자 18:20 에 인스턴스를 키워 메모리와 CPU, burst balance 를 늘렸다. 데이터베이스가 돌아오는 동안 VM 프로비저닝 서비스를 줄여 연결이 몰리지 않게 했고, 19:15 에 한 번 더 키웠다.
- VM 프로비저닝 서비스를 줄이고, vm-create 대기열을 키우던 remote-docker 작업이 실행되지 않게 막아 부하를 덜었다.
- 21:00 에 새 VM 을 만들고 오래된 VM 을 지우는 파드를 모두 줄여 VM 을 만들고 지우지 못하는 순환을 끊었다.
- 21:57 에 remote-docker 작업을 프로비저닝 대기열에 넣지 않는 새 분배 백엔드를 배포했고, 22:21 에 프로비저닝 시스템을 줄여 대기열이 빠질 여유를 만들었다.
- 22:36 부터 두 시간 동안 프로비저닝과 분배 시스템의 구성 요소를 하나씩 안정성을 확인하며 다시 올렸고, 00:39 에 모두 돌아오자 완화용 코드 변경을 되돌렸다.
- 후속 조치
- VM 프로비저닝이 부하 변화에 더 잘 버티고 thundering herd 에서 회복하도록 고친다.
- VM 프로비저닝을 분리해 그 실패가 Docker 작업에 영향을 주지 않게 한다.
- RabbitMQ 와 운영 대기열들의 관측성을 점검하고 보강한다.
- 요청을 묶어 보내 GCP API 요청 한도에 걸리지 않게 한다.
- 오래 이어지는 장애에 맞게 장애 대응 방식을 보강한다.
이 2건에서 가장 많이 나오는 구성 요소: 데이터베이스, PostgreSQL vacuum. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.
원인별2
용량 한계1건
- 조직
업그레이드로 깨진 호환성1건
- 조직