[K8s] Kubernetes Node가 NotReady 상태일 때: 실전 트러블슈팅 가이드

[K8s] Kubernetes Node가 NotReady 상태일 때: 실전 트러블슈팅 가이드

요약 (Abstract) 인프라 엔지니어의 새벽잠을 깨우는 주범, Kubernetes Node의 NotReady 상태. 17년 차 엔지니어의 시각으로 문제의 핵심 원인(Kubelet, CNI, Runtime)을 분석하고, kubectl을 활용한 진단부터 자동 복구 스크립트 구축까지, 실전에서 즉시 적용 가능한 해결책을 정리합니다.


1. 들어가며: 인프라 엔지니어의 숙명

레거시 환경에서 서버의 Health Check 실패가 단순히 Ping이 빠지는 문제였다면, 쿠버네티스(Kubernetes) 환경에서의 Node NotReady는 훨씬 복합적인 의미를 가집니다.

이는 단순히 서버가 죽은 것일 수도 있지만, Kubelet 프로세스의 오동작, 컨테이너 런타임(Docker/Containerd)의 행, 혹은 CNI(Network Interface) 설정 꼬임 등 다양한 원인이 얽혀 있습니다. 이번 포스트에서는 실제 운영 환경에서 겪었던 사례를 바탕으로, 당황하지 않고 문제를 해결하는 체계적인 트러블슈팅 프로세스를 공유합니다.


2. 🚨 문제 상황: "Node가 준비되지 않았습니다"

운영 중인 클러스터에서 갑자기 노드 하나가 NotReady 상태로 변하면, 스케줄러는 해당 노드에 새로운 파드(Pod)를 할당하지 않으며, 기존 파드들의 상태도 불안정해질 수 있습니다.

Bash

# kubectl get nodes 결과
NAME       STATUS     ROLES    AGE   VERSION
master-1   Ready      master   30d   v1.28.2
worker-1   Ready      worker   30d   v1.28.2
worker-2   NotReady   worker   30d   v1.28.2  <-- 문제 발생
worker-3   Ready      worker   30d   v1.28.2

가장 먼저 해야 할 일은 describe 명령어로 상세 원인을 파악하는 것입니다.

Bash

kubectl describe node worker-2

주요 에러 메시지 예시:

  • KubeletNotReady: Kubelet이 응답하지 않음
  • SystemOOM: 시스템 메모리 부족
  • NetworkPluginNotReady: CNI 플러그인 초기화 실패 (가장 흔함)

3. 🔍 핵심 원인 분석 (The Root Causes)

경험상 NotReady 상태의 원인은 크게 4가지 영역으로 좁혀집니다.

  1. Kubelet 서비스 문제: 노드의 에이전트인 Kubelet이 죽었거나 API 서버와 통신하지 못하는 경우.
  2. CNI (Container Network Interface) 문제: Flannel, Calico 등의 네트워크 플러그인 파드가 죽거나 설정이 꼬인 경우.
  3. 컨테이너 런타임 (Runtime) 문제: Docker 데몬이나 Containerd가 응답 불가(Hang) 상태인 경우.
  4. 시스템 리소스 고갈: Disk Pressure, Memory Pressure 등으로 인해 노드가 스스로를 보호하기 위해 셧다운된 경우.

4. 🛠️ 단계별 해결 솔루션

4.1. Kubelet 서비스 심폐소생술

가장 빈번한 원인입니다. Kubelet 서비스의 로그를 확인하고 재시작합니다.

Bash

# 1. Kubelet 상태 확인
sudo systemctl status kubelet

# 2. 로그 확인 (최근 10분)
sudo journalctl -u kubelet -f

# 3. 서비스 재시작
sudo systemctl restart kubelet
Tip: 만약 인증서(Certificate) 만료 문제라면 /var/lib/kubelet/pki/ 경로의 인증서를 확인하고 갱신해야 합니다.

4.2. CNI 플러그인 점검

NetworkPluginNotReady 메시지가 보인다면 CNI 문제입니다.

Bash

# 1. kube-system 네임스페이스의 CNI 파드 확인
kubectl get pods -n kube-system -o wide | grep -E 'flannel|calico'

# 2. 문제가 있는 파드 로그 확인
kubectl logs -n kube-system <cni-pod-name>

# 3. (필요시) CNI 데몬셋 재시작
kubectl rollout restart daemonset/kube-flannel-ds -n kube-system

4.3. 컨테이너 런타임 (Docker/Containerd) 점검

런타임이 멈추면 Kubelet도 동작하지 않습니다.

Bash

# Docker를 사용하는 경우
sudo systemctl status docker
sudo systemctl restart docker

# Containerd를 사용하는 경우 (최신 K8s)
sudo systemctl status containerd
sudo systemctl restart containerd

5. 🚀 고급: 자동 복구 및 모니터링 (Auto-Healing)

매번 사람이 붙어서 해결할 수는 없습니다. DevOps 엔지니어라면 자동화를 고민해야 합니다.

5.1. Prometheus & Grafana 알림 설정

