Kubernetes 노드에 적용된 Taint 확인 방법

KubernetesBeginner
지금 연습하기

소개

컨테이너 오케스트레이션 플랫폼인 Kubernetes 는 노드에 파드를 스케줄링하는 것을 제어하기 위해 "taints"라는 강력한 기능을 제공합니다. 이 튜토리얼에서는 Kubernetes 노드에 적용된 taint 를 확인하는 방법을 살펴볼 것입니다. 이는 Kubernetes 클러스터를 효과적으로 관리하는 데 필수적인 기술입니다.

Taint 는 특정 파드를 거부할 수 있는 특정 속성으로 노드를 표시하여, 노드의 기능과 리소스에 따라 워크로드가 적절하게 스케줄링되도록 합니다. Taint 를 확인하고 사용하는 방법을 이해하면 Kubernetes 환경에서 최적의 리소스 할당을 유지하는 데 도움이 됩니다.

테스트를 위한 Kubernetes 환경 설정

Kubernetes 노드에서 taint 를 확인하기 전에, 작동하는 Kubernetes 환경이 필요합니다. 이 튜토리얼에서는 개발 및 테스트 목적으로 가볍고 로컬 Kubernetes 클러스터를 제공하는 Minikube 를 사용합니다.

Minikube 를 설치하는 것으로 시작해 보겠습니다.

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
rm minikube-linux-amd64

이제 Minikube 가 설치되었으므로 Kubernetes 클러스터를 시작해 보겠습니다.

minikube start --driver=docker

다음과 유사한 출력을 볼 수 있습니다.

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Using the docker driver based on user configuration
📌  Using Docker driver with root privileges
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
🔥  Creating docker container (CPUs=2, Memory=2200MB) ...
🐳  Preparing Kubernetes v1.26.1 on Docker 23.0.1 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: default-storageclass, storage-provisioner
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

클러스터가 실행 중인지 확인하기 위해 노드 상태를 확인해 보겠습니다.

kubectl get nodes

다음과 유사한 출력을 볼 수 있습니다.

NAME       STATUS   ROLES           AGE    VERSION
minikube   Ready    control-plane   1m     v1.26.1

훌륭합니다! 이제 taint 를 탐색할 수 있는 작동하는 Kubernetes 환경이 있습니다. kubectl 명령은 이미 Minikube 클러스터와 함께 작동하도록 구성되어 있습니다.

Kubernetes Taint 이해

Taint 를 보기 전에, taint 가 무엇이며 Kubernetes 에서 어떻게 작동하는지 이해해 보겠습니다.

Taint 란 무엇인가요?

Taint 는 특정 파드를 거부할 수 있도록 Kubernetes 노드에 적용되는 속성입니다. Taint 를 특정 유형의 워크로드에 적합하지 않은 노드를 표시하는 레이블이라고 생각할 수 있습니다.

Taint 는 "tolerations"라는 개념과 함께 작동합니다. Taint 는 노드에 적용되는 반면, tolerations 는 파드에 적용됩니다. 노드의 taint 와 일치하는 toleration 이 있는 파드는 해당 taint 된 노드에서 스케줄링될 수 있습니다.

Taint 구조

Taint 는 세 가지 구성 요소로 구성됩니다.

  1. Key (키): taint 를 식별하는 문자열 (예: gpu, disk, network)
  2. Value (값): 키에 할당된 선택적 문자열 (예: true, high-performance)
  3. Effect (효과): 일치하는 toleration 이 없는 파드를 처리하는 방법을 정의합니다.

가장 일반적인 taint 효과는 다음과 같습니다.

  • NoSchedule: 일치하는 toleration 이 없는 새 파드는 노드에서 스케줄링되지 않습니다.
  • PreferNoSchedule: 시스템은 일치하는 toleration 이 없는 파드를 노드에 배치하지 않으려고 시도하지만 보장되지는 않습니다.
  • NoExecute: 일치하는 toleration 이 없는 새 파드는 노드에서 스케줄링되지 않으며, 일치하는 toleration 이 없는 기존 파드는 제거됩니다.

다음은 taint 의 구문입니다.

  • 값을 포함하는 경우: key=value:effect
  • 값을 포함하지 않는 경우: key:effect

Kubernetes 클러스터의 일부 노드에는 기본 taint 가 있습니다. 예를 들어, control plane 노드는 일반적으로 node-role.kubernetes.io/control-plane:NoSchedule로 taint 되어 일반 워크로드가 해당 노드에서 스케줄링되는 것을 방지하여 시스템 구성 요소에 대한 리소스를 보존합니다.

Minikube 노드에 기본 taint 가 있는지 확인해 보겠습니다.

kubectl describe node minikube | grep -A3 Taints

다음과 유사한 출력을 볼 수 있습니다.

Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false
Lease:
  HolderIdentity:  minikube

이 출력은 Minikube 노드가 control plane 노드이므로 일반 파드가 해당 노드에서 스케줄링되는 것을 방지하는 taint 를 가지고 있음을 보여줍니다.

Kubernetes 노드의 Taint 보기

