Incident Library
적용된 필터 구성 요소kubelet모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

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

사례20건

20건 중 1~5번째

  1. 증상

    워커 노드 한 대에서 NodeFilesystemFilesFillingUp 알림이 울려 담당자가 호출됐다. inode 가 바닥날 추세라는 알림이었다.

    촉발

    단일 스테이지로 빌드한 이미지에 소스, 빌드 결과물, 개발 의존성까지 포함한 node_modules 전체가 들어갔고, 새 레이어 다이제스트가 생길 때마다 노드에 새 스냅샷이 풀렸다.

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

    node_exporter mixin 에 들어 있는 NodeFilesystemFilesFillingUp 알림이 inode 사용률 67% 에서 울렸다. predict_linear 로 inode 가 바닥날 시점을 예측하는 추세 알림이다.

    후속 조치
    • 멀티 스테이지 Dockerfile 로 바꿔, 한 스테이지에서 의존성을 설치하고 빌드한 뒤 최종 이미지에는 nginx:alpine 위에 컴파일된 결과물만 넣는다.
    • 추세 알림과 별도로 루트 파일 시스템의 inode 사용률이 0.80 을 넘으면 울리는 고정 기준 알림을 for: 30m 으로 둔다.
    • 노드마다 inode 사용률에서 디스크 사용률을 뺀 값을 큰 순서로 보여 주는 Prometheus 쿼리를 대시보드에 둔다.
    • 노드에 이미 쌓인 오래된 스냅샷은 crictl rmi --prune 으로 어떤 컨테이너도 쓰지 않는 이미지를 지워 정리한다.
    교훈

    kubelet 의 백그라운드 정리는 바이트를 기준으로 돈다. 용량보다 파일 수가 먼저 차는 워크로드에는 미리 손쓸 장치가 없다. kubelet 은 inode 가 5% 남았을 때 파드 축출로 처음 개입한다. 파드 축출은 노드를 지키는 마지막 수단일 뿐 해결책이 아니다. ext4 의 inode 수는 포맷할 때 정해진다. 작은 파일이 많으면 디스크가 넉넉해도 inode 가 먼저 바닥난다. 추세 알림은 증가가 잠시 멈추면 조용해진다. kubelet 의 95% eviction 지점보다 한참 앞에서 울리는 고정 기준 알림을 함께 둔다. node_modules 뿐 아니라 Python virtualenv, 벤더링한 PHP 패키지, Ruby gem 처럼 작은 파일이 많은 의존성 트리를 담은 이미지는 모두 같은 문제를 일으킨다.

  2. 증상

    외부에서 쿠버네티스 클러스터에 접속할 수 없었다. 작성자는 컨트롤 플레인 노드로 들어가 sudo systemctl status kubelet 으로 kubelet 로그를 확인했다.

    촉발

    kubeadm 이 만든 하위 인증서의 기본 유효기간 1년이 2026-02-20 16:16 UTC 에 끝났다.

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

    외부에서 클러스터에 접속이 안 되는 것으로 알아챘다. 컨트롤 플레인 노드에서 kubelet 로그, containerd 로그, kube-apiserver 컨테이너 로그를 차례로 보다가 kube-apiserver 로그의 x509 만료 오류에서 원인을 확인했다.

    조치
    • sudo kubeadm certs renew all 로 만료된 인증서를 한 번에 갱신했다.
    • containerd 와 kubelet 을 재시작해 Static Pod 로 도는 컨트롤 플레인 컴포넌트를 새 인증서로 다시 띄웠다.
    • /etc/kubernetes/admin.conf 를 $HOME/.kube/config 로 복사하고 소유자를 바꿔 kubeconfig 를 새 인증서로 바꿨다.
    교훈

    sudo kubeadm certs check-expiration 으로 만료일을 주기적으로 확인하고, 만료 30일 전부터 갱신하는 것이 좋다. kubeadm upgrade apply 를 실행하면 인증서도 함께 갱신되므로, 1년에 한 번 이상 쿠버네티스 버전을 올리는 클러스터는 이 문제를 자연스럽게 피한다. 버전을 올리지 않고 오래 운영하는 클러스터라면 kubeadm certs renew all 과 kubelet 재시작을 cron 으로 매년 걸어 둘 수 있다. 작성자가 든 예시에서는 매년 1월 1일 새벽 3시에 실행한다.

  3. 증상

    프로덕션 EKS 클러스터에서 원인을 바로 알기 어려운 서비스 에러가 간헐적으로 났다. RDS 나 Redis 같은 외부 서비스를 호출할 때 연결이 가끔 실패했다. DNS 요청이 몰릴 때는 도메인 조회 응답이 늦어지거나 조회가 아예 실패했다.

    촉발

    모든 CoreDNS 파드가 같은 노드에 배치되었고, 그 노드의 메모리 사용률이 급증해 메모리가 고갈됐다.

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

    글은 전면 장애를 어떻게 알아챘는지 적지 않았다. 그 전의 DNS 문제는 원인을 알기 어려운 서비스 에러가 간헐적으로 나면서 드러났다. 팀은 RDS 와 Redis 호출이 가끔 실패하는 현상을 추적하다가 DNS 이름 해석 실패가 근본 원인이라는 것을 확인했다.

    조치
    • CoreDNS 앞에서 DNS 질의를 받아 노드마다 캐시하는 NodeLocalDNS Cache 를 데몬셋으로 배포해 CoreDNS 부하를 줄였다.
    • CoreDNS 에 maxUnavailable: 1 인 PodDisruptionBudget 과 topology.kubernetes.io/zone 기준의 topologySpreadConstraints 를 적용해 파드가 한 곳에 몰리지 않게 했다.
    • Deployment 의 dnsConfig 로 ndots 값을 5 에서 2 로 낮춰 불필요한 DNS 조회를 줄였다.
    교훈

    쿠버네티스의 ndots:5 기본값은 점이 적은 외부 도메인을 조회할 때마다 질의를 여러 번 만든다. 이 부하는 트래픽이 큰 프로덕션 환경에서야 드러난다. CoreDNS 를 파드 2개의 기본 구성으로 두면 클러스터 전체의 단일 장애점이 된다. CoreDNS 파드는 노드와 가용 영역에 흩어 둔다. 별도 노드 그룹이나 Fargate 로 분리하면 다른 워크로드와 자원을 다투지 않는다. Affinity 와 PriorityClassName 으로 우선순위를 주면 더 안정적이다. CoreDNS 의 캐시와 bufsize 조정은 증상을 잠깐 줄였을 뿐이다. ndots 값은 여러 자료가 1이나 2를 권하지만 각 환경에 맞춰 정해야 한다.

  4. 증상

    2024년 9월 25일 22:25 UTC부터 SFO3 리전의 DigitalOcean 서비스 전반에서 네트워크 연결 문제가 생겼다. 리전 전체 서비스는 22:50에 회복됐지만 일부 Managed Kubernetes 클러스터는 그 뒤에도 연결이 불안정했다.

    촉발

    SFO3 코어 라우터 한 대에서 하드웨어 오류로 라인 카드 대부분이 동시에 재부팅됐다.

    원인
    구성 요소
    기여 요인
    –
    조치
    • 죽었던 라인 카드가 모두 빠르게 다시 올라와 네트워크 트래픽이 다시 흐르고 코어 라우터가 정상으로 돌아왔다.
    • SFO3 리전 DOKS 전체에서 영향받은 노드를 손으로 모두 재생성했다.
    후속 조치
    • 장비 벤더 지원팀과 함께 라인 카드가 죽은 근본 원인을 찾는다.
    • SFO3 리전 코어 라우터의 소프트웨어를 업그레이드한다.
    • 자동 복구 조치의 임계값을 높여 사람이 손으로 노드를 복구해야 하는 일을 줄인다.
    교훈

    네트워크가 몇 분 만에 돌아와도 게스트 네트워킹이 회복되지 않은 노드는 사람이 재생성할 때까지 비정상으로 남았다. 리전 전체 서비스는 25분 만에 돌아왔지만 DOKS 는 01:40까지 영향을 받았다. 자동 복구 조치가 이 경우를 처리하지 못해 SFO3 DOKS 전체에서 수동 작업이 필요했다.

  5. 증상

    2024-01-24 23:48 CET, FR-PAR 리전에서 Kapsule 과 Kosmos 고객 클러스터의 일부 노드가 NotReady 로 바뀌었다. 같은 시각 API Gateway 로 들어오는 요청이 크게 치솟았다.

    촉발

    FR-PAR 에서 동시에 몰린 배포가 Scaleway Kubernetes API 의 메모리를 바닥냈다.

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

    23:48 에 API Gateway 부하가 늘어난 것이 감지됐고, 00:00:10 에 내부 에스컬레이션을 거쳐 당직 엔지니어가 맡았다.

    조치
    • 관리형 Kubernetes 서비스의 메모리 한도와 가비지 컬렉션 임계값을 곧바로 올렸다.
    • 늘어난 부하를 받도록 주요 서비스에 복제본을 추가로 배포했다.
    • 레지스트리 캐시를 비우고, 클러스터가 안정되는 동안 지켜봤다.
    • 장애 뒤에도 계속 모니터링하며 서비스 설정을 조정했다.
    후속 조치
    • 로컬 인증 캐시를 구현한다.
    • 노드 인증 방식을 더 개선한다.
    • 모니터링을 강화하고 레이트 리밋 전략을 조정했으며 장애 대응 절차를 개선했다.
    교훈

    탄탄한 모니터링과 빠른 대응 체계가 중요하다. Kubernetes API 가 노드 인증까지 맡고 있어서 API 의 메모리 부족이 곧장 노드 NotReady 로 번졌다. Scaleway 는 이를 막으려고 로컬 인증 캐시와 노드 인증 개선을 계획했다.

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

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

