TestForge Blog

Kubernetes Node 장애 대응 가이드 — NotReady부터 복구까지

Kubernetes Node가 NotReady 상태가 됐을 때 단계별 대응 방법. 원인 진단, 워크로드 대피, 복구 절차까지 실전 가이드.

TestForge Team ·

Node NotReady 감지

kubectl get nodes
# NAME          STATUS     ROLES    AGE
# node-1        Ready      worker   30d
# node-2        NotReady   worker   30d  ← 장애
# node-3        Ready      worker   30d

즉각 대응: 워크로드 대피 (Drain)

Node 장애 시 가장 먼저 해야 할 일은 워크로드를 다른 Node로 이동하는 것입니다.

# 1. 스케줄 불가 표시 (새 Pod 배치 중단)
kubectl cordon node-2

# 2. 기존 Pod 안전하게 대피 (PDB 존중)
kubectl drain node-2 \
  --ignore-daemonsets \
  --delete-emptydir-data \
  --grace-period=60

# PDB로 인해 막힐 경우 강제 진행 (주의)
kubectl drain node-2 --force --ignore-daemonsets --delete-emptydir-data

주의: --force는 PodDisruptionBudget을 무시합니다. 서비스 영향 발생 가능.

원인 진단

# Node 상세 이벤트 확인
kubectl describe node node-2

# 주요 확인 포인트:
# Conditions: MemoryPressure, DiskPressure, PIDPressure, Ready
# Events: 마지막 장애 이벤트

원인 1: kubelet 중단

# Node에 SSH 접속
ssh node-2

# kubelet 상태 확인
systemctl status kubelet

# 재시작 시도
sudo systemctl restart kubelet
sudo journalctl -u kubelet -n 100 --no-pager  # 에러 로그 확인

원인 2: 디스크 고갈

# 디스크 사용률 확인
df -h

# 큰 파일/디렉터리 찾기
du -sh /var/lib/docker/* 2>/dev/null | sort -rh | head -10
du -sh /var/log/* | sort -rh | head -10

# Docker 미사용 리소스 정리
docker system prune -f
docker volume prune -f

# containerd 캐시 정리
crictl rmi --prune

원인 3: 메모리 고갈 (OOMKilled)

# dmesg에서 OOM 기록 확인
dmesg | grep -i oom | tail -20

# 메모리 사용 상위 프로세스
free -h
top -o %MEM

원인 4: 네트워크 단절

# CNI 플러그인 상태 확인
kubectl get pods -n kube-system | grep -E "calico|flannel|cilium|weave"

# Node 네트워크 연결성
ping <control-plane-ip>
curl -k https://<control-plane-ip>:6443/healthz

원인 5: 인증서 만료

# 인증서 만료일 확인
kubeadm certs check-expiration

# 인증서 갱신
kubeadm certs renew all
systemctl restart kubelet

복구 절차

# 1. Node 복구 확인
kubectl get node node-2
# STATUS가 Ready로 돌아왔는지 확인

# 2. 스케줄 재활성화
kubectl uncordon node-2

# 3. Pod 분산 확인
kubectl get pods -o wide | grep node-2

Node 자동 복구 설정

Node Problem Detector + Cluster Autoscaler

# Node Problem Detector 설치 (Helm)
helm install node-problem-detector \
  deliveryhero/node-problem-detector \
  --namespace kube-system

# Cluster Autoscaler가 NotReady Node 자동 교체
--balance-similar-node-groups=true
--skip-nodes-with-system-pods=false

Readiness 기반 자동 제거 (AWS EKS)

# Node Termination Handler
helm install aws-node-termination-handler \
  aws/aws-node-termination-handler \
  --namespace kube-system \
  --set enableSpotInterruptionDraining=true \
  --set enableRebalanceDraining=true

예방: Node 모니터링 알림

# Prometheus Alert Rule
- alert: KubernetesNodeNotReady
  expr: kube_node_status_condition{condition="Ready",status="true"} == 0
  for: 2m
  labels:
    severity: critical
  annotations:
    summary: "Node {{ $labels.node }} is NotReady"

- alert: KubernetesNodeDiskPressure
  expr: kube_node_status_condition{condition="DiskPressure",status="true"} == 1
  for: 1m
  labels:
    severity: warning

체크리스트 요약

단계명령어
1. 워크로드 대피kubectl drain node-2 --ignore-daemonsets
2. 원인 파악kubectl describe node node-2
3. kubelet 확인systemctl status kubelet
4. 디스크/메모리df -h, free -h
5. 복구 후 복원kubectl uncordon node-2