제목:
worker 재부팅 전 drain 절차 정리 - 2026-07-02
내용:
운영 매뉴얼을 쓰면서 worker 노드 점검 절차를 따로 정리함.
처음부터 잘 알고 쓴다기보다, worker를 재부팅하거나 점검해야 할 때 어디부터 확인해야 하는지 순서를 잡는 느낌.
핵심은 재부팅 자체가 아님.
worker 하나를 비워도 서비스가 유지되는지 확인하는 게 목적.
기본 흐름.
cordon
-> drain
-> Pod 재생성 확인
-> 작업 또는 재부팅
-> Ready 확인
-> uncordon
의미.
cordon
= 새 Pod가 해당 worker에 더 배치되지 않게 막음
drain
= 기존 Pod를 내리고 다른 worker에서 다시 뜨게 함
uncordon
= 작업 끝난 worker가 다시 Pod를 받을 수 있게 함
먼저 전체 노드 상태 확인.
# Kubernetes 노드 상태와 IP를 확인한다.
kubectl get nodes -o wide
전체 Pod 배치 확인.
# 전체 Pod가 어떤 노드에 배치되어 있는지 확인한다.
kubectl get pods -A -o wide
대상 worker를 바로 정하지 않고, 먼저 전체 배치를 봄.
확인할 것.
다른 worker와 control-plane이 Ready인지
replica 1 앱이 어느 worker에 있는지
StatefulSet/PVC Pod가 있는지
kube-system, ingress-nginx, monitoring Pod가 어디 있는지
대상 worker를 정한 뒤 그 worker에 떠 있는 Pod만 확인.
# k8s-worker1에 떠 있는 Pod를 확인한다.
kubectl get pods -A -o wide --field-selector spec.nodeName=k8s-worker1
StatefulSet/PVC Pod가 있으면 바로 drain하지 않음.
replica 1 중요 앱이 있어도 영향 범위를 먼저 봄.
drain 전 목록 기록.
# drain 전 k8s-worker1에 떠 있는 Pod 목록을 파일로 기록한다.
kubectl get pods -A -o wide --field-selector spec.nodeName=k8s-worker1 \
> /tmp/k8s-worker1-pods-before-drain.txt
# 기록한 drain 전 Pod 목록을 확인한다.
sed -n '1,120p' /tmp/k8s-worker1-pods-before-drain.txt
이 기록은 원래 위치로 되돌리기 위한 게 아니라, drain 후 Pod가 다시 만들어졌는지 비교하기 위한 기준.
cordon 실행.
# k8s-worker1에 새 Pod가 더 배치되지 않도록 cordon 한다.
kubectl cordon k8s-worker1
확인.
# 대상 worker가 SchedulingDisabled 상태인지 확인한다.
kubectl get nodes
drain 직전 다시 확인.
# drain 직전 k8s-worker1의 Pod 목록을 다시 확인한다.
kubectl get pods -A -o wide --field-selector spec.nodeName=k8s-worker1
여기서 멈춰야 하는 경우.
StatefulSet/PVC Pod가 있고 영향 범위를 모름
replica 1 중요 앱이 있음
다른 worker가 이미 NotReady
ArgoCD나 monitoring이 이미 불안정
drain 실행.
# k8s-worker1을 비운다. DaemonSet Pod는 무시하고 emptyDir 데이터가 있는 Pod 삭제를 허용한다.
kubectl drain k8s-worker1 --ignore-daemonsets --delete-emptydir-data
drain은 확인 명령이 아니라 실제로 Pod를 내리는 명령.
옵션 없이 실행하면 DaemonSet Pod나 emptyDir 사용 Pod 때문에 실패할 수 있음.
이 실패는 장애라기보다 Kubernetes가 위험한 삭제를 막는 보호 동작으로 봄.
drain 후 확인.
# drain 후 전체 Pod 상태를 확인한다.
kubectl get pods -A
# drain 후 Running 또는 Succeeded가 아닌 Pod가 남아 있는지 확인한다.
kubectl get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded
# drain 후 k8s-worker1에 일반 Pod가 남아 있는지 확인한다.
kubectl get pods -A -o wide --field-selector spec.nodeName=k8s-worker1
정상 기준.
Deployment Pod가 다른 worker에서 다시 만들어짐
대상 worker에는 DaemonSet Pod 정도만 남음
Pending, CrashLoopBackOff, Terminating Pod가 오래 남지 않음
READY가 낮거나 RESTARTS가 계속 늘어나는 Pod가 없음
Pod 재생성이 비정상이면 재부팅이나 작업을 진행하지 않음.
정상일 때만 worker 점검이나 재부팅 진행.
작업 후 Ready 확인.
# k8s-worker1이 Ready로 돌아왔는지 확인한다.
kubectl get node k8s-worker1 -o wide
재부팅 후에도 Ready,SchedulingDisabled로 보일 수 있음.
cordon 상태는 재부팅으로 자동 해제되지 않음.
정상 복귀를 확인한 뒤 uncordon 실행.
# k8s-worker1이 다시 Pod를 받을 수 있도록 uncordon 한다.
kubectl uncordon k8s-worker1
# SchedulingDisabled 표시가 사라졌는지 확인한다.
kubectl get nodes
마지막 전체 확인.
# 전체 Pod 상태를 확인한다.
kubectl get pods -A
# ArgoCD Application의 sync와 health 상태를 확인한다.
kubectl -n argocd get app
대표 Ingress 응답도 직접 확인.
# 대표 Ingress host가 Ingress VIP로 직접 정상 응답하는지 확인한다.
host="grafana.yeonghoon.kim"
curl -k -I --resolve "$host:443:192.168.200.49" "https://$host/"
worker가 이미 NotReady일 때는 계획 점검과 다르게 봄.
NotReady는 Pod가 즉시 죽었다는 뜻이 아니라, control-plane이 해당 worker의 kubelet과 정상적으로 대화하지 못한다는 뜻.
기존 컨테이너는 worker 안에서 계속 실행 중일 수 있음.
# NotReady 노드가 몇 개인지 확인한다.
kubectl get nodes -o wide
# NotReady worker에 남아 있는 Pod를 확인한다.
kubectl get pods -A -o wide --field-selector spec.nodeName=k8s-worker1
NotReady worker에 StatefulSet/PVC Pod가 있으면 바로 강제 삭제하지 않음.
강제 Pod 삭제, PV/PVC 삭제, finalizer 제거 같은 건 이 절차에서 바로 하지 않고 별도 장애 대응 기준으로 판단.
정리.
worker 점검은 바로 재부팅부터 하는 게 아니라, 먼저 비워도 되는지 보고, 비운 뒤에도 Pod가 다른 worker에서 살아나는지 확인하는 절차로 잡음.