Incident Library

IL-0229 bunny.net · 2021-06-22networking

손상된 SmartEdge 데이터 파일을 받은 bunny.net 의 전 세계 DNS 서버가 크래시를 되풀이해 플랫폼 대부분이 2시간 넘게 멈췄다.

bunny.net 의 SmartEdge 라우팅 시스템은 많은 양의 데이터를 주기적으로 DNS 노드에 동기화하고, 이 큰 데이터베이스 파일을 Edge Storage 와 Bunny CDN 으로 전 세계에 나른다. bunny.net 은 메모리와 트래픽, 가비지 컬렉터 할당을 줄이려고 얼마 전 JSON 대신 BinaryPack 이라는 바이너리 직렬화 라이브러리를 쓰기 시작했다. 2021-06-22 UTC 8:25 에 최적화 데이터베이스의 다운로드 크기를 줄이는 업데이트가 손상된 파일을 Edge Storage 에 올렸다. DNS 서버는 데이터가 없어도 돌고 예외를 무시하도록 만들어져 있었다. 하지만 손상된 파일이 BinaryPack 에서 stack overflow 예외를 일으켰고, 이 예외는 예외 처리를 건너뛰고 프로세스를 종료시켰다. 몇 분 만에 전 세계에 있는 100대 가까운 DNS 서버가 거의 모두 죽었다. bunny.net 은 트래픽의 60% 넘게 잃었고, 750,000개가 넘는 웹사이트가 영향을 받았다.

팀은 SmartEdge 업데이트를 곧바로 롤백했다. 하지만 SmartEdge 와 배포 시스템이 기대는 Edge Storage 와 CDN 이 이미 무너져, DNS 서버는 수정본을 받지 못한 채 크래시를 되풀이했다. 8:45 에 SmartEdge 를 끄는 업데이트를 손으로 배포했지만, DNS 서버가 손상된 GeoDNS 데이터베이스를 내려받아 모든 요청이 작은 Madrid PoP 로 몰렸다. 서버 100대가 루프를 돌며 다시 시작하면서 중앙 API 도 크래시했다.

9:40 무렵 팀은 모든 요청을 가장 큰 리전인 Frankfurt 로 보내는 라우팅 업데이트를 DNS 서버 몇 대에 손으로 배포해 트래픽 일부를 되찾았다. 이어 자체 시스템을 아예 쓰지 않기로 하고 배포 시스템과 파일을 외부 클라우드 스토리지 서비스로 옮겼다. 10:15 에 배포 시스템과 DNS 소프트웨어를 새 스토리지에 연결해 배포했고, 10:30 에 트래픽이 돌아왔다. 하지만 서두르다 잘못된 GeoDNS 데이터베이스 버전을 배포해 요청이 여전히 Madrid 로 갔다. 10:45 에 모든 것을 다시 확인하고 데이터베이스를 동기화해 최신 파일 세트를 배포했다. SmartEdge 없이 캐시되지 않은 데이터를 많이 내보내느라 스토리지가 한계까지 몰렸다. 11:00 에 상황이 안정되기 시작했고, bunny.net 은 복구 모드로 서비스를 다시 열었다.

심각도
–
영향 범위
bunny.net DNS, CDN, storage, optimizer service, API, dashboard and logging; over 60% of traffic lost
영향 사용자
over 750,000 websites
지역
global
감지까지
10m
복구까지
2h 35m

증상

2021-06-22 UTC 8:25 에 업데이트를 내보내고 몇 분 만에 전 세계에 있는 100대 가까운 bunny.net DNS 서버가 거의 모두 죽었다. bunny.net 은 트래픽의 60% 넘게 잃었고, 수백 Gbit 의 처리량이 사라졌으며, 750,000개가 넘는 웹사이트가 영향을 받았다.

팀은 무슨 일인지 알아채는 데 시간이 걸렸다. 10분이 지나서야 DNS 서버가 다시 시작했다가 죽기를 되풀이하고 있고, 이 상태로는 되살릴 방법이 없다는 것을 알았다. DNS 서버는 데이터가 있든 없든 돌고 예외를 무시하도록 만들어져 있었다. 하지만 손상된 파일을 읽은 BinaryPack 직렬화 라이브러리가 stack overflow 예외를 일으켰고, 이 예외는 예외 처리를 건너뛰고 프로세스를 그대로 종료시켰다.

팀은 버튼 하나로 배포를 롤백할 수 있었고 SmartEdge 업데이트를 곧바로 모두 롤백했지만 이미 늦었다. SmartEdge 와 배포 시스템은 Edge Storage 와 Bunny CDN 으로 DNS 서버에 데이터를 나르는데, 이 CDN 용량 대부분이 이미 사라진 상태였다. DNS 서버는 스스로 다시 뜰 때마다 깨진 배포를 읽고 다시 크래시해 CDN 에서 수정본을 내려받지 못했다.

UTC 8:35 에는 서버 몇 대만 요청을 버티고 있었고, 트래픽 대부분을 잃어 100Gbit 까지 떨어졌다. 하루 중 트래픽이 가장 적은 시간대였다.

8:45 에 SmartEdge 를 끄는 업데이트를 손으로 배포하자 잠시 동작하는 것처럼 보였다. 하지만 CDN 장애 때문에 DNS 서버가 손상된 GeoDNS 데이터베이스를 내려받았고, 모든 요청이 가장 작은 PoP 가운데 하나인 Madrid 로 몰려 Madrid 가 금방 무너졌다. 100대의 서버가 루프를 돌며 다시 시작하자 중앙 API 가 크래시했고, 되살린 서버도 제대로 시작하지 못했다. 팀은 네트워킹을 다시 세우려고 여러 번 시도하다 포기했다.

장애는 DNS 에서 CDN, 스토리지, optimizer 서비스로 번졌다. 수백 대의 서버가 다시 올라오는 동안 API 와 대시보드가 크래시했고, 마지막에는 로깅 서비스도 크래시했다.

증상 컨테이너 재시작 반복DNS 조회 실패서비스 중단요청 오라우팅부하 불균형

원인

촉발
2021-06-22 UTC 8:25 에 최적화 데이터베이스의 다운로드 크기를 줄이려는 업데이트가 손상된 파일을 Edge Storage 에 올렸다. DNS 서버가 이 파일을 읽자 BinaryPack 직렬화 라이브러리가 stack overflow 예외를 일으켰고, 예외 처리를 건너뛴 채 DNS 프로세스가 종료됐다.

감지

팀은 무슨 일인지 알아채는 데 시간이 걸렸다. 업데이트 10분 뒤에야 DNS 서버가 다시 시작했다가 죽기를 되풀이하고 있고, 이 상태로는 되살릴 방법이 없다는 것을 알았다.

조치

후속 조치

교훈

bunny.net 은 내부 인프라의 핵심 부분까지 모든 시스템이 서로 기대도록 설계했다. 그 때문에 손상된 파일 하나가 여러 겹의 이중화를 무너뜨리고 복구할 길까지 막았다. 자체 인프라를 자기 생태계 안에 지으면 한 곳의 장애가 연쇄로 번질 수 있다. 업데이트는 카나리 방식으로 잘게 배포하려 했지만, 중요하지 않다고 본 소프트웨어 하나가 여러 클러스터에 동시에 걸친 단일 장애 지점이 됐다. 급하게 고치는 동안 오타와 실수가 늘었고, 결국 침착하게 모든 것을 다시 확인한 뒤의 마지막 배포로 복구했다.

출처

관련 사례

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

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: DNS 서버와 레코드, CDN 과 엣지 네트워크, 오브젝트 스토리지. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.