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

사례19건

19건 중 2~6번째

  1. 증상

    2025년 3월 3일 14:15:34부터 홈랩 쿠버네티스에 올린 서비스에 접속되지 않았다. 운영자가 서비스에 들어가려다 직접 알아챘고, 알아채기까지 3시간이 걸렸다.

    촉발

    정전 때문에 마스터 노드가 재부팅됐다.

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

    운영자가 서비스에 접속하려다 직접 알아챘다. 자동 알림이 없어서 알아채기까지 3시간이 걸렸다.

    조치
    • 원격 접속이 되지 않아 모니터를 연결해 부팅 로그를 보고 커널 패닉을 확인했다.
    • 이전 커널 버전으로 부팅해 시스템을 되살렸다.
    • sudo apt-get remove --purge '^nvidia-.*' 로 망가진 패키지를 지우고 sudo dpkg --configure -a 로 패키지 설정 문제를 고쳤다.
    • dpkg -l | grep -v ^ii 로 남은 망가진 패키지를 찾아 sudo apt-get remove --purge <package_name> 으로 하나씩 지웠다.
    • sudo apt-get install -f 로 빠진 의존성을 채우고 sudo apt-get install --reinstall linux-headers-$(uname -r) 로 커널 헤더를 다시 설치했다.
    • 머신을 재부팅해 커널 패닉이 사라진 것을 확인했다.
    후속 조치
    • GPU 드라이버 설치가 완전히 성공했는지 확인하고, 오류가 나면 바로 변경을 되돌린다.
    • 단일 장애 지점을 없애도록 클러스터를 고가용성 구성으로 옮긴다.
    • 고가용성 구성에서 Kube-API 를 로드 밸런서 뒤에 둔다.
    • 장애를 기록하고 해결 과정을 추적할 티켓 시스템을 만든다.
    • 미리 정해 둔 문제 해결 절차를 만들어 홈랩 장애 대응 시간을 줄인다.
    • Prometheus 와 Grafana 같은 인프라 모니터링을 넣어 문제를 미리 잡는다.
    • 주요 서비스에 HTTP, TCP 검사를 거는 블랙박스 모니터링을 넣어 쿠버네티스 클러스터 밖에서도 장애를 잡는다.
    교훈

    드라이버 빌드 실패를 그대로 두면 몇 주 뒤 재부팅 때 터질 수 있다. 자동 알림이 없어서 발견과 복구가 늦었다. 마스터 노드가 하나뿐이라 노드 하나의 고장이 클러스터 전체 장애가 됐다. 원인을 찾은 뒤에는 비교적 간단히 고쳤고, 데이터 손실은 없었다.

  2. 증상

    14:27 에 사용자가 #ask-cloud-platform 채널로 Kibana 에 13:45 부터 로그가 들어오지 않는다고 알려 왔다.

    촉발

    OpenSearch 의 디스크 공간이 바닥나 인덱스 쓰기가 막혔다.

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

    원문은 처음 감지된 시각을 12:10 으로 적었다. 이때 cp-live-app-logs 에서 ClusterIndexWritesBlocked 경보가 시작됐다. 팀이 실제로 문제를 알게 된 것은 14:27 에 사용자가 #ask-cloud-platform 채널로 Kibana 에 13:45 부터 로그가 들어오지 않는다고 알려 왔을 때였다.

    조치
    • 14:59 에 fluent-bit 컨테이너를 모두 rollout restart 했다. 로그가 잠깐 일부 흘렀지만 같은 오류가 다시 났다.
    • OpenSearch 디스크 공간을 8000 에서 12000 으로 늘렸다.
    • 근본 원인을 조사하는 동안 임시 조치로 fluent-bit 가 OpenSearch 로 로그를 보내지 않게 설정했다.
    후속 조치
    • OpenSearch 와 Elasticsearch 의 인덱스 날짜 문제를 살핀다.
    • Elasticsearch 와 OpenSearch 에 우선순위 높은 경보를 만든다.
    • OpenSearch 를 live 로깅에 다시 넣는다.
    • fluent-bit 의 “failed to flush chunk” 오류를 조사한다.
  3. 증상

    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 로 카디널리티가 높은 지표를 찾는다. 메모리 제한만 올려서는 답이 되지 않았다. 메모리가 치솟는 것은 재생 단계뿐이었기 때문이다.

  4. 증상

    2024-04-15 12:32 에 계획된 Prometheus 변경을 적용한 뒤 Prometheus 를 쓸 수 없게 되었다. 팀은 prometheus 파드가 여러 번 재시작한 것을 보았다. 그동안 Cloud Platform 에는 모니터링이 없었고 지표가 빠졌다.

    촉발

    계획된 변경으로 Prometheus 를 재시작했는데 그때 WAL 수가 평소보다 많아, WAL 다시 읽기가 startupProbe 기본 허용 시간인 15분 안에 끝나지 않았다.

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

    계획된 Prometheus 변경 뒤 팀이 prometheus 파드가 여러 번 재시작한 것을 보고 알았다. 처음 감지한 시각은 2024-04-15 12:32 였다.

    조치
    • startupProbe 허용 시간을 기본값 15분에서 30분으로 늘려 WAL 다시 읽기가 끝날 때까지 기다리게 했다.
    후속 조치
    • 팀은 계획된 Prometheus 재시작을 WAL 수가 적을 때 해서 재시작 시간을 줄이는 방안을 논의했다.
    • Prometheus 의 기본 CPU 와 메모리 요청값을 최대 사용량에 맞춰 설정했다.
    • 운영 환경의 WAL 수를 재현하는 테스트 환경을 만든다.
    • memory-snapshot-on-shutdown 과 auto-gomaxprocs 기능 플래그를 검토한다.
    • WAL 파일을 다른 위치의 원격 저장소에 두는 방법을 검토한다.
    • 운영과 같은 구성의 블루그린 Prometheus 를 만들어 운영에 적용하기 전에 변경을 시험하는 방안을 알아본다.
    • Amazon Managed Prometheus 를 간단히 조사한다.
  5. 증상

    2024-03-13 10:01 UTC 에 쿠버네티스 노드 하나가 NotReady 상태가 됐다. 그때 노드에 잡힌 requests 는 CPU 78%, 메모리 82% 였다. 10:03 에 Slack 으로 알림이 왔고, 10:05 에 알림을 보고 조사를 시작했다.

    촉발

    Hangfire 로 작업을 실행하는 개발 컨테이너가 Grafana Agent 가 메모리를 많이 쓰고 있던 노드에 배치됐고, 작업이 OOM 으로 실패하며 CrashLoopBackOff 를 반복했다.

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

    10:03 UTC 에 Slack 으로 알림이 왔고, 10:05 에 알림을 확인하고 조사를 시작했다. 두 번째 노드는 15:03 에 Slack 알림이 왔고 15:09 에 확인했다. 탐지까지 걸린 시간은 4분이었다.

    조치
    • 10:22 에 EC2 인스턴스를 비정상으로 표시해 새 노드를 띄웠다.
    • 10:30 에 NotReady 노드를 cordon 하고 강제로 drain 했고, 10:36 에 그 EC2 인스턴스를 종료했다.
    • 13:02 에 네임스페이스에서 LimitRange 를 지우고 Grafana Agent 파드를 재시작했다.
    • 14시대에 문제의 개발 컨테이너를 0개로 줄였고, 몇 분 뒤 EC2 네트워크 트래픽이 정상으로 돌아왔다.
    • 두 번째 NotReady 뒤 15:15 에 개발 컨테이너를 다시 0개로 줄였고, 15:18 에 새 노드가 추가됐다.
    • 15:19 에 개발 컨테이너를 맡은 팀에 메일을 보냈고, 15:52 에 그 팀이 문제를 확인하고 수정 중이라고 답했다.
    후속 조치
    • grafana-agent 를 모니터링 노드 그룹으로 옮긴다.
    • 클러스터 전체 대역폭이 정해 둔 기준에 닿으면 알림을 보낸다.
    • grafana-agent Helm 차트에 메모리 한도를 걸 수 있는지 조사한다.
    • grafana-agent 의 메모리 사용량을 조사한다.
    • grafana-agent 에 PVC 를 써야 하는지 Grafana 지원팀에 묻는다.
    • 보존 기간을 제한한 채 노드 로그를 Loki 로 보내는 방안을 검토한다.
    • 쿠버네티스 노드 문제를 조사할 때 확인할 자주 쓰는 지표와 로그 쿼리를 위키 페이지로 만든다.
    교훈

    포스트모템에서 나온 후속 조치를 끝까지 챙겨야 한다. CloudWatch 에서 어떤 지표가 쓸모 있는지가 팀에 제대로 공유되지 않아 진단과 조사가 어려웠다.

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

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

