Study/K8s

[Kubernetes] 리소스 스케쥴링(Scheduling) - Taint & Tolerant, Node Affinity

Omoknooni 2024. 5. 29. 12:47

Taint & Tolerant

어떤 pod가 특정 node에 schedule되는 것을 제한하는 것 (set restriction)

즉, 특정 node가 특정 pod만 수용할 수 있도록 하거나 특정 node에 특정 pod가 배치되지 않도록 하는 수단이다.

 

Taint는 node에 지정하는 요소이고, Tolerant는 pod에 지정하는 요소다.

이해하기 쉽게 보자면, Taint는 '벌레 퇴치 스프레이', 그리고 Tolerant는 Taint에 적응할 수 있는 면역력으로 생각할 수 있다.

 

 

Taint와 Tolerant를 이해하기 위해 아래와 같이 Node와 Pod들이 있다고 가정해본다.

 

 

Node라는 사람 객체에 Pod라는 벌레 객체가 붙는다. 이때 Node에 예를 들어 app=prd 라는 Taint를 적용하게되면, 이 taint에 대한 면역력이 없는 Pod들은 taint 처리가된 Node에 붙을 수 없게된다.

즉, 1번 pod는 node01에 Scheduling되는 것이다.


이러한 Taint와 Tolerant는 완벽한 격리 Scheduling을 지원하지는 않는다. Pod가 taint된 Node에만 반드시 적용된다는 보장이 없다는 것이다.

위 예시에 따르면 app=prd Taint가 적용된 node01에는 tolerant가 지정된 1번 Pod만 배치될 수 있지만, 1번 Pod는 항상 node01에만 배치가 된다는 것은 아니다라는 것이다.

 

Taint

Taint는 label과 유사하게 key-value 쌍의 값으로 이루어져 있다. 여기에 taint-effect라는 요소가 뒤에 더 붙게 된다.

 

taint-effect는 '이 taint에 tolerant하지 않은 pod들은 어떻게 처리할 것인가'에 대한 설정으로, 이 field에 들어올 수 있는 값은 3가지가 존재한다.

  • NoSchedule : tolerant하지 않은 pod들은 이 Node에 Schedule되지 않도록 한다.
  • PreferNoSchedule : tolerant하지 않은 pod들은 이 Node에 Schedule되는 것을 피한다. (NoSchedule과는 다르게 완전 보장을 하지 않음)
  • NoExecute : 새롭게 생성되는 tolerant하지 않은 pod는 이 Node에 Schedule되지 않고, 이미 이 Node에 배치된 Pod 중 tolerant하지 않은 것들은 Evict 처리한다.

 

 

Node에 Taint 처리하는 kubectl 커맨드는 아래와 같다. taint 삭제도 label과 마찬가지로 동일하게 삭제 가능하다.

# Node에 taint 설정
kubectl taint nodes [node명] key=value:taint-affect

# Node의 taint 삭제
kubectl taint nodes [node명] key-

 

 

 

Master Node(Control plane)에 Pod가 배치되지 않도록 하는 taint 처리가 존재한다.

(node-role.kubernetes.io/control-plane)

이때 이 taint는 삭제해서 Master Node에도 pod가 배치되도록 할 수 있으나, 가급적이면 수정하지 않는 것을 권장한다고 한다.

 

 

Tolerant

Tolerant는 taint와 동일한 key, value, effect를 사용하여 정의한다. Pod의 configuration file 부분의 spec에 tolerations field를 지정해 Tolerant를 설정할 수 있다.

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  tolerations:		# pod에 지정할 tolerant 선언
  - key: "app"
    operator: "Equal"
    value: "dev"
    effect: "NoSchedule"
  containers:
  - name: my-container
    image: my-image

 

 

위 예시는 pod에 app=dev라는 taint에 대해 toleration을 적용시킨 모습이다. tolerations field는 앞서 살펴본 Selector 중 matchExpression field와 유사하게 key, operator, value, effect를 지정하는 모습을 확인할 수 있다.

 

 

Node Affinity

Pod를 특정 Node에 Scheduling하는 제약조건을 설정하는데 사용되는 방법으로 Node Selector와 유사하지만, OR 조건과 같은 더 복잡한 조건을 설정할 수 있다.

 

이러한 Node Affinity의 유형에는 2가지가 존재한다.

requiredDuringSchedulingIgnoredDuringExecution : 이 조건을 만족하는 Node에만 Pod를 Scheduling한다

preferredDuringSchedulingIgnoredDuringExecution : 이 조건을 만족하는 Node에 Pod Scheduling하는 것을 선호한다. (required보다 약한 선언)

 

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: az-name
            operator: In
            values:
            - az1
            - az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: env
            operator: In
            values:
            - test1
  containers:
  - name: my-container
    image: my-image

 

위 예시는 pod에 Node Affinity를 지정해준 것으로, required Affinity에 따라 'az-name' label값이 az1이나 az2인 Node에만 Scheduling되고, preferred Affinity에 따라 'env=test1' label이 있는 Node에 Scheduling되는 것을 선호하게 된다.

 

 

이러한 Node Affinity 역시 taint/tolerant와 마찬가지로 이 node에 배치되지 않기를 원하는 다른 Pod들이 붙을 가능성이 존재한다.