하나의 클러스터 안에 여러 개의 노드가 있을 때, 그 중 하나의 노드를 maintenance(유지보수) 목적으로 down 시켜야 하는 시나리오를 생각해 봅시다.
위의 그림처럼 하나의 클러스터 안에 4개의 노드가 있고 각각의 노드 안에 여러 개의 pod가 있다고 가정합니다.
(그림은 마지막 단계의 그림입니다. 처음에는 왼쪽부터 순서대로 [0 | 파랑, 초록 | 파랑, 보라 | 빨강, 검정] 의 pod 들이 각각의 노드 안에 있다고 가정합니다.)
파랑같이 여러 개가 존재하는 파드는 replicaset에 의해 관리되는 파드이고, 초록, 보라, 빨강, 검정 같이 한 개씩만 존재하는 색상의 파드는 단일 파드입니다.
하나의 레플리카셋에 있는 pod는 같은 애플리케이션을 서비스 합니다.
우리는 왼쪽에서 두 번째 노드를 down 시킬 것입니다. 노드가 다운되면 그 안에 있던 파랑, 초록 파드도 접근이 불가능해집니다.
파란색 pod는 replicaset에 속하는 pod 라서 다른 노드에 있는 해당 pod를 통해 서비스를 받을 수 있기 때문에 영향을 받지 않지만, 초록색 pod를 사용하는 사용자는 해당 pod가 애플리케이션을 실행하는 유일한 pod 였기 때문에 영향을 받아 문제가 발생합니다.
쿠버네티스는 이렇게 노드가 다운된 경우, controller manager의 pod-eviction-timeout 옵션의 인자 만큼의 시간 만큼 기다립니다. (기본 값 5분)
kube-controller-manager -- pod-eviction-timeouts=5m0s
노드가 시간 안에 online으로 돌아오면 kubelet이 시작되고 pod들도 다시 online 상태가 됩니다.
하지만 그 시간이 지난 후에는 pod들이 terminate 됩니다.
이 때 replicaset에 속하는 파드는 다른 노드에 재생성되지만, 그렇지 않은 파드(초록)은 재생성되지 않습니다.
Drain
kubectl drain node-01
이런 경우를 방지하기 위해 drain 명령어를 사용하여 다운시킬 노드 안의 모든 리소스를 다른 노드로 옮길 수 있습니다. (정상적으로 terminated 된 후에 다른 노드에서 recreated)
drain 명령어를 사용하면 아래와 같은 프로세스가 실행됩니다.
- Pod 이동:
kubectl drain
명령은 노드에 있는 모든 Pod를 다른 노드로 안전하게 이동합니다. 이것은 노드를 비우는 프로세스입니다. Pod는 다른 노드로 옮겨지거나, 다른 노드에 새로 생성될 수 있습니다. - Cordon 됨(주의): 명령을 실행하면 노드가 "cordon"되며 더 이상 새로운 Pod가 해당 노드에 예정되지 않습니다. 드레인 프로세스 동안 노드에 새로운 Pod가 예정되지 않도록 해야하기 때문입니다.
- Termination Grace Period: 드레인 프로세스 중에 Pod가 안전하게 이동하도록
TerminationGracePeriodSeconds
에 정의된 기간 동안 대기합니다. 기본적으로 이 값은 30초입니다. 드레인 중에 작동 중인 Pod가 자동으로 중지되는 것을 방지합니다. - 예약된 Pod 제외: 특별한 경우, 일부 Pod를 드레인 대상에서 제외할 수 있습니다. 이는
kubectl drain
명령에-ignore-daemonsets
및-force
와 같은 옵션을 사용하여 구현됩니다.
해당 노드는 제한을 풀기 전까지 cordoned / unschedulable 상태를 유지하여 임의의 pod가 해당 노드에 예약되지 않도록 한다.
모든 리소스가 안전하게 이동되면 이제 해당 노드를 down 시키고 업그레이드를 진행시킬 수 있습니다.
업그레이드가 끝났으면 스케쥴러가 다시 해당 노드에 파드를 배정할 수 있게 해주어야 합니다.
kubectl uncordon node-01
위의 명령어로 해당 노드가 다시 online으로 돌아와도 아직은 cordoned / unschedulable 합니다. 다시 pod가 예약될 수 있도록 uncordon 시켜야 한다.
cordon
kubectl cordon node-01
drain 외에도 cordon 이라는 명령어를 사용하여 노드를 임의로 예약할 수 없도록 표시할 수 있습니다.
drain과 달리 노드에 존재하는 pod를 종료하거나 이동시키지 않고, 새로운 pod가 스케쥴되는 것을 막습니다.
- cordon?
- 보통 노드 같은 시스템 컴포넌트에 적용됨.
- 노드를 "코르던" 상태로 설정하면 그 노드에 새로운 POD가 예약되지 않음. 이렇게 노드를 차단하는 것은 유지보수 또는 작업을 수행하기 전에 해당 노드에서 실행 중인 POD를 안전하게 이동시키는 데 사용됩니다.
- 무언가를 격리하거나 차단하는 것을 의미.
Demo
replicaset에 의해 control 되는 pod가 아니고 단독 pod 라면 해당 pod가 존재하는 노드를 drain 하려고 할 때 에러 메세지가 발생합니다.
참고
Certified Kubernetes Adiminstrtor(CKA) with Practice Tests by Mumshad Mannambeth, KodeKloud Training