IL-0378 Cloudflare · 2025-03-21database
Cloudflare R2 객체 스토리지에서 1시간 7분 동안 쓰기가 모두 실패하고 읽기가 전 세계에서 약 35% 실패했다
R2 Gateway 서비스는 R2 의 API 프런트엔드이고, ID 와 키 쌍으로 된 자격 증명으로 스토리지 인프라에 인증한다. R2 엔지니어링 팀은 이 자격 증명을 정기적으로 교체한다. 2025년 3월 21일 19:49 UTC 에 팀은 교체를 시작해 새 자격 증명을 만들었다. 20:19 UTC 에 wrangler secret put 으로 새 비밀 값을 넣고 wrangler deploy 로 R2 Gateway 서비스를 배포했다. 두 명령 모두 --env 인자를 빠뜨렸고, 이 명령들은 --env 가 없으면 기본 환경을 쓴다. 그래서 새 자격 증명은 운영 환경 Worker 가 아니라 기본 환경 Worker 에 들어갔지만, 팀은 운영 Worker 가 갱신됐다고 믿었다. 20:37 UTC 에 교체를 마무리하려고 스토리지 인프라에서 옛 자격 증명을 지웠다. 운영 R2 Gateway Worker 는 여전히 옛 자격 증명을 쓰고 있었으므로 스토리지 백엔드에 인증하지 못하게 됐다.
삭제가 스토리지 인프라에 퍼지는 데 시간이 걸려서 영향은 21:38 UTC 에 천천히 시작됐다. 21:45 UTC 에 가용성 알림이 울렸고, 21:50 UTC 에 내부 장애를 선언했고, 22:05 UTC 에 공개 상태 페이지를 올렸다. 팀은 처음에 새 자격 증명이 퍼지는 과정에 회귀가 생겼다고 의심해 자격 증명을 다시 만들었다. 그다음 새 자격 증명을 게이트웨이에 다시 배포했지만, 이때도 환경 인자를 빠뜨려 운영이 아닌 Worker 에 배포했다. 22:36 UTC 에 운영 Worker 의 배포 이력을 보다가 자격 증명이 운영이 아닌 Worker 에 들어갔다는 것을 찾았다. 22:45 UTC 에 올바른 운영 Worker 에 자격 증명을 배포하자 가용성이 바로 돌아왔고, 22:54 UTC 에 해결로 닫았다.
장애 동안 R2 의 쓰기는 100%, 읽기는 전 세계에서 약 35% 실패했다. 스토리지 앞에 있는 중간 캐시가 계속 요청을 처리해서 읽기 피해가 크게 줄었다. Billing, Cache Reserve, Email Security, Images, Key Transparency Auditor, Log Delivery, Stream, Vectorize 도 영향을 받았다. 데이터 손실이나 손상은 없었고, 성공 HTTP 상태 코드를 받은 업로드와 변경은 모두 저장됐다.
- 심각도
- –
- 영향 범위
- R2 object writes (100% failed) and object reads (about 35% failed globally), and services that use R2: Billing invoices, Cache Reserve, Email Security metrics, Images, Key Transparency Auditor, Log Delivery, Stream and Vectorize
- 영향 사용자
- All customers using Cloudflare R2
- 지역
- Global
- 감지까지
- 7m
- 복구까지
- 1h 7m
증상
21:45 UTC 에 R2 전역 가용성 알림이 울렸다. 알림은 오류 예산 소진율 2% 를 가리켰고, R2 의 읽기와 쓰기 가용성 지표가 조금씩 계속 내려가고 있었다.
가용성 지표는 21:38 UTC 부터 나빠지기 시작했다. 스토리지 인프라에서 옛 자격 증명을 지운 것이 퍼지는 데 시간이 걸려서 지표는 한꺼번에 떨어지지 않고 서서히 내려갔다. 그래서 처음에는 문제가 바로 눈에 띄지 않았다.
객체 쓰기는 100% 실패했고, 객체 읽기는 전 세계에서 약 35% 실패했다. head 와 list 같은 메타데이터만 쓰는 작업은 영향을 받지 않았다. 사용자 지정 도메인으로 공개 객체를 읽는 고객은 캐시된 객체 읽기가 성공해서 오류율이 더 낮았다.
R2 에 기대는 다른 서비스도 실패했다. Images 와 Stream 은 업로드가 모두 실패했고, Stream Live 는 내려갔다. Vectorize 는 insert 와 upsert 가 모두 실패했다. Log Delivery 는 로그 처리가 최대 70분 늦어졌고, Cache Reserve 고객의 오리진으로 가는 요청이 늘었다.
R2 엔지니어링 팀은 가용성이 서서히 떨어지는 것을 보고 스토리지 인프라에서 새 자격 증명이 퍼지는 과정에 회귀가 생겼다고 의심했다. 22:15 UTC 에 다시 퍼지게 하려고 스토리지 인프라용 자격 증명을 새로 만들었지만 22:20 UTC 까지 지표는 나아지지 않았다.
22:30 UTC 에 팀은 게이트웨이에 넣은 자격 증명이 문제인지 확인하려고 새 자격 증명을 R2 Gateway Worker 에 배포했다. 처음 교체 때처럼 이번에도 wrangler secret put 과 wrangler deploy 에 환경 인자를 빠뜨려서, 새 자격 증명은 운영이 아닌 Worker 에 배포됐다.
원인
- 촉발
- 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 서비스가 실제로 어떤 토큰을 쓰는지 직접 확인했어야 했다고 적었다.
출처
관련 사례
같은 원인 · 공통 오브젝트 스토리지
IL-0534US-EAST-1 의 Amazon S3 가 몇 시간 동안 요청을 처리하지 못했고 S3 에 기대는 AWS 서비스도 함께 멈췄다Amazon Web Services · 2017같은 원인 · 공통 오브젝트 스토리지
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0378
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0378/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.