원인별7

용량 한계6건

  1. IL-0071 작은 파일이 4만 개 넘게 든 단일 스테이지 이미지의 containerd 스냅샷이 쌓여 워커 노드의 inode 가 디스크보다 빠르게 소진되고 있었다
  2. IL-0027 CoreDNS 파드가 모두 한 노드에 몰린 채 그 노드의 메모리가 고갈되자 DNS 가 응답하지 못해 아이디어스 서비스 전체가 멈췄다
  3. IL-0169 FR-PAR 의 Scaleway Kubernetes API 가 메모리 부족으로 쓰러져 노드 인증이 막히고 Kapsule 노드가 NotReady 가 됐다.
  4. IL-0176 시계열 급증으로 호스트 메모리가 바닥나자 oom_score_adj 999 를 받은 Prometheus 컨테이너가 커널 OOM Killer 에게 먼저 죽어 CrashLoopBackOff 에 빠졌다.
    LINE2020
  5. IL-0002 빌더 파드가 노드 한 대에 몰리자 kubelet 이 기본 API QPS 한도에 막혀 파드 상태를 늦게 갱신했고, CI 빌드가 AWS IAM 자격 증명을 받지 못해 실패했다
  6. IL-0040 비운영 쿠버네티스 클러스터에 Helm 차트를 한꺼번에 설치하자 작은 gp2 루트 볼륨의 IOPS 가 바닥나, 워커 노드 세 대에서 kubelet 이나 Docker 가 내려가 세 대 모두 NotReady 가 됐다

