Fairy ' s

[K8s] Taints and Tolerations 본문

Study/K8s

[K8s] Taints and Tolerations

berafairy 2023. 8. 17. 18:43

 

  • Taint : 노드에 유지 관리 중이거나 리소스가 제한된 것과 같은 특정 특성이 있음을 나타내는 노드에 적용되는 레이블이다. taint는 노드에 적용되며, 스케줄러가 내린 결정에 영향을 미치는 데에 사용된다. (노드에 설정)
  • Toleration : 특정 taint가 있는 노드에 파드를 예약할 수 있도록 파드에 설정된 속성이다. 본질적으로 일치하는 taint가 있는 노드에서 예약되도록 파드에서 부여한 권한이며, 특정 taint에 대한 toleration이 있는 파드는 해당 taint가 있는 노드에서 예약할 수 있지만, 일치하는 toleration이 없는 다른 포드는 예약을 할 수 없다. toleration을 사용하면 어떤 파드가 어떤 노드에 배치되는지 제어하기 쉽다. (파드에 설정)

 


 세 개의 워커 노드가 있는 간단한 클러스터가 있다. 노드의 이름은 1, 2, 3이며, 이러한 오드에 배포할 수 있는 파드 세트들의 이름은 A, B, C, D이다. 파드가 생성되면 스케줄러는 파드들을 사용 가능한 워커 노드에 배치한다. 현재로서는 아무 제한이 없기 때문에 스케줄러는 모든 노드에 균등하게 균형을 맞추어 파드를 배치한다.

예시 요구사항

  • 노드 1에 원하지 않는 파드는 배치되지 않는다.
  • 노드 1에는 특정한 파드만 배치된다.

 만약 노드 1에 특정 use case나 애플리케이션을 위한 전용 리소스가 있다면, 노드 1에는 특정 애플리케이션에 속하는 파드만 배치하는 것이 좋을 것이다. 그럴 경우 해당 노드에 taint를 배치하여 모든 파드가 그 노드에 배치되는 것을 방지한다. 이 taint를 blue라고 가정해보자. 파드는 디폴트로 tolerations를 가지고 있지 않기 때문에 따로 명시해주지 않을 경우 어떠한 파드도 taint가 있는 곳에 갈 수 없다. 따라서 현재 어떤 파드도 blue taint를 찾을 수 없기 때문에 노드 1에는 어떠한 파드도 배치되지 않는다. 이것으로 '노드 1에 원하지 않는 파드는 배치되지 않는다'의 요구사항을 충족했다.

 나머지 요구사항을 충족하기 위해서는 어떠한 파드가 특정한 taint에 용인될 수 있는지 지정해야 한다. 파드 D만 노드 1에 배치되는 것을 허용하고 싶을 때, 파드 D에 toleration을 추가한다. 이렇게 되면 파드 D는 blue taint를 용인할 수 있게 되어 스케줄러가 이 파드를 노드 1에 배치할 수 있다. 노드 1은 blue taint에 대한 toleration을 가지고 있는 파드만 허용할 수 있다. 이것이 taint와 toleration이 존재할 때 파드가 스케줄링 되는 방식이다.

 스케줄러는 파드 A를 노드 1에 배치하려고 하지만 노드 1의 taint에 의해 허용되지 못해 노드 2로 배치된다. 다음으로 파드 B를 노드 1에 배치하려고 시도하지만, 똑같이 taint에 의해 허용되지 않고 다음 free 노드인 노드 3에 배치된다. 파드 C를 노드 1에 배치하는 것 또한 실패하고 노드 2에 배치된다. 마지막 파드 D는 노드 1에 대한 toleration이 있으므로 허용된다. 


Taints 적용

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

