Incident Library
적용된 필터 기여 요인리소스 요청과 한도 미설정도메인쿠버네티스모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

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

사례11건

11건 중 4~8번째

  1. 증상

    남은 엔드포인트의 요청 비율을 EKS 쪽으로 1% 에서 25% 로 올리자 Sentry 에 DNS 이름 해석 오류가 대량으로 올라왔다. API 가 데이터베이스와 외부 서비스에 연결하지 못했다.

    촉발

    ALB 로 엔드포인트마다 요청 비율을 바꾸며 이전하던 중, 남은 엔드포인트의 요청 비율을 EKS 쪽으로 1% 에서 25% 로 올렸다.

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

    요청 비율을 EKS 쪽으로 올린 직후 Sentry 에 DNS 이름 해석 오류가 대량으로 올라온 것을 확인했다.

    조치
    • 오류를 멈추려고 요청 비율을 VM 쪽으로 되돌렸다.
    • 임시 조치로 HPA 리소스를 만들어 CoreDNS 파드를 오토스케일하게 했고, 그 뒤 EKS 이전을 마쳤다.
    후속 조치
    • 애플리케이션 Deployment 의 dnsConfig 에 ndots 값 "1" 을 넣어 파드가 항상 FQDN 으로 이름을 해석하게 했다.
    • CoreDNS ConfigMap 의 Corefile 에서 cache 를 600 으로 바꿔 캐시 TTL 을 늘렸다.
    • CoreDNS ConfigMap 의 health 플러그인에 lameduck 30s 를 넣어, 스케일인 때 파드가 바로 끝나지 않고 남은 처리를 이어 가게 했다.
    • 운영 환경과 스테이징 환경의 차이를 줄이는 것을 비용과 균형을 보며 검토한다.
    교훈

    MonotaRO 는 관리형 서비스이니 문제가 없으리라 짐작하고 사전 사례 조사, 부하 시험, 감시 같은 측정을 하지 않아 이번 문제가 났다고 보았다. 그래서 짐작하지 말고 측정하라는 원칙을 다시 새겼다. 운영 환경과 스테이징 환경의 차이가 컸다. 네트워크 구성이 달라 환경마다 ndots 가 달랐고, 스테이징 환경의 데이터베이스 사양으로는 고부하 시험을 할 수 없었다. 직접 관리하지 않는 부분의 리소스도 잘 알지 못했다. 쿠버네티스로 옮긴 다른 회사의 사례를 조사했다면 이번 문제를 어느 정도 예측할 수 있었다고 했다.

  2. 증상

    DevOps 팀이 아직 운영 트래픽을 받지 않는 notification-preferences 마이크로서비스의 `resources.requests.cpu` 를 2에서 1로 줄였다. 작업을 마치고 몇 분 뒤 메모리 사용량이 90% 를 넘었다는 경보가 왔다. 메모리 할당량이나 JVM 의 GC 관련 인자는 건드리지 않은 상태였다.

    촉발

    리소스 최적화 작업 중 notification-preferences 디플로이먼트의 `resources.requests.cpu` 를 2에서 1로 줄였다. CPU limit 은 설정하지 않은 상태였다.

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

    CPU requests 를 줄이고 몇 분 뒤 메모리 사용량이 90% 를 넘었다는 경보가 울렸다.

    조치
    • JVM 옵션에 `-XX:ActiveProcessorCount=1` 을 넣어 JVM 이 쓸 CPU 수를 강제로 지정했다. 자원을 다시 늘리거나, CPU limit 을 걸거나, requests 를 1001m 이나 999m 으로 두는 방법은 각각 문제가 있어 고르지 않았다.
    후속 조치
    • 이 문제를 사내 공지로 알렸다.
    교훈

    cgroup v1 환경에서 JVM 은 `cpu.shares` 값이 정확히 1024 일 때 이를 설정 없음으로 보고 노드의 CPU 수를 쓴다. CPU limit 없이 requests 만 1로 준 JVM 파드는 노드가 클수록 스레드를 많이 띄우고 메모리를 더 쓴다. 이 문제는 쓸 수 있는 CPU 수로 스레드 수를 정하는 WebFlux 같은 프레임워크에서 특히 크게 드러난다. 이런 설정이라면 `-XX:ActiveProcessorCount` 나 CPU limit 으로 CPU 수를 명시해야 한다. Hyperconnect 는 원래 운영 JVM 애플리케이션에 CPU requests 를 2 이상 주었고, 마이크로서비스가 늘어 자원을 아끼려다 이 문제를 만났다.

  3. 증상

    WER 허브의 학생들이 페이지가 멈춘다고 알려 왔다. 아무것도 쓸 수 없는 완전한 장애였다. 08:52 PM IST 에 많은 학생이 허브에 접속하지 못하고 허브가 멈췄다는 보고가 들어왔다.

    촉발

    WER 학생들의 사용량이 늘어 사용자 파드와 코어 파드가 함께 도는 노드의 CPU 와 메모리를 다 썼다.

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

    08:52 PM IST 에 많은 학생이 허브에 접속하지 못하고 허브가 멈췄다는 보고가 들어왔다.

    조치
    • 09:23 PM 에 WER 학생 파드의 메모리 오버커밋을 없앴다. 학생들이 메모리 한도의 상당 부분을 쓰고 있었고, 새 노드가 하나 더 떠서 기존 노드의 부담을 덜 것으로 보았다.
    • 09:24 PM 에 모든 코어 파드의 자원 보장을 올려 노드가 가득 차도 코어 파드가 동작할 자원을 갖게 했다. 코어 파드가 재시작되며 일부가 새 노드로 옮겨졌다.
    후속 조치
    • 사용자 파드를 별도 노드 풀로 옮겨 코어 파드에 부담을 주지 않게 한다.
    • prometheus, grafana, ingress 같은 지원 인프라에도 한도를 건다.
    • 메모리 오버커밋 비율을 검토하고 문서로 남긴다.
    • 자원 사용량을 감시할 Grafana 대시보드를 더 낫게 만든다.
    • 다른 사람도 문제를 살펴볼 수 있게 클러스터의 kubectl 접근 권한을 얻는 방법을 문서로 남긴다.
    교훈

    코어 파드와 사용자 파드가 같은 노드에 섞여 있으면 사용자 사용량이 몰릴 때 코어 파드까지 자원을 얻지 못한다. 코어 파드에는 노드가 가득 차도 동작할 만큼의 자원 보장이 있어야 한다. 메모리 오버커밋 비율은 관례대로 정하지 말고 실제 사용량에 맞춰야 한다. WER 학생들은 한도의 상당 부분을 실제로 쓰고 있어서 4배 오버커밋은 지나쳤다.

  4. 증상

    어느 월요일 아침, 엔지니어가 쿠버네티스 클러스터 경고를 보려고 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 를 정한다.

  5. 증상

    2019년 6월 15일 토요일 오후 5시 12분에 자체 모니터링이 운영 클러스터의 노드 한 대에서 SystemOOM 이벤트가 났다고 알렸다. 4분 뒤에는 같은 노드의 루트 볼륨에서 EBS Burst Balance 가 낮다는 경고가 왔다.

    촉발

    메모리 요청과 제한 없이 배포된 fluentd-sumologic 파드가 노드 메모리를 계속 차지해 노드에 SystemOOM 이 났다.

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

    Blue Matador 의 자체 모니터링이 노드의 SystemOOM 이벤트 알림과 EBS Burst Balance 가 낮아졌다는 경고를 보냈다. 원인 파드는 Datadog 의 메모리 사용량 그래프에서 찾았다.

    조치
    • 모든 sumologic 파드를 재시작해, 파드들이 메모리를 적게 쓰는 상태에서 다시 출발하게 했다.
    • fluentd-sumologic 파드 스펙에 환경 변수 RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR 를 "0.9" 로 넣어 배포했다.
    • fluentd-sumologic 에 메모리 요청 128Mi, 메모리 제한 1024Mi, CPU 요청 100m, CPU 제한 250m 을 지정했다.
    후속 조치
    • 기본 리소스 제한과 리소스 쿼터를 함께 써서 모든 파드가 요청과 제한을 갖게 하는 작업을 백로그에 올렸다.
    교훈

    재시작된 파드를 확인할 때는 모든 네임스페이스를 본다. 이번에는 fluentd-sumologic 파드가 별도 네임스페이스에 있어 첫날 원인을 놓쳤다. 모든 파드, 특히 서드파티 애플리케이션에는 리소스 요청과 제한을 지정한다. 제한이 있으면 메모리 문제를 고치지는 못해도 그 문제가 해당 파드들 밖으로 번지지 않게 막을 수 있다. 보이는 문제는 증거가 남아 있을 때 근본 원인까지 파고든다. 이번에는 디스크 IO 가 늘어난 이유를 확인할 로그가 사라진 뒤였다.

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

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

