Incident Library
  • 원인
  • 구성 요소
  • 증상
  • 기여 요인
  • 사례

사례4건

4건 중 1~4번째

  1. 증상

    22:47 UTC 부터 Buildkite 웹 화면, REST API, Agent API, 작업 큐, 알림이 한꺼번에 장애를 겪었다. 모든 고객이 웹 화면이나 REST API 로 새 빌드를 만들 수 없었고, 작업 배정이 늦어졌다.

    촉발

    22:44 UTC 에 애플리케이션을 배포하면서 파드가 한꺼번에 늘어 이미 떠 있던 노드의 여유 용량이 바닥났다. 같은 시각 알림 워커를 비롯한 백그라운드 워커들도 확장하려 했고, 노드 공급이 늦어지자 확장 지표가 그대로인 채 파드를 계속 더 요청했다. 이 워커들의 최대 레플리카 수는 평소보다 높게 잡혀 있었다.

    원인
    구성 요소
    기여 요인
    감지

    장애는 22:47 UTC 에 시작됐고, Buildkite 는 22:55 UTC 에 문제를 조사 중이라고 상태 페이지에 처음 알렸다. 23:05 UTC 에는 사이트 전체 장애를 조사 중이라고 올렸다. CoreDNS 쿼리 처리 시간은 클러스터가 커지면서 늘고 있었지만, 핵심 모니터링 쿼리의 결함과 쿼리량 모니터링 부족 때문에 장애 전에는 이를 알아채지 못했다.

    조치
    • 추가 애플리케이션 배포를 멈췄다.
    • CoreDNS 파드를 3개에서 12개로 늘렸다.
    • CoreDNS 파드마다 메모리 한도를 512 MiB 에서 2 GiB 로 올렸다.
    • CoreDNS 를 돌리는 시스템 노드 풀을 늘렸다.
    후속 조치
    • CoreDNS 파드를 3개에서 12개로 늘리고, 파드당 메모리 한도를 512 MiB 에서 2 GiB 로 올리고, 이 파드들을 돌릴 시스템 노드 풀을 넓혔다.
    • EKS 관리형 CoreDNS 오토스케일링을 켠다. 검증한 최소 레플리카 수를 정하고, 레플리카를 여러 노드와 가용 영역에 나눠 둘 만큼 용량을 확보한다.
    • CoreDNS 쿼리 처리 시간, 쿼리량, 고루틴 증가, 메모리 압박, OOM 재시작, 사용 가능한 레플리카 수에 직접 알림을 건다. 장기 추세도 용량 계획에 넣어 지켜본다.
    • 클러스터에 꼭 필요한 다른 서비스도 살핀다. 검증된 용량, 직접 알림, 장애 도메인 분산이 없는 서비스, 그리고 안전한 오토스케일링도 문서로 정한 고정 여유분도 없는 서비스를 찾아 고친다.
    교훈

    크기를 고정해 둔 CoreDNS 는 클러스터가 커지고 변경 속도가 빨라지면 한순간에 무너질 수 있다. 나중에 낮출 생각으로 높게 잡아 둔 워커의 최대 레플리카 수는 노드 공급이 늦어질 때 오토스케일링 폭주를 막지 못했다. 모니터링 쿼리에 결함이 있고 쿼리량을 제대로 감시하지 않아 장기 추세가 보이지 않았다. 클러스터 핵심 서비스는 급격한 저하와 여유분 감소를 둘 다 직접 감시해야 한다.

  2. 증상

    2023년 2월 1일 leap 클러스터의 prod 허브에서 노드가 대량으로 늘었고, hub 파드가 알 수 없는 이유로 재시작됐다. 사용자 지원 티켓도 들어왔다.

    촉발

    한 사용자의 dask-gateway 작업이 1분 사이에 dask-worker 노드를 100대쯤 늘렸고, Prometheus 는 노드 200대쯤의 지표 내보내기 대상을 수집하기 시작했다.

    원인
    구성 요소
    기여 요인
    감지

    2i2c Freshdesk에 들어온 사용자 지원 티켓 414로 드러났다. 이후 엔지니어가 Grafana와 클러스터의 노드, event를 살폈다. 조사 내용은 같은 날 UTC+1 기준 저녁 8시에서 9시 사이에 이슈에 정리됐다.

    후속 조치
    • basehub에서 hub와 proxy 파드의 CPU와 메모리 요청을 넉넉히 설정한다. 이슈 #2127이다.
    • Grafana의 OOMKiller 대시보드가 제대로 동작하게 고친다. 이슈 #2213이다.
    • LEAP 클라우드 인프라를 공유 노드 구성으로 옮긴다. 이슈 #2209다.
    • ingress-nginx와 Prometheus의 리소스 요청과 한도를 고친다. Prometheus 서버는 메모리 요청을 한도와 같게 맞춘다. 이슈 #2324다.
    • Prometheus가 daskhub 워커 파드를 수집하도록 넣은 설정이 필요한지 다시 본다. 이슈 #2366이다.
    교훈

    Prometheus 서버처럼 메모리를 많이 쓰는 파드가 요청보다 훨씬 많이 쓰면 같은 노드의 중요한 파드가 축출된다. 노드가 한꺼번에 100대 늘면 Prometheus가 수집할 대상도 함께 늘어난다. hub와 proxy처럼 중요한 파드는 실제 사용량보다 요청을 넉넉히 잡아야 축출과 CPU 부족을 피할 수 있다. 쿠버네티스 event는 60분이 지나면 사라지므로, OOMKill 여부를 나중에 확인하려면 따로 기록해 두어야 한다.

  3. 증상

    2021-06-21 08:05 UTC 부터 API 의 Apdex 가 나빠지고 Rails 대기열이 늘어나는 추세가 보였다. Apdex 는 목표 시간 안에 끝난 요청의 비율로 사용자 만족도를 나타내는 지표다. 08:43 에 ahmad 가 Slack 에서 장애를 선언했고, 09:01 에 API 디플로이먼트가 비정상 상태이고, 노드를 늘려 파드 용량을 더할 수도 없다는 것을 확인했다.

    촉발

    GitLab 이 운영하는 GCP us-east1 리전에서 SSD 재고가 바닥난 상태였는데, 사용자 트래픽이 늘어 API 서비스가 노드를 늘려야 했다.

    원인
    구성 요소
    기여 요인
    감지

    로그를 한참 뒤져서 찾았다. 클러스터 오토스케일러 오류는 일부 노드가 백오프 상태라 확장할 수 없다고만 했고, 인스턴스 그룹 수준 오류도 ZONE_RESOURCE_POOL_EXHAUSTED 뿐이어서 어떤 자원이 바닥났는지 알 수 없었다. 결국 GCP 지원팀이 SSD 재고 부족을 알려 주었다. 탐지까지 22시간이 걸렸고, 팀은 자원 가용성 알림이 있었다면 탐지와 진단을 앞당길 수 있었다고 보았다.

    조치
    • 09:55 에 pd-standard 디스크를 쓰는 노드 풀을 하나 더 만들었다.
    • 10:37 에 새 노드 풀이 늘어나지 않자 API 부담을 덜려고 이 노드 풀을 세 존 모두에서 손으로 늘렸다.
    • 13:42 에 배포가 막혀 있고 다른 워크로드도 같은 영향을 받고 있어서 pd-standard 디스크를 쓰는 새 노드 풀들을 올리기로 했다.
    • 18:16 에 canary 시험에서 클러스터 오토스케일러가 새 노드 풀과 함께 동작하지 않자 프로덕션 배포를 막는다고 공지하고, 오토스케일러 문제로 Google 에 지원 케이스를 열었다.
    • 18:26 에 남은 워크로드의 노드 풀과 nodeSelector 를 바꾸는 인프라 작업을 시작했다.
    • pd-standard 노드 풀 위주로 하루 동안 운영하며 문제가 없는 것을 확인한 뒤 SSD 노드 풀을 정리해 없앴다.
    후속 조치
    • 쿠버네티스 서비스를 pd-standard 디스크로 옮겼다.
    • 자원 고갈 오류를 지표로 수집한다.
    교훈

    장애를 수습하는 도중 다른 버그를 만나 대응 전체가 느려졌다. 팀에는 클라우드 자원 가용성을 감시할 수단도, 자원을 미리 예약해 둘 수단도 없었다. 워크로드는 pd-ssd 대신 pd-standard 디스크에서도 문제없이 도는 것으로 보였다.

  4. 증상

    Prelive 클러스터에 배포하던 개발자들이 #ask-platform 슬랙 채널에 배포가 실패한다고 알렸다. 16:00 에 첫 제보가 왔고 16:06 에 두 번째 제보가 왔다.

    촉발

    CentOS 저장소가 재구성되면서 container-selinux 패키지의 고정 다운로드 주소를 더는 쓸 수 없게 됐다. kops 는 nodeup 에 이 주소를 하드코딩해 두었고, docker-ce 를 실행하려면 이 패키지가 필요했다.

    원인
    구성 요소
    기여 요인
    감지

    팀은 개발자들이 배포가 실패한다며 #ask-platform 슬랙 채널에 도움을 요청하면서 장애를 알게 됐다. 조사를 시작하자 배포 실패의 원인이 클러스터 용량 부족이라는 것이 빠르게 드러났다.

    조치
    • Prelive 노드에서 패키지를 손으로 내려받아 부트스트랩을 끝내고 노드를 클러스터에 합류시켰다.
    • 클러스터 AMI 를 Amazon Linux 2 에서 Debian 으로 바꿔 Prelive 에서 확인한 뒤 모든 클러스터에 적용했다.
    후속 조치
    • 노드가 클러스터에 합류하지 못하는 상황을 알려 주는 알림을 만든다. cluster-autoscaler 가 이 정보를 갖고 있을 수 있다.
    • 노드 시작에 필요한 외부 의존성을 문서로 정리하고 줄일 방법을 찾는다.
    • kops 가 이 문제를 고치면 AMI 를 Amazon Linux 2 Minimal 로 되돌린다.
    • 클러스터 노드 문제 해결 문서를 보강해, 부트스트랩 중에 무슨 일이 일어나고 로그가 어디에 남는지 적는다.
    교훈

    kops 와 Jenkins 로 클러스터 변경을 적용하는 흐름은 잘 동작했다. 조사를 시작하자 배포 실패의 원인이 클러스터 용량 부족이라는 것이 빠르게 드러났다. 일부 오토스케일링 그룹의 워커 인스턴스 수와 쿠버네티스에 등록된 워커 노드 수가 오랫동안 달랐는데도 아무도 알아채지 못한 것은 잘못이었다. 문제가 이어지는 동안 운영 환경의 스팟 인스턴스가 대량으로 종료되지 않은 것과 업무 시간에 발견한 것은 운이 좋았다.

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

