노드는 SchedulingEnabled
(=default)와 SchedulingDisabled
중 하나의 상태를 가지는데 SchedulingDisabled
된 노드는 스케줄링 대상에서 제외되어 해당 노드에 파드가 신규로 생성되지 않습니다. (이미 노드에서 실행되고 있던 Pod에는 영향을 주지 않습니다.)
특정 노드의 스케줄링을 중단시키는 것이 cordon, 허용하는 것이 uncordon입니다.
cordon 시킨 노드의 상태는 SchedulingDisabled
상태가 되며, 해당 노드에는 더 이상 새로운 Pod가 생성되지 않습니다.
※ cordon 한 노드에 떠있던 기존 Pod에는 아무 영향이 없습니다.
# cordon 사용
$ kubectl cordon <NodeName>
# uncordon 사용
$ kubectl uncordon <NodeName>
따라서 아래 캡처를 보면 'k8s-worker2' 노드에 있던 기존의 Pod들은 그대로 있는 상태에서 cordon 이후 스케줄링되는 새로운 Pod들은 모두 'k8s-worker1' 노드(=SchedulingDisabled
상태인 노드를 제외한 모든 노드)에 생성될 것입니다.
이 상태에서 uncordon을 하면 'k8s-worker2' 노드의 status에서 SchedulingDisabled
는 사라지며 cordon과 마찬가지로 기존 Pod에는 아무런 영향을 주지 않습니다.
cordon/uncordon한 노드는 스케줄링 대상에서 제외될 뿐이며, 노드에서 이미 실행 중인 Pod는 정지되거나 삭제되지 않습니다.
그렇다면 cordon처럼 노드를 SchedulingDisabled
상태로 만들면서 실행 중인 모든 Pod도 제거하고 싶을 경우는 어떻게 해야 할까요? 그때 사용하는 게 바로 drain 명령어입니다.
'drain = 물을 빼다' 에서 직관적으로 느낄 수 있듯이, drain은 노드에 있는 모든 Pod들을 제거해서 노드를 비웁니다. 노드가 SchedulingDisabled
된다는 점은 cordon과 동일하기 때문에(drain ⊃ cordon) 미리 cordon을 실행할 필요는 없습니다.
# drain 사용
$ kubectl drain <NodeName> <options>
# <options>
--ignore-daemonsets : DaemonSet이 관리하는 Pod 삭제
--force : RC, RS, Job, DaemonSet 또는 StatefulSet에서 관리하지 않는 단일 Pod 삭제
--delete-local-data : 로컬 스토리지를 사용하고 있는 Pod 삭제
replicas=3이고 pod-1은 'k8s-worker1' 노드에, pod-2와 pod-3은 'k8s-worker2' 노드에 떠있다는 가정 하에 'kubectl drain k8s-worker2'를 실행하면 pod-2와 pod-3은 즉시 terminate 되며 동시에 'k8s-worker1' 노드에 2개의 Pod가 새로 생성될 것입니다.
Deployment의 경우에는 drain을 하더라도 즉시 다른 노드에 새로운 Pod가 뜨겠지만, replicas 설정이 없는 단일 Pod의 경우는 --force
옵션으로 Pod를 삭제하고 나면 재생성되지 않기 때문에 주의해야 합니다.
cordon과 drain 모두 노드를 SchedulingDisabled 상태로 만든다는 것은 동일하나
cordon은 기존 Pod에 아무런 영향을 주지 않는 반면, drain은 기존 Pod를 제거한다는 것이 차이점입니다.
cordon
: SchedulingDisabled (O), 기존 Pod 삭제 (X)drain
: SchedulingDisabled (O), 기존 Pod 삭제 (O)개인적으로 공부하며 작성한 글로, 내용에 오류가 있을 수 있습니다.