인증서·자격 증명 만료2건

  1. IL-0183 kubeadm 으로 만든 클러스터의 1년짜리 인증서가 만료되어 kube-apiserver 가 etcd 와 TLS 연결을 맺지 못하고 재시작을 반복했고, 클러스터에 접속할 수 없게 됐다.
  2. IL-0184 kubeadm 클러스터의 API 서버와 내부 인증서가 만료돼 JupyterHub KubeSpawner 가 컨테이너를 만들지 못하고 kubectl 연결이 거부됐다
    dbhang2021

DNS·네트워크 장애1건

기여 요인
–
  1. IL-0154 SFO3 코어 라우터의 라인 카드가 하드웨어 오류로 한꺼번에 재부팅된 뒤 게스트 네트워킹이 돌아오지 않은 DOKS 노드가 비정상으로 남아, 일부 클러스터의 연결과 컨트롤 플레인 접속이 01:40 UTC까지 불안정했다.

설정 변경3건

  1. IL-0153 DOKS 1.27.6-do.0 과 1.28.2-do.0 워커 노드에서 매일 아침 도는 apt 자동 업그레이드가 15분 타임아웃에 걸려 강제 종료되면서 노드 네트워킹이 망가지고, 노드가 사흘 연속 NotReady 가 됐다.
  2. IL-0008 응답하지 않는 OPA 검증 웹훅 때문에 GKE 마스터 업그레이드가 멈추고 API 서버가 간헐적으로 끊기면서 노드가 끝없이 재생성됐다
  3. IL-0035 ElastAlert 에 새로 넣은 알림 규칙 때문에 ElastAlert 파드가 메모리를 끝없이 써서 노드가 잇달아 NotReady 가 되었고, 같은 클러스터의 도구와 Grafana, Prometheus 가 함께 흔들렸다.
    NU.nl2019

