노드 안전하게 drain하기

노드 안전하게 drain하기 (Safely Drain a Node)

이 페이지는 정의한 PodDisruptionBudget을 선택적으로 존중하면서 노드를 안전하게 drain하는 방법을 보여드려요.

출처: 문서

본문

시작하기 전에 (Before you begin)

이 작업은 다음 전제 조건을 충족했다고 가정해요.

  • 노드 drain 중에 애플리케이션이 고가용성일 필요가 없거나
  • PodDisruptionBudget 개념에 대해 읽었고, 필요로 하는 애플리케이션에 대해 PodDisruptionBudget을 구성했거나

(선택) 중단 예산 구성하기 (Configure a disruption budget)

유지 관리 중에도 워크로드가 사용 가능하게 유지되도록 하려면 PodDisruptionBudget을 구성할 수 있어요. drain하는 노드에서 실행되거나 실행될 수 있는 애플리케이션에 가용성이 중요하다면, 먼저 PodDisruptionBudget을 구성한 다음 이 가이드를 계속 따라가세요.

PodDisruptionBudget에 AlwaysAllow Unhealthy Pod Eviction Policy를 설정해 노드 drain 중 잘못 동작하는 애플리케이션의 퇴거를 지원하는 것이 권장돼요. 기본 동작은 drain이 진행되기 전에 애플리케이션 파드가 건강해질 때까지 기다리는 것이에요.

kubectl drain으로 노드를 서비스에서 제거하기 (Use kubectl drain to remove a node from service)

kubectl drain을 사용해 노드에 유지 관리를 수행하기 전에(예: 커널 업그레이드, 하드웨어 유지 관리 등) 노드에서 모든 파드를 안전하게 퇴거할 수 있어요. 안전한 퇴거는 파드의 컨테이너가 정상적으로 종료되도록 허용하고, 지정한 PodDisruptionBudget을 존중해요.

참고: 기본적으로 kubectl drain은 노드에서 죽일 수 없는 특정 시스템 파드를 무시해요. 자세한 내용은 kubectl drain 문서를 참고하세요.

kubectl drain이 성공적으로 반환되면, 모든 파드(이전 단락에서 설명한 제외 항목 제외)가 안전하게 퇴거됐음을 나타내요(원하는 정상 종료 기간과 정의한 PodDisruptionBudget을 존중하며). 그런 다음 물리 머신의 전원을 끄거나, 클라우드 플랫폼에서 실행 중이라면 가상 머신을 삭제해 노드를 안전하게 내려놓을 수 있어요.

참고: 새 파드가 node.kubernetes.io/unschedulable 테인트를 허용(tolerate)하면 그 파드들이 drain한 노드에 스케줄링될 수 있어요. DaemonSet이 아닌 경우 그 테인트를 허용하지 않는 것을 피하세요. 사용자나 다른 API 사용자가 파드의 nodeName 필드를 직접 설정하면(스케줄러를 우회), 파드는 지정된 노드에 바인딩되어 그 노드에서 실행돼요. 노드를 drain하고 unschedulable로 표시했더라도 말이죠.

먼저 drain하려는 노드의 이름을 식별해요. 다음으로 클러스터의 모든 노드를 나열할 수 있어요.

kubectl get nodes

다음으로 쿠버네티스에 노드를 drain하도록 지시해요.

kubectl drain --ignore-daemonsets <node name>

DaemonSet이 관리하는 파드가 있다면 노드를 성공적으로 drain하려면 kubectl--ignore-daemonsets를 지정해야 해요. kubectl drain 하위 명령 자체는 실제로 노드의 DaemonSet 파드를 drain하지 않아요. DaemonSet 컨트롤러(컨트롤 플레인의 일부)는 사라진 파드를 즉시 동등한 새 파드로 교체해요. DaemonSet 컨트롤러는 unschedulable 테인트를 무시하는 파드도 만들어, 새 파드가 drain 중인 노드에 실행될 수 있게 해요.

명령이 (오류 없이) 반환되면 노드의 전원을 끄거나(또는 동등하게 클라우드 플랫폼이면 노드를 뒷받침하는 가상 머신을 삭제) 할 수 있어요. 유지 관리 작업 중에 노드를 클러스터에 남겨둔다면, 이후에 명령을 실행해 쿠버네티스가 노드에 새 파드 스케줄링을 재개할 수 있다고 알려야 해요.

kubectl uncordon <node name>

여러 노드를 병렬로 drain하기 (Draining multiple nodes in parallel)

kubectl drain 명령은 한 번에 단일 노드에만 발급해야 해요. 하지만 서로 다른 터미널에서 또는 백그라운드에서 서로 다른 노드에 대해 여러 kubectl drain 명령을 병렬로 실행할 수 있어요. 동시에 실행되는 여러 drain 명령은 여전히 지정한 PodDisruptionBudget을 존중해요.

예를 들어 세 개의 복제본이 있는 StatefulSet이 있고 그 집합에 minAvailable: 2를 지정한 PodDisruptionBudget을 설정했다면, kubectl drain은 세 복제본 파드가 모두 건강한 경우에만 StatefulSet에서 파드를 퇴거해요. 그런 다음 여러 drain 명령을 병렬로 발급하면 쿠버네티스는 PodDisruptionBudget을 존중해 언제든지 1개(replicas - minAvailable로 계산)의 Pod만 사용 불가능하도록 보장해요. 지정된 예산 아래로 건강한 복제본 수가 떨어지게 하는 어떤 drain도 차단돼요.

Eviction API (The Eviction API)

kubectl drain을 사용하지 않는 것을 선호한다면(외부 명령 호출을 피하거나 파드 퇴거 과정을 더 세밀하게 제어하기 위해), eviction API를 사용해 프로그래밍 방식으로 퇴거를 일으킬 수도 있어요. 자세한 내용은 API 시작 퇴거(API-initiated eviction)를 참고하세요.

다음 단계 (What's next)

  • Pod Disruption Budget을 구성해 애플리케이션을 보호하는 단계를 따라가세요.

더 알아보기 (Learn more)