# ex
$ kubectl taint nodes node1 app=blue:NoSchedule

 kubectl taint nodes 명령을 사용해 노드에 taint를 설정하는데, 명령 뒤에 key-value 쌍으로 노드 이름과 taint를 지정한다. taint-effect는 taint가 toleration이 없는 파드를 어떻게 처리할 것인지 결정한다.

 예를 들어 노드를 blue 애플리케이션 전용으로 지정하려는 경우, key-value 쌍은 app=blue가 되고, taint-effect가 NoSchedule인 것은 toleration이 없는 파드는 taint가 있는 노드에 스케줄링되지 않는다는 것을 의미한다. 이 외에도 다음과 같은 옵션들이 있다.

  • Noschedule : toleration이 없는 파드는 taint가 있는 노드에 스케줄링 되지 않는다.
  • PreferNoSchedule : 시스템이 되도록이면 taint가 있는 노드에 파드를 배치하지 않지만, 배치를 할 수는 있다.
  • NoExcute : toleration이 없는 새로운 파드는 노드에 배치되지 않으며, 이미 노드에 존재하는 파드는 toleration이 없다면 축출된다.

 위의 시나리오가 발생하기 전 아무런 taint가 없을 시기에 파드 C가 노드 1에 배치 되었다고 가정하자. 파드 C가 노드 1에 배치된 후 taint가 생기고 파드 D에 toleration이 부여되었을 경우, 노드 1의 taint-effect를 NoExcute로 설정하게 되면 taint effect 발생 시 파드 C는 노드에서 제거된다. 파드 D는 blue taint에 toleration을 가지고 있기 때문에 노드에서 계속 실행된다.

 

Taint를 제거하기 위한 명령

$ kubectl taint nodes <node-name> <key>:<value>-

Tolerations 적용

 파드에 toleration을 추가하려면 먼저 파드의 definition file을 가져와야 한다. definition file의 spec 섹션에 tolerations 라는 섹션을 추가한다. 값은 taint를 생성했을 때 사용한 값과 동일하게 입력한다.

# pod-definition.yaml

apiVersion: v1
king: Pod
metadata:
  name: myapp-pod
spec:
  containers:
  - name: nginx-container
    image: nginx
  tolerations:
  - key: app
    operator: Equal
    value: blue
    effect: NoSchedule

 지금까지는 워커 노드만 언급했지만, 클러스터에는 마스터 노드도 있다. 마스터 노드는 파드를 호스팅하고 모든 소프트웨어를 실행할 수 있다. 쿠버네티스 클러스터가 처음 설정되면, 마스터 노드에 taint가 자동으로 설정되어 스케줄러는 마스터 노드에 파드를 스케줄링하지 않는다. 이 부분에 대해서는 직접 확인을 해볼 수도 있고, 필요 시 수정을 할 수도 있다. 그러나 마스터 서버에는 애플리케이션 워크로드를 배포하지 않는 것이 좋다. 

 마스터 노드의 taint 설정 값을 보기 위해서는 다음 명령을 실행한다.

$ kubectl describe node kubemaster | grep Taint
Taints:            node-role.kubernetes.io/master:NoSchedule

실습 도중 트러블이 발생했다. 다음 조건에 만족하는 'bee'라는 이름의 파드를 만드는 문제였다.

  • Image name: nginx
  • Key: spray
  • Value: mortein
  • Effect: NoSchedule
  • Status: Running
# bee.yaml

apiVersion: v1
kind: Pod
metadata:
  name: bee
spec:
  containers:
  - image: nginx
    name: bee
  tolerations:
  - key: spray
    value: mortein
    effect: NoSchedule
    operator: Equal

 위와 같은 옵션으로 yaml 생성 후 " kubectl create -f bee.yaml " 을 실행하면 정상적으로 Running 상태가 되어야 하는데, Event에 다음과 같은 오류가 떴다.

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

spray: mortein에 대한 toleration은 yaml을 생성할 당시 등록해주었는데 이상하게 오류가 났고, node-role.kubernetes.io/conrtol-plane 이라는 taint에 대한 toleration도 없는 것으로 판단 되었다. 어찌된 영문인지는 잘 모르겠지만 toleration에 key-value를 추가해 주었다.

  - key: node-role.kubernetes.io/control-plane
    operator: Exists
    effect: NoSchedule

이후 파드를 재생성해주니 정상적으로 Running 상태가 되었다.

'Study > K8s' 카테고리의 다른 글

[K8s] Taints and Tolerations vs Node Affinity  (0) 2023.08.24
[K8s] Node Selectors & Affinity  (0) 2023.08.23
[K8s] Labels & Selectors  (0) 2023.08.14
[K8s] Scheduling  (0) 2023.08.10
[K8s] kubectl apply command  (0) 2023.08.09
Comments