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

사례5건

5건 중 1~5번째

  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. 증상

    2026-08-06 15:05 UTC 부터 GitHub Actions 워크플로 실행이 시작하지 못하거나 도중에 실패했고, 일부 Actions REST API 요청이 오류를 냈다. 일부 고객은 워크플로에서 예상하지 못한 rate limiting 을 겪었다.

    촉발

    이벤트를 처리하고 Actions 작업을 만드는 Actions 내부 서비스에 일상 배포를 했다. 배포로 파드가 교체되는 동안 남은 용량이 포화됐다.

    원인
    구성 요소
    기여 요인
    조치
    • 용량을 늘렸고, 처음 무너진 서비스들은 17:00 에 회복했다.
    • 시스템이 회복할 수 있게 웹훅으로 들어오는 작업을 줄였다. 한때 웹훅의 약 15% 만 처리했다.
    • 밀린 이벤트를 처리할 용량을 늘렸다.
    • 러너가 유효하지 않은 작업을 되풀이해 가져가려 하지 않도록 하는 변경을 배포했다.
    • 작업을 가져가지 못하던 자체 호스트 러너를 위한 수정을 배포하고 조금씩 켰다.
    • 완화 작업에 도움이 되도록 GitHub Enterprise Importer 마이그레이션을 멈췄다.
    • 웹훅으로 시작하는 Actions 워크플로를 전체 처리량으로 되돌렸다.
    • 완화 조치 하나 때문에 오프라인으로 남은 Actions Runner Controller 러너는 손으로 복구했고, 그 변경은 나중에 롤백했다.
    • 재시도도 취소도 되지 않는 작업을 고객이 정리할 수 있는 CLI 와 UI 방법을 GitHub 커뮤니티 토론 글로 공유했다.
    후속 조치
    • 영향받은 서비스의 배포 안전장치와 용량 안전장치를 개선한다.
    • 이번 장애에 앞서 나타난 조건을 잡아내도록 모니터링을 강화한다.
    • 장애가 나도 큐에 쌓인 작업과 러너 배정이 버티고 빨리 복구되도록 개선한다.
    • 다음 Actions Runner 와 Actions Runner Controller 릴리스에 자동 복구를 넣어 손으로 하는 조치가 필요 없게 한다.
    • 대규모 Actions 장애에서 연쇄 장애가 번질 위험을 줄이고 복구를 앞당기는 개선을 더 한다.
  3. 증상

    2026-03-04 에 IONOS Container Registry 고객이 컨테이너 이미지를 푸시하거나 풀할 때 504 Gateway Timeout 오류를 받았다. 레지스트리에 기대는 배포가 막혔다. 상태 페이지에는 09:23 UTC 에 레지스트리의 오류 수가 늘었고 고객이 이미지를 풀하지 못할 수 있다고 처음 올라왔다.

    촉발

    마이그레이션 중 일시적인 용량 제약 때문에 중요한 컨트롤 플레인 구성 요소 둘이 같은 프록시 인스턴스에 놓였다. 직접적인 계기는 그 프록시가 동시 연결 한도에 닿아 새 연결을 받지 않은 것이었다.

    원인
    구성 요소
    기여 요인
    조치
    • 12:22 UTC 에 쿠버네티스 팀이 쿠버네티스 컨트롤 플레인 구성 요소 하나의 버전을 롤백하는 완화책을 배포했다.
    • 프록시 용량을 더 마련했다.
    • 영향받은 컨트롤 플레인 구성 요소를 서로 다른 프록시 인스턴스로 옮겨 부하를 고르게 되돌렸고, 504 오류가 끝났다.
    후속 조치
    • 노드마다 전용 로컬 프록시를 쓰도록 레지스트리와 쿠버네티스 API 사이의 연결을 다시 설계해 공유 프록시 병목을 없앤다. 운영 적용은 2026년 2분기로 잡았다.
    • 프록시 연결 사용률이 한도에 다가가기 전에 경고가 울리도록 알림 기준을 조정한다. 2026년 2분기에 끝낼 예정이다.
    • 인프라 클러스터를 더 배포하고 기존 레지스트리를 다시 나눠, 어느 클러스터도 안전한 운영 용량을 넘지 않게 한다. 사용량이 늘면 자동화가 부하를 계속 고르게 맞춘다.
  4. 증상

    kube-prometheus-stack 헬름 차트를 업그레이드하는 중에 여러 파드가 Ready 가 되지 않았다. 그중 prometheus-prometheus-operator-prometheus-0 파드는 3/4 Running 상태였고 최근에 OOMKilled 로 종료된 기록이 있었다.

    촉발

    kube-prometheus-stack 헬름 차트를 업그레이드하던 중 Prometheus 가 시작하면서 WAL 을 재생했고, 이 과정에서 메모리 사용량이 메모리 제한을 넘었다.

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

    팀은 kube-prometheus-stack 헬름 차트를 업그레이드하던 중 Prometheus 파드를 포함한 여러 파드가 Ready 가 되지 않는 것을 보았다. kubectl describe pod 와 Prometheus 로그로 OOMKilled 를 확인했다.

    조치
    • Prometheus 파드에 kubectl exec 로 들어가 promtool tsdb analyze . 를 실행해 haproxy_server_http_responses_total 처럼 카디널리티가 높은 지표를 찾았다.
    후속 조치
    • WAL 재생 중 메모리 오버헤드가 10% 에서 15% 정도의 허용 범위 안에 있는지 확인하고, Prometheus 를 메모리 제한에 가깝게 운영하지 않는다.
    • Prometheus 의 저장, 스크레이프, remote write 설정을 정기적으로 최적화하고, 최적화가 들어간 새 릴리스로 업그레이드한다.
    • OOM 크래시 루프에서 자동으로 복구하는 장치를 만든다. 예를 들어 OOM 이벤트가 나면 WAL 을 자동으로 지운다.
    • 메모리 사용량이 일정 기준을 넘으면 스크레이프를 멈추는 강제 스크레이프 제한을 둔다.
    교훈

    Prometheus 를 메모리 제한에 가깝게 운영하면 WAL 재생 중의 작은 오버헤드로도 OOM 이 난다. 가비지 컬렉션은 들쭉날쭉하고 카디널리티나 쿼리는 갑자기 늘 수 있으므로 메모리에 여유를 둔다. Prometheus 메모리 문제의 상당 부분은 카디널리티에서 온다. Prometheus 가 떠 있지 않을 때는 promtool tsdb analyze 로 카디널리티가 높은 지표를 찾는다. 메모리 제한만 올려서는 답이 되지 않았다. 메모리가 치솟는 것은 재생 단계뿐이었기 때문이다.

  5. 증상

    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 여부를 나중에 확인하려면 따로 기록해 두어야 한다.

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

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

원인별1