IL-0102 Buildkite · 2026-08-25kubernetesaws
Buildkite 는 넉 달째 운영 워크로드를 AWS ECS 에서 AWS EKS 클러스터로 옮기고 있었고, 그동안 클러스터는 꾸준히 커졌다. 이 클러스터의 서비스들은 데이터베이스와 큐 같은 구성 요소의 위치를 CoreDNS 로 찾는다. CoreDNS 는 크기가 고정돼 있어 클러스터 크기나 변경 속도에 맞춰 늘어나지 않았다. Buildkite 는 얼마 전 시간에 민감한 알림 작업을 범용 백그라운드 워커 풀에서 새 저지연 워커 풀로 옮기면서, 두 풀 모두에 원래 공용 풀과 같은 높은 maxReplica 값을 주었다. 이 값은 나중에 낮출 생각이었다.
22:44 UTC 배포로 파드가 급증하자 클러스터가 확장을 시작했고, 기존 노드의 여유 용량이 바닥나 다른 서비스의 오토스케일링이 제때 되지 않았다. 노드를 기다리는 동안 확장 지표가 바뀌지 않으니 워커들은 파드를 더 요청했고, 높게 잡아 둔 최대치가 이 폭주를 막지 못했다. 배포와 오토스케일링 폭주가 겹쳐 애플리케이션, 네트워크 엔드포인트, 노드가 유난히 빠르게 바뀌었고, 그 결과 CoreDNS 에 갑자기 부하가 몰렸다.
CoreDNS 쿼리 처리 시간이 약 780ms 까지 늘면서 대기 요청이 메모리에 쌓였고, 파드 세 개가 모두 메모리 한도를 넘어 재시작됐다. 재시작 뒤에도 수요와 DNS 재시도가 이어져 CoreDNS 는 회복하지 못했다. CoreDNS 가 멈추자 모든 고객의 API, 작업 배정, 알림이 실패했고, 재시도와 밀린 작업이 복구 중 부하를 더 키웠다. 팀은 배포를 멈추고 CoreDNS 를 늘렸다. 새 빌드 처리는 23:10 UTC 에 다시 시작됐다. 새 CoreDNS 파드가 23:12 UTC 에 서비스에 들어오자 DNS 오류가 빠르게 줄었고, 밀린 작업은 23:16 UTC 까지 모두 처리됐다.
사후 분석에서 CoreDNS 모니터링의 결함이 드러났다. 핵심 모니터링 쿼리 하나에 결함이 있어 클러스터 크기와 함께 늘던 쿼리 처리 시간이 보이지 않았고, DNS 쿼리량은 충분히 모니터링되지 않았다. 그래서 계획해 둔 CoreDNS 오토스케일링 도입의 우선순위가 제대로 잡히지 않았다.
22:47 UTC 부터 Buildkite 웹 화면, REST API, Agent API, 작업 큐, 알림이 한꺼번에 장애를 겪었다. 모든 고객이 웹 화면이나 REST API 로 새 빌드를 만들 수 없었고, 작업 배정이 늦어졌다.
소스 관리 서비스에서 오는 웹훅은 계속 받았지만 처리가 밀렸다. 장애가 시작될 때 이미 돌고 있던 빌드 일부는 서비스가 회복될 때까지 멈춰 있었다. EKS 클러스터 안의 PgBouncer 를 거쳐 데이터베이스에 붙던 일부 고객은 웹 화면과 웹훅 수신에서 오류 응답을 받았고, 이런 오류는 전체 요청의 1.5% 미만이었다.
CoreDNS 에서는 처리를 마친 쿼리 수가 그대로였지만 쿼리 처리 시간이 1ms 미만에서 약 780ms 로 늘었다. 처리되지 못한 요청이 메모리에 쌓이면서 원래 있던 CoreDNS 파드 세 개가 모두 메모리 한도를 넘었고, 쿠버네티스가 이 파드들을 재시작했다. 재시작 뒤에도 요청과 DNS 재시도가 계속 몰려 CoreDNS 는 회복하지 못했다.
징후는 장애 전부터 있었다. CoreDNS 쿼리 처리 시간은 클러스터가 커지면서 계속 늘고 있었고, DNS 쿼리량도 EKS 로 워크로드를 옮길수록 늘고 있었다. 핵심 모니터링 쿼리에 결함이 있어 처리 시간이 느는 것이 보이지 않았고, 쿼리량은 제대로 모니터링되지 않았다. 클라이언트 쪽 지연 증가는 최근 애플리케이션 성능 개선에 묻혀 눈에 띄지 않았다.
원인 ? 용량 한계
장애는 22:47 UTC 에 시작됐고, Buildkite 는 22:55 UTC 에 문제를 조사 중이라고 상태 페이지에 처음 알렸다. 23:05 UTC 에는 사이트 전체 장애를 조사 중이라고 올렸다. CoreDNS 쿼리 처리 시간은 클러스터가 커지면서 늘고 있었지만, 핵심 모니터링 쿼리의 결함과 쿼리량 모니터링 부족 때문에 장애 전에는 이를 알아채지 못했다.
크기를 고정해 둔 CoreDNS 는 클러스터가 커지고 변경 속도가 빨라지면 한순간에 무너질 수 있다. 나중에 낮출 생각으로 높게 잡아 둔 워커의 최대 레플리카 수는 노드 공급이 늦어질 때 오토스케일링 폭주를 막지 못했다. 모니터링 쿼리에 결함이 있고 쿼리량을 제대로 감시하지 않아 장기 추세가 보이지 않았다. 클러스터 핵심 서비스는 급격한 저하와 여유분 감소를 둘 다 직접 감시해야 한다.
같은 원인 · 공통 컨테이너 메모리 한도, CoreDNS, 노드 풀
같은 원인 · 공통 CoreDNS, 노드 풀
같은 원인 · 공통 CoreDNS, 노드 풀
같은 원인 · 공통 컨테이너 메모리 한도, 노드 풀
같은 원인 · 공통 수평 파드 오토스케일러, CoreDNS
같은 원인 · 공통 컨테이너 메모리 한도, 노드 풀
같은 원인 · 공통 컨테이너 메모리 한도, 노드 풀
같은 원인 · 공통 컨테이너 메모리 한도, CoreDNS
같은 원인 · 공통 수평 파드 오토스케일러
같은 원인 · 공통 노드 풀
같은 원인 · 공통 CoreDNS
같은 원인 · 공통 CoreDNS
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 노드 풀
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도