원인별7

의존성 장애1건

조직
  1. IL-0133 폭풍으로 데이터센터 냉각이 멈춰 us-central1 리전 전체가 내려갔고, 디스크 핫플러그 버그로 Managed Kubernetes 컨트롤 플레인 약 140개의 복구가 길어졌다.
    Nebius2026

소프트웨어 결함2건

  1. IL-0138 nvidia-dkms-390 드라이버 빌드 실패로 망가진 커널 헤더가 몇 주 동안 방치됐다가, 정전 뒤 재부팅하자 하나뿐인 마스터 노드가 커널 패닉에 빠져 홈랩 쿠버네티스 클러스터가 6일 동안 멈췄다.
  2. IL-0041 fluent-bit 이 오류 없이 멈춰 운영 노드 한 대의 애플리케이션 로그가 Elasticsearch 로 전혀 가지 않았다.

용량 한계10건

  1. IL-0042 OpenSearch 디스크가 가득 찬 동안 fluent-bit 가 로그를 처리하지 못해 Elasticsearch 와 OpenSearch 에 애플리케이션 로그가 들어오지 않았다.
  2. IL-0044 kube-prometheus-stack 업그레이드 뒤 Prometheus 가 WAL 재생 중 메모리를 50Gi 넘게 써서 시작할 때마다 OOMKilled 로 죽었다
  3. IL-0046 계획된 재시작 뒤 Prometheus 가 WAL 을 다 읽기 전에 startupProbe 에 걸려 재시작을 반복했고 지표가 빠졌다
  4. IL-0110 Grafana Agent 파드가 메모리를 많이 쓰던 노드에 Hangfire 파드가 함께 올라가 시스템 OOM 으로 CrashLoopBackOff 를 반복했고, 노드가 응답을 멈추고 NotReady 가 됐다.
    DFDS2024
  5. IL-0169 FR-PAR 의 Scaleway Kubernetes API 가 메모리 부족으로 쓰러져 노드 인증이 막히고 Kapsule 노드가 NotReady 가 됐다.
  6. IL-0043 새 버전 fluent-bit에서 청크를 버리는 방식이 바뀌어 Kibana의 애플리케이션 로그에 긴 공백이 생겼다
  7. IL-0016 네임스페이스와 규칙이 늘어 live 클러스터의 Prometheus 가 메모리 부족으로 OOMKilled 되며 플랫폼 모니터링이 끊겼다
  8. IL-0176 시계열 급증으로 호스트 메모리가 바닥나자 oom_score_adj 999 를 받은 Prometheus 컨테이너가 커널 OOM Killer 에게 먼저 죽어 CrashLoopBackOff 에 빠졌다.
    LINE2020
  9. IL-0076 dex의 AuthRequest 리소스가 끝없이 쌓였고, 이를 치우려고 네임스페이스를 지우자 목록 조회 타임아웃과 재시도가 반복되며 쿠버네티스 마스터가 내려갔다
  10. IL-0001 CoreDNS 파드가 메모리 한도 100Mi 에 걸려 OOM 으로 계속 죽으면서 쿠버네티스 클러스터 전체의 DNS 가 멈췄다