Prometheus 룰을 설정하여 노드 장애 발생 시 즉시 알림을 받습니다.

YAML

groups:
- name: kubernetes-nodes
  rules:
  - alert: NodeNotReady
    expr: kube_node_status_condition{condition="Ready",status="true"} == 0
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "Node {{ $labels.node }} is Down!"

5.2. 자동 복구 스크립트 (Self-Healing Script)

Cronjob이나 모니터링 시스템의 Webhook과 연동하여 사용할 수 있는 간단한 복구 스크립트 예제입니다.

Bash

#!/bin/bash
NODE_NAME=$1

echo "🔍 Diagnosing Node: $NODE_NAME"

# Kubelet 재시작 시도
ssh $NODE_NAME "sudo systemctl restart kubelet"
sleep 10

# 상태 재확인 후 실패 시 런타임 재시작
if [ $(kubectl get node $NODE_NAME -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}') != "True" ]; then
    echo "⚠️ Kubelet restart failed. Restarting Runtime..."
    ssh $NODE_NAME "sudo systemctl restart containerd"
fi

6. 마치며: 장애는 막을 수 없지만, 대응은 줄일 수 있다

17년 동안 인프라를 만지며 느낀 점은 **"장애가 없는 시스템은 없다"**는 것입니다. 하지만 **"장애 복구 시간을 단축시키는 시스템"**은 만들 수 있습니다.

단순히 systemctl restart를 반복하는 것을 넘어, 위에서 소개한 모니터링과 자동화 스크립트를 통해 여러분의 클러스터가 스스로 치유되는(Self-Healing) 환경을 구축해 보시기 바랍니다.

다음 포스트에서는 이 노드들을 관리하는 **"K8s 클러스터 업그레이드 전략(Zero Downtime)"**에 대해 다뤄보겠습니다.

Read more

[Roadmap] 17년 차 인프라 엔지니어, 다시 수험생이 되다: 2026 Cloud & DevOps 도전기

[Roadmap] 17년 차 인프라 엔지니어, 다시 수험생이 되다: 2026 Cloud & DevOps 도전기

요약 (Abstract) Unix-C부터 시작해 RHEL, VMware 등 온프레미스 환경에서 잔뼈가 굵은 17년 차 엔지니어. 안정적인 레거시 기술을 넘어, 이제 'Cloud Native'라는 새로운 파도에 올라타려 합니다. 2026년, 인프라 엔지니어에서 DevOps 전문가로 도약하기 위한 자격증 취득 계획과 학습 로드맵을 공유합니다. 1. 왜 다시 공부인가? (Why Now?) 지난 17년간 공공기관과

By Kdokev
[HomeLab] 맨땅에 헤딩: Kubeadm으로 Kubernetes 클러스터 직접 구축하기 (Rocky Linux 9)

[HomeLab] 맨땅에 헤딩: Kubeadm으로 Kubernetes 클러스터 직접 구축하기 (Rocky Linux 9)

요약 (Abstract) 클라우드(EKS, GKE)의 편안함을 뒤로하고, 인프라 엔지니어의 야성을 되찾기 위해 홈 서버(VMware) 위에 Kubernetes 클러스터를 직접 구축합니다. Rocky Linux 9 환경에서 Containerd 런타임 구성부터 Kubeadm Init, 그리고 Calico CNI 설치까지의 전 과정을 'Copy & Paste' 수준으로 상세히 기록합니다. 1. 구축 환경 및 아키텍처 (Architecture)

By Kdokev
[HomeLab] 방구석 데이터센터 구축기: 스펙, 네트워크, 그리고 K8s를 향한 여정

[HomeLab] 방구석 데이터센터 구축기: 스펙, 네트워크, 그리고 K8s를 향한 여정

요약 (Abstract) 17년 차 인프라 엔지니어가 집에서 운영 중인 홈 서버(Home Server)의 전체 사양과 네트워크 구성을 상세히 공개합니다. 고성능 미니 PC(Beelink)와 VMware Workstation을 활용한 현재의 VM 기반 아키텍처를 분석하고, 향후 Kubernetes(K8s) 클러스터와 DevOps 환경(ArgoCD, Prometheus 등)으로 전환하기 위한 구체적인 로드맵을 기술합니다. 1. 하드웨어

By Kdokev
[DevOps] 인프라 엔지니어가 바라보는 DevOps 문화와 클라우드 전환의 의미

[DevOps] 인프라 엔지니어가 바라보는 DevOps 문화와 클라우드 전환의 의미

요약 (Abstract) 17년 차 인프라 TA로서, 전통적인 온프레미스 환경에서 DevOps 및 클라우드 환경으로 변화하는 IT 트렌드를 조망합니다. DevOps가 단순한 도구의 도입이 아닌 개발과 운영의 협업 문화임을 강조하고, 클라우드(AWS, Azure, GCP)가 이러한 변화를 가속화하는 핵심 인프라로서 어떻게 활용되는지 경험을 바탕으로 기술합니다. 1. 들어가며: 변화의 흐름 속에서 오랫동안 서버 랙과

By Kdokev