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

사례3건

3건 중 1~3번째

  1. 증상

    일부 Buildkite 고객에게 알림 전달, 빌드 디스패치, 지표 서비스의 지연이 커졌다. 상태 페이지에는 2026년 5월 20일 16:40 UTC 에 모든 고객의 알림 지연을 조사한다는 글이 올라왔다.

    촉발

    오토스케일링으로 Prometheus 가 추적하는 파드 수가 늘었고, 그만큼 Prometheus 서버의 메모리 요구량이 커졌다.

    원인
    구성 요소
    기여 요인
    조치
    • 당번 팀이 미리 마련한 문서를 따라 영향을 받은 서비스의 부하를 Fargate 로 되돌렸고, 대부분의 고객이 16:49 부터 완전히 회복됐다.
    • 지연 동안 백로그가 크게 쌓인 일부 고객의 처리 규모를 손으로 더 늘렸고, 17:33 에 모든 고객이 완전히 회복됐다.
    후속 조치
    • 시스템 노드의 크기를 키웠다.
    • Prometheus 서버가 더 많은 제품 부하를 감당하도록 requests 와 limits 를 높였다.
    • 새 EKS 리소스 전부를 검토해 빠진 requests 와 limits 를 채웠다. EKS 가 뜻하지 않은 리소스 경합을 막으려면 이 정보가 모두 있어야 한다.
    • 다음 장애에서 근본 원인을 빨리 찾도록 EKS 파드와 노드 상태의 관측 수단과 모니터를 더했다.
  2. 증상

    어느 월요일 아침, 엔지니어가 쿠버네티스 클러스터 경고를 보려고 Prometheus 대시보드를 열었는데 접속되지 않았다. Prometheus 서버 파드는 CrashLoopBackOff 상태였다.

    촉발

    Prometheus 가 시작한 지 5분 만에 시계열 수가 2,162,256 까지 급증해 메모리 8GB 호스트의 메모리를 거의 다 썼다.

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

    월요일 아침 엔지니어가 클러스터 경고를 확인하려고 Prometheus 대시보드를 열었다가 접속되지 않는 것을 보고 알았다.

    조치
    • Prometheus configMap 에서 불필요한 설정 대부분을 지워 컨테이너가 더 이상 비정상 종료되지 않게 했다.
    후속 조치
    • Prometheus 파드의 requests 와 limits 를 알맞게 고친다. 지금 문제를 완전히 풀지는 못해도 비슷한 문제를 막아 해결 시간을 줄인다.
    • 불필요한 수집 지표를 줄이도록 수집 대상이나 수집 간격을 조정한다.
    • Prometheus 에 필요한 메모리를 예측해 새 호스트를 마련하고 deploy-topology: Prometheus 같은 노드 레이블을 붙인 뒤, 매니페스트에 nodeSelector 를 넣어 Prometheus 파드가 그 호스트에만 배치되게 한다.
    교훈

    원인은 둘이었다. 첫째, Prometheus 파드의 requests 와 limits 를 잘못 잡아 Prometheus 서버 컨테이너가 높은 oom_score_adj 를 받았다. 둘째, 대규모 클러스터에서 Prometheus 가 쓸 메모리를 미리 예측하지 않았다. 쿠버네티스에서 파드의 QoS 클래스는 메모리가 모자랄 때 어느 컨테이너가 먼저 죽는지에 영향을 준다. 커널의 OOM Killer 는 메모리 사용량과 oom_score_adj 로 점수를 매기고, kubelet 은 QoS 클래스에 따라 oom_score_adj 를 정한다.

  3. 증상

    팀은 여러 서비스가 이상하게 동작한다는 보고를 받았다. 가끔 오류 페이지가 뜨고, 응답이 느리고, 타임아웃이 났다.

    촉발

    장애 직전에 팀원 한 명이 ElastAlert 에 새 알림 규칙을 명령줄로 배포했다. Cloudfront-* 인덱스에 일정 시간 새 문서가 들어오지 않으면 울리는 규칙이었다.

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

    여러 서비스에서 오류 페이지, 느린 응답, 타임아웃이 난다는 보고가 팀에 들어왔다. 알림은 하나도 울리지 않았다. 팀은 Prometheus 와 Grafana 가 안정적인 노드로 옮겨 간 뒤 파드 메모리 사용량 대시보드에서 원인을 찾았다.

    조치
    • NotReady 노드를 하나씩 종료해 오토스케일링 그룹이 새 노드를 띄우게 했다. 새 노드도 곧 NotReady 가 되어 이것만으로는 풀리지 않았다.
    • Prometheus 와 Grafana 가 안정적인 노드에 다시 스케줄된 뒤 파드 메모리 대시보드를 보고 ElastAlert 파드가 원인임을 찾아냈다.
    • 원인인 ElastAlert 문제를 고쳤다.
    후속 조치
    • CPU, 메모리, 디스크 공간 같은 자원 사용량에 알림 규칙을 정의한다.
    • 여러 출처를 함께 쓰는 알림 전략을 계속 연구한다. 지금은 Elasticsearch, 아직 설정하지 않은 Prometheus alertmanager, APM 용 New Relic 이 있다.
    • 지표를 클러스터 밖으로 내보내고 Grafana 도 클러스터 밖으로 옮기는 방안을 검토한다. 옮길 곳은 EC2 나 별도 쿠버네티스 클러스터가 될 수 있다.
    • 중요한 지표를 ELK 에서 시각화하거나 Prometheus 와 Grafana 의 가용성을 높인다. 지표 전략도 개선한다.
    • ElastAlert 의 자원 한도를 Helm values 로 지정한다.
    • 네임스페이스에 메모리 요청값의 기본값과 한도를 설정한다.
    • 고객 대면 워크로드를 빌드, 로깅, 모니터링 워크로드와 떼어 놓는다. 먼저 운영 클러스터 안의 전용 노드 그룹으로 옮기고, 경험에 따라 별도 도구 클러스터도 검토한다.
    • 모든 배포를 Jenkins 파이프라인 같은 자동화로 하고, 새 버전 배포에 GitOps 방식을 검토한다.
    • 배포 뒤 스모크 테스트 단계가 있는 파이프라인으로 배포한다.
    • 쿠버네티스와 클라우드 인프라 작업을 팀 스프린트에 넣어 모든 팀원이 경험 많은 팀원과 짝을 지어 맡게 하고, 주제별 심화 워크숍을 연다.
    교훈

    근본 원인 하나만 탓하는 포스트모템은 장애로 이어진 문제의 15% 정도만 다룬다. 이번에도 ElastAlert 를 고친 것은 일부일 뿐이었다. 알림이 없었고, 모니터링이 같은 클러스터 안에 있었고, Helm 차트의 자원 한도에 기본값이 없었다. 운영 도구와 고객 워크로드가 자원을 나눠 썼고, 손으로 한 배포를 팀이 몰랐고, 스모크 테스트가 없었고, 운영 지식이 일부에게만 있었다. 이렇게 배우려면 장애 건수나 해결 시간만 보지 않고 비난 없는 포스트모템을 허용하는 문화가 필요하다.

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

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

원인별2