원인별4

용량 한계8건

  1. IL-0548 EKS 의 Prometheus 가 거듭 죽으며 Buildkite 의 알림 전달과 빌드 디스패치가 지연됐다
  2. IL-0099 메모리 상한 없이 8GB 만 보장한 프로필 때문에 워크숍 중 사용자 파드가 서로를 축출해 서버 시작이 15분을 넘고 커널이 죽었다.
    2i2c2025
  3. IL-0110 Grafana Agent 파드가 메모리를 많이 쓰던 노드에 Hangfire 파드가 함께 올라가 시스템 OOM 으로 CrashLoopBackOff 를 반복했고, 노드가 응답을 멈추고 NotReady 가 됐다.
    DFDS2024
  4. IL-0433 EC2 에서 EKS on Fargate 로 트래픽을 옮기던 중 CoreDNS 과부하로 이름 해석 오류가 쏟아져 롤백했다
  5. IL-0094 JupyterHub 클러스터에서 학생 파드가 노드의 CPU 와 메모리를 다 써서 자원 보장이 부족했던 코어 파드가 자원을 얻지 못했고, 허브 전체가 멈췄다.
    2i2c2020
  6. IL-0176 시계열 급증으로 호스트 메모리가 바닥나자 oom_score_adj 999 를 받은 Prometheus 컨테이너가 커널 OOM Killer 에게 먼저 죽어 CrashLoopBackOff 에 빠졌다.
    LINE2020
  7. IL-0026 메모리 제한이 없는 fluentd-sumologic 파드가 메모리를 다 써서 운영 쿠버네티스 노드 두 대에 이틀 연속 SystemOOM 이 났다
  8. IL-0503 GKE 노드의 메모리가 바닥나 mybinder.org 의 proxy 파드가 OOM 으로 죽고 새 서버 실행이 실패했다

소프트웨어 결함1건

  1. IL-0175 JVM 파드의 CPU requests 를 1코어로 줄이자 JVM 이 노드의 CPU 36개를 인식해 Reactor Netty 스레드가 늘고 메모리 사용량이 경보 기준을 넘었다

배포 결함1건

구성 요소
  1. IL-0466 Prow 가 테스트 작업을 서비스 클러스터에 스케줄해 작업이 뜨지 못하고 Prow 전체가 느려졌다

설정 변경1건

조직
  1. IL-0035 ElastAlert 에 새로 넣은 알림 규칙 때문에 ElastAlert 파드가 메모리를 끝없이 써서 노드가 잇달아 NotReady 가 되었고, 같은 클러스터의 도구와 Grafana, Prometheus 가 함께 흔들렸다.
    NU.nl2019