unknown1건

구성 요소
기여 요인
–
  1. IL-0045 live 클러스터의 Prometheus 가 readiness probe 실패로 여러 번 재시작해 Cloud Platform 모니터링이 끊기고 메트릭이 빠졌다

업그레이드로 깨진 호환성2건

  1. IL-0060 쿠버네티스 1.24 업그레이드로 node-role.kubernetes.io/master 레이블이 사라지자 이 레이블에 기대던 Calico 라우트 리플렉터가 동작을 멈춰 레거시 클러스터의 네트워크가 모두 끊기고 Reddit 이 314분 동안 멈췄다
    Reddit2023
  2. IL-0144 Ubuntu 18.04 의 systemd 보안 업데이트가 DNS 설정을 날려 AKS 노드의 kubelet 이 레지스트리 이름을 해석하지 못하고 파드가 ImagePullBackoff 에 빠졌다.

설정 변경2건

  1. IL-0109 로그 수집을 고치려던 EKS 노드 롤오버가 꼬이면서 Auto Scaling 그룹이 정상 워커 노드를 모두 종료해 클러스터에 노드가 하나도 남지 않았다.
    DFDS2023
  2. IL-0035 ElastAlert 에 새로 넣은 알림 규칙 때문에 ElastAlert 파드가 메모리를 끝없이 써서 노드가 잇달아 NotReady 가 되었고, 같은 클러스터의 도구와 Grafana, Prometheus 가 함께 흔들렸다.
    NU.nl2019

운영 실수1건

  1. IL-0089 테스트 클러스터 삭제 스크립트가 운영 클러스터 live-1 을 대상으로 실행돼 인그레스 컨트롤러, 모니터링, 인증서 구성 요소가 지워지고 사용자 서비스에 접속할 수 없게 됐다.