이제 taint 가 무엇인지 이해했으므로 Kubernetes 노드에 적용된 taint 를 보는 다양한 방법을 살펴보겠습니다.

방법 1: kubectl describe 사용

노드의 taint 를 보는 가장 자세한 방법은 kubectl describe node 명령을 사용하는 것입니다.

kubectl describe node minikube

이 명령은 노드에 대한 포괄적인 정보를 출력합니다. Taint 에만 집중하려면 grep을 사용할 수 있습니다.

kubectl describe node minikube | grep -A1 Taints

예시 출력:

Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false

방법 2: custom-columns 와 함께 kubectl get 사용

kubectl get nodes 명령을 사용자 지정 출력 열과 함께 사용하여 taint 만 표시할 수 있습니다.

kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

예시 출력:

NAME       TAINTS
minikube   [map[effect:NoSchedule key:node-role.kubernetes.io/control-plane]]

방법 3: JSONPath 와 함께 kubectl get 사용

또 다른 방법은 JSONPath 를 사용하여 taint 정보를 추출하는 것입니다.

kubectl get nodes minikube -o jsonpath='{.spec.taints}'

예시 출력:

[{"effect":"NoSchedule","key":"node-role.kubernetes.io/control-plane"}]

가독성을 높이기 위해 출력을 JSON 형식으로 지정할 수 있습니다.

kubectl get nodes minikube -o jsonpath='{.spec.taints}' | jq .

jq가 설치되어 있지 않은 경우 다음 명령으로 설치할 수 있습니다.

sudo apt-get update && sudo apt-get install -y jq

예시 형식화된 출력:

[
  {
    "effect": "NoSchedule",
    "key": "node-role.kubernetes.io/control-plane"
  }
]

방법 4: YAML 출력과 함께 kubectl get 사용

YAML 형식으로 전체 노드 사양을 보고 taint 를 검색할 수도 있습니다.

kubectl get node minikube -o yaml | grep -A5 taints:

예시 출력:

  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/control-plane
  unschedulable: false
status:
  addresses:

이러한 각 방법은 동일한 정보를 다른 형식으로 제공합니다. 가독성과 정보를 사용할 계획에 따라 필요에 가장 적합한 방법을 선택하십시오.

Taint 추가 및 제거

이제 taint 를 보는 방법을 알았으므로 taint 를 추가하고 제거하는 방법을 배우겠습니다. 이는 파드 스케줄링을 제어하거나 유지 관리를 위해 노드를 준비해야 할 때 일반적인 작업입니다.

노드에 Taint 추가

노드에 taint 를 추가하는 구문은 다음과 같습니다.

kubectl taint nodes <node-name> <key>=<value>:<effect>

Minikube 노드에 GPU 가 있음을 표시하는 taint 를 추가해 보겠습니다.

kubectl taint nodes minikube gpu=true:NoSchedule

다음과 같은 출력을 볼 수 있습니다.

node/minikube tainted

이제 taint 가 추가되었는지 확인해 보겠습니다.

kubectl describe node minikube | grep -A3 Taints

예시 출력:

Taints:             gpu=true:NoSchedule
                    node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false
Lease:

보시다시피, 이제 노드에는 두 개의 taint 가 있습니다. 원래의 control-plane taint 와 새로운 GPU taint 입니다.

노드에서 Taint 제거

Taint 를 제거하려면 동일한 taint 정의에 빼기 기호 (-) 를 추가합니다.

kubectl taint nodes <node-name> <key>=<value>:<effect>-

방금 추가한 GPU taint 를 제거해 보겠습니다.

kubectl taint nodes minikube gpu=true:NoSchedule-

다음과 같은 출력을 볼 수 있습니다.

node/minikube untainted

Taint 가 제거되었는지 확인해 보겠습니다.

kubectl describe node minikube | grep -A3 Taints

예시 출력:

Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false
Lease:
  HolderIdentity:  minikube

이제 노드는 다시 control-plane taint 만 갖게 되었습니다.

Taint 를 언제 사용해야 하는가

Taint 는 다음과 같은 몇 가지 시나리오에서 특히 유용합니다.

  1. 특수 하드웨어: 특수 하드웨어 (예: GPU) 가 있는 노드를 taint 하여 해당 하드웨어를 필요로 하는 워크로드만 해당 노드에서 스케줄링되도록 합니다.
  2. 노드 유지 관리: 유지 관리를 수행하기 전에 taint 를 추가하여 새 파드가 스케줄링되지 않도록 합니다.
  3. 보안 격리: 보안상의 이유로 특정 워크로드를 다른 워크로드와 분리합니다.
  4. 리소스 최적화: 최적의 리소스 활용을 위해 특정 워크로드 유형에 노드를 할당합니다.

Taint 를 보고, 추가하고, 제거하는 방법을 이해함으로써 Kubernetes 클러스터에서 파드 스케줄링을 관리하기 위한 기본적인 지식을 얻었습니다.

Toleration 작업

이제 taint 가 어떻게 작동하는지 이해했으므로, taint 가 있는 노드에서 파드를 스케줄링할 수 있게 해주는 메커니즘인 toleration 을 살펴보겠습니다.

