그래프
사례2건
2건 중 1~2번째
- 증상
21:45 UTC 에 R2 전역 가용성 알림이 울렸다. 알림은 오류 예산 소진율 2% 를 가리켰고, R2 의 읽기와 쓰기 가용성 지표가 조금씩 계속 내려가고 있었다.
- 촉발
R2 엔지니어링 팀이 R2 Gateway 서비스의 스토리지 인프라 자격 증명을 교체하면서 wrangler secret put 과 wrangler deploy 에 --env 인자를 빠뜨렸다. 새 자격 증명은 운영 Worker 가 아니라 기본 환경 Worker 에 들어갔고, 그 뒤 스토리지 인프라에서 옛 자격 증명을 지웠다.
- 원인
- 구성 요소
- 기여 요인
- 감지
21:45 UTC 에 R2 전역 가용성 알림이 울렸다. 알림은 오류 예산 소진율 2% 를 가리켰고, R2 엔지니어링 팀은 운영 대시보드와 로그를 보기 시작했다.
- 조치
- 22:45 UTC 에 올바른 운영 R2 Gateway Worker 에 자격 증명을 배포했고, R2 가용성이 돌아왔다.
- 후속 조치
- R2 Gateway Worker 가 스토리지 인프라 인증에 쓰는 자격 증명 ID 의 끝자리를 로그 태그에 넣어, 어떤 자격 증명을 쓰는지 바로 확인할 수 있게 했다.
- 옛 토큰을 지우기 전에 새 토큰 ID 의 끝자리가 스토리지 인프라 로그와 맞는지 반드시 확인하도록 내부 절차를 바꿨다.
- 키 교체를 wrangler 명령을 손으로 치는 대신 핫픽스 배포 도구로만 하도록 했다. 이 도구는 환경 설정을 강제하고 다른 안전 검사도 한다.
- 변경을 적어도 두 사람이 확인한다는 관행을 관련 표준 운영 절차에 명시했다.
- 엔드포인트를 감시하는 기존 폐루프 상태 검사 시스템을 넓힌다. 이 시스템이 새 키를 시험하고, 그 상태를 알림 플랫폼으로 자동 보고하고, 게이트웨이 Worker 를 배포하기 전에 새 키가 전역으로 퍼졌는지 확인하게 한다.
- 분산 스토리지 엔드포인트의 문제를 빨리 가려내도록, 관측 플랫폼에 캐시를 거치지 않은 업스트림 성공률 화면을 더한다.
- 교훈
이번 장애는 사람의 실수로 일어났고, R2 Gateway Worker 가 어떤 자격 증명으로 스토리지 인프라에 인증하는지 볼 수 없어서 더 길어졌다. Cloudflare 는 옛 자격 증명을 지운 뒤 가용성 지표에 기대지 말고, R2 Gateway 서비스가 실제로 어떤 토큰을 쓰는지 직접 확인했어야 했다고 적었다.
- 증상
처리되지 않은 잡이 밀리는지 감시하던 DataDog 에서 알림이 울렸다. 대량의 잡이 처리되지 못하고 쌓여 있었다.
- 촉발
Redash 에서 reader 인스턴스로 보내야 할 데이터 분석용 쿼리가, 데이터 소스 등록 때 잘못 설정한 클러스터 엔드포인트를 거쳐 writer 인스턴스에서 오래 실행됐다.
- 원인
- 구성 요소
- 기여 요인
- 감지
처리되지 않은 잡이 밀리는지 감시하던 DataDog 알림이 대량의 잡이 쌓였을 때 울렸다.
- 조치
- Redash 의 데이터 소스 설정 실수를 고쳐 reader 엔드포인트를 가리키게 했다.
- VACUUM 을 막는 쿼리라고 확신한 뒤 pg_terminate_backend 로 그 쿼리의 프로세스를 강제로 끝냈다.
- 프로세스가 끝난 것을 확인하고 VACUUM 을 다시 수동으로 실행해 dead tuples 를 대량으로 치웠다.
- 후속 조치
- Redash 컨테이너의 /etc/hosts 에서 writer 엔드포인트 호스트 이름을 테스트용 무효 주소인 TEST-NET-1 의 IP 주소로 지정해, Redash 에 writer 엔드포인트를 잘못 설정해도 실제로는 접속하지 못하게 한다.
- PostgreSQL 사용자의 statement_timeout 을 알맞게 설정해 오래 걸리는 쿼리를 자동으로 멈춰 재발을 막는다.
- 늘어날 잡을 견디도록 qg 를 개선하거나, SELECT FOR UPDATE SKIP LOCKED 로 락을 잡는 river 같은 기술을 쓰는 것을 검토한다.
- 교훈
que_jobs 와 전혀 관계없는 쿼리라도 같은 DB 인스턴스에서 오래 실행되면 que_jobs 의 dead tuples 를 치우지 못하게 막아 테이블이 계속 커지고, qg 의 디큐 성능 저하와 DB 부하 상승으로 이어진다. 글쓴이는 이것을 오래 걸리는 쿼리 때문에 VACUUM 이 효과를 내지 못하는 PostgreSQL 운영의 전형적인 경우로 보았다. 이런 상황에서 어디를 확인해야 하는지를 정해 두고 습관으로 만들어야 한다고 느꼈다. 현재 qg 가 쓰는 advisory lock 과 Recursive CTE 는 dead tuples 의 영향을 받기 쉬운 설계다.
이 2건에서 가장 많이 나오는 구성 요소: PostgreSQL vacuum, 데이터베이스. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.