drain
kubectl drain <node-name>
영어로 배수구, 물 빠짐 등의 의미로, 노드에 존재하는 모든 Pod를 제거하고, Pod를 다른 노드에 스케쥴링하도록 한다. drain 한 node는 cordon을 실행한 것과 동일하게 SchedulingDisabled 상태가 되기 때문에 신규 Pod를 스케쥴링하지 않는다.
drain은 커널 업그레이드, 하드웨어 유지 보수 등의 노드 관리를 위해 노드에서 포드를 안전하게 제거할 때 사용한다.
동작 순서
1. 새 포드가 노드에 스케쥴링되지 않도록 한다. (cordon)
2. 노드에서 실행 중이던 포드를 삭제한다. 이 때 Daemonset으로 실행된 포드가 존재하면 drain에 실패한다.
3. ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet에 의해 실행되었으나 삭제된 포드는 컨트롤러에 의해 다른 노드에서 실행된다. 단순 pod만으로 실행된 포드는 완전히 종료된다.
drain 시 포드는 graceful하게 종료된다.
테스트
아래와 같이 포드가 동작하고 있는 node01 노드를 drain 하고자 한다.
1. 노드 상태 확인
kubectl get nodes
또한 daemonset에 의해 동작하고 있는 포드가 있는 것을 확인했다.
kubectl get daemonsets.apps -A
2. drain
daemonset에 의해 관리되는 포드는 삭제하지 않도록 --ignore-daemonsets 옵션을 사용하여 drain을 실행한다.
kubectl drain node01 --ignore-daemonsets
pod만으로 동작하는 포드가 존재하면 아래와 같이 에러 메세지가 발생하면서 drain에 실패한다.
서비스에 중요한 포드가 없다면 --force 옵션을 이용하여 drain을 강제할 수 있다.
kubectl drain node01 --ignore-daemonsets --force
3. drain 결과 확인
node01에서 동작하던 pod가 모두 삭제되고, node01의 상태가 SchedulingDisalbed로 전환된 것을 확인할 수 있다.
--ignore-daemonset 옵션에 의해 daemonset으로 동작하는 포드는 유지된 것 또한 확인할 수 있다.
참고 문서
https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/
https://velog.io/@koo8624/Kubernetes-Drain-Cordon-and-Uncordon