Toleration 이해

Toleration 은 파드 사양에 지정되며, 일치하는 taint 가 있는 노드에서 파드를 스케줄링할 수 있도록 합니다. Toleration 은 다음으로 구성됩니다.

  • key: taint key 와 일치합니다.
  • operator: Equal (key 와 value 일치) 또는 Exists (key 만 일치)
  • value: 일치시킬 값 ( Equal 연산자 사용 시)
  • effect: 일치시킬 effect, 또는 모든 effect 와 일치시키려면 비워 둡니다.
  • tolerationSeconds: 일치하는 NoExecute taint 가 있는 노드에서 파드가 유지될 수 있는 선택적 기간

Toleration 이 있는 파드 생성

control-plane taint 를 toleration 하는 파드를 생성해 보겠습니다. 먼저, 파드에 대한 YAML 파일을 생성해 보겠습니다.

nano ~/project/toleration-pod.yaml

이제 파일에 다음 내용을 추가합니다.

apiVersion: v1
kind: Pod
metadata:
  name: toleration-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest
  tolerations:
    - key: "node-role.kubernetes.io/control-plane"
      operator: "Exists"
      effect: "NoSchedule"

이 파드 사양에는 노드의 control-plane taint 와 일치하는 toleration 이 포함되어 있습니다. 파일을 저장하고 종료합니다 (nano 에서 Ctrl+O, Enter를 누른 다음 Ctrl+X를 누릅니다).

이제 파드를 생성해 보겠습니다.

kubectl apply -f ~/project/toleration-pod.yaml

다음과 같은 출력을 볼 수 있습니다.

pod/toleration-pod created

파드가 노드에서 스케줄링되었는지 확인해 보겠습니다.

kubectl get pods -o wide

예시 출력:

NAME             READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
toleration-pod   1/1     Running   0          12s   10.244.0.5   minikube   <none>           <none>

파드는 control-plane taint 와 일치하는 toleration 이 있기 때문에 minikube 노드에서 실행 중입니다.

Toleration 이 없는 파드로 테스트

비교를 위해 toleration 이 없는 파드를 생성해 보겠습니다.

nano ~/project/no-toleration-pod.yaml

다음 내용을 추가합니다.

apiVersion: v1
kind: Pod
metadata:
  name: no-toleration-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest

파일을 저장하고 종료한 다음 파드를 생성합니다.

kubectl apply -f ~/project/no-toleration-pod.yaml

이제 파드 상태를 확인해 보겠습니다.

kubectl get pods -o wide

파드가 Pending 상태로 유지되는 것을 알 수 있습니다.

NAME               READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
no-toleration-pod  0/1     Pending   0          12s   <none>       <none>     <none>           <none>
toleration-pod     1/1     Running   0          2m    10.244.0.5   minikube   <none>           <none>

파드가 왜 Pending 상태인지 확인해 보겠습니다.

kubectl describe pod no-toleration-pod

Events 섹션에서 다음과 유사한 내용을 볼 수 있습니다.

Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  45s   default-scheduler  0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.

이는 파드가 control-plane taint 를 toleration 하지 않기 때문에 스케줄링할 수 없음을 확인합니다.

정리

생성한 파드를 정리해 보겠습니다.

kubectl delete pod toleration-pod no-toleration-pod

다음과 같은 출력을 볼 수 있습니다.

pod "toleration-pod" deleted
pod "no-toleration-pod" deleted

축하합니다! 이제 Kubernetes 에서 파드 스케줄링을 제어하기 위해 taint 와 toleration 이 함께 작동하는 방식을 이해했습니다.

요약

이 실습에서는 Kubernetes taint 와 toleration 을 사용하여 클러스터에서 파드 스케줄링을 제어하는 방법을 배웠습니다. 다음은 수행한 작업입니다.

  1. Minikube 를 사용하여 Kubernetes 환경을 설정했습니다.
  2. taint 의 개념과 파드 스케줄링에 미치는 영향을 이해했습니다.
  3. Kubernetes 노드에서 taint 를 보는 다양한 방법을 탐색했습니다.
  4. kubectl 명령을 사용하여 노드에서 taint 를 추가하고 제거했습니다.
  5. tainted 노드와 상호 작용하는 방식을 확인하기 위해 toleration 이 있는 파드와 없는 파드를 생성했습니다.

이러한 기술은 Kubernetes 클러스터에서 워크로드 배치 및 리소스 할당을 관리하는 데 필수적입니다. Taint 와 toleration 을 적절하게 사용하면 하드웨어 요구 사항, 워크로드 특성 및 리소스 제약 조건에 따라 파드가 적절한 노드에서 스케줄링되도록 할 수 있습니다.

Kubernetes 여정을 계속 진행하면서 이 지식을 바탕으로 노드 선호도 (node affinity) 및 반선호도 (anti-affinity) 와 같은 보다 정교한 스케줄링 전략을 구현하여 클러스터 리소스를 더욱 최적화할 수 있습니다.