이 4건에서 가장 많이 나오는 구성 요소: 노드 풀, 클러스터 오토스케일러. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별3

용량 한계2건

  1. IL-0102 배포와 워커 오토스케일링 폭주가 겹치자 크기를 고정해 둔 CoreDNS 가 메모리 한도를 넘겨 재시작된 뒤 회복하지 못했고, Buildkite 사이트 전체가 약 30분 멈췄다.
  2. IL-0070 dask-gateway로 워커를 대량으로 띄우자 노드가 1분 만에 100대 늘었고, Prometheus가 메모리를 거의 다 쓰던 코어 노드에서 hub 파드를 비롯한 중요한 파드들이 축출되거나 재시작됐다
    2i2c2023

클라우드 제공자 장애1건

조직
  1. IL-0205 Google Cloud us-east1 의 SSD 영구 디스크 재고가 바닥나 GKE 클러스터 오토스케일러가 프로덕션 노드를 늘리지 못했고, API 디플로이먼트가 파드를 띄울 용량을 얻지 못했다.
    GitLab2021

의존성 장애1건

조직
  1. IL-0039 CentOS 저장소 재구성으로 kops nodeup 에 하드코딩된 container-selinux 패키지 주소가 깨져 새 워커 노드가 클러스터에 합류하지 못했다