소프트웨어 결함6건

  1. IL-0112 나중에 회수된 EKS 노드 AMI 로 노드를 교체한 뒤 노드가 PLEG is not healthy 를 보고하며 NotReady 를 오갔고 파드 네트워크 타임아웃이 났다
    DFDS2022
  2. IL-0139 Calico 네트워크 정책을 쓰는 GKE 클러스터를 1.22 이상으로 업그레이드하자 경쟁 조건 때문에 CNI 정리가 Unauthorized 로 실패해 파드가 Terminating 이나 Pending 에 멈췄다.
  3. IL-0012 CPU limit 과 커널 CFS 쿼터 버그로 파드가 과하게 스로틀링돼 헬스 체크가 실패하고 애플리케이션이 멈췄다
    Omio2020
  4. IL-0074 워커 노드가 잇달아 Not Ready 에 빠지고 네트워크와 DNS 실패로 사이드카가 죽으면서, AirMap 플랫폼의 모든 서비스가 다섯 시간 동안 응답하지 않았다.
    AirMap2018
  5. IL-0038 kubelet 설정 변경을 롤링 업데이트하다 쿠버네티스 버그로 kubelet 이 올라오지 못해 한 클러스터의 노드가 NotReady 가 되고 파드 절반쯤이 축출됐다
    Oath2018
  6. IL-0003 etcd 클러스터 재구성 뒤 쿠버네티스 버그로 linkerd 가 서비스 위치 갱신을 받지 못했고, linkerd 를 모두 재시작하자 엔드포인트가 없는 서비스를 파싱하지 못하는 오류가 드러나 플랫폼 전체가 멈췄다
    Monzo2017

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

  1. IL-0144 Ubuntu 18.04 의 systemd 보안 업데이트가 DNS 설정을 날려 AKS 노드의 kubelet 이 레지스트리 이름을 해석하지 못하고 파드가 ImagePullBackoff 에 빠졌다.

unknown1건

조직
  1. IL-0059 kubeadm이 만든 etcd 정적 파드의 liveness probe가 실패해 kubelet이 약 2분마다 etcd를 재시작했고, 단일 마스터 클러스터의 API 서버가 계속 끊겼다