테인트와 톨러레이션

테인트와 톨러레이션 (taint-and-toleration)

노드 어피니티(affinity)는 파드를 특정 노드 집합으로 끌어당기는 파드의 속성이에요. 테인트(taint)는 그 반대 개념으로, 노드가 일부 파드를 밀어낼 수 있게 해주죠.

톨러레이션(toleration)은 파드에 적용돼요. 톨러레이션은 스케줄러가 일치하는 테인트를 가진 파드를 스케줄링하게 허용해 줍니다. 다만 톨러레이션이 스케줄링을 '허용'할 뿐 '보장'하지는 않아요. 스케줄러는 기능의 일부로 다른 파라미터도 함께 평가하니까요.

테인트와 톨러레이션은 함께 동작해서 파드가 부적절한 노드에 스케줄링되지 않게 해요. 노드에 하나 이상의 테인트를 적용하면, 그 노드는 자기가 가진 테인트를 톨러레이트하지 않는 파드는 받아들이지 않겠다는 표시가 되는 거예요.

개념

kubectl taint로 노드에 테인트를 추가할 수 있어요. 예를 들어,

kubectl taint nodes node1 key1=value1:NoSchedule

이 커맨드는 node1 노드에 테인트를 새겨요. 테인트는 키 key1, 값 value1, 효과(effect) NoSchedule을 가지고 있어요. 즉 일치하는 톨러레이션이 없는 파드는 node1에 스케줄링될 수 없다는 뜻이죠.

위 커맨드가 추가한 테인트를 제거하려면 이렇게 실행하면 돼요.

kubectl taint nodes node1 key1=value1:NoSchedule-

PodSpec에서 파드의 톨러레이션을 지정해요. 다음 두 톨러레이션은 모두 위 kubectl taint 줄이 만든 테인트와 '일치'하므로, 둘 중 어느 톨러레이션을 가진 파드든 node1에 스케줄링될 수 있어요.

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
tolerations:
- key: "key1"
  operator: "Exists"
  effect: "NoSchedule"

기본 Kubernetes 스케줄러는 특정 파드를 실행할 노드를 고를 때 테인트와 톨러레이션을 고려해요. 그런데 파드의 .spec.nodeName을 직접 지정하면 이 동작이 스케줄러를 우회해요. 그러면 파드는 내가 지정한 노드에 바인딩되는데, 그 노드에 NoSchedule 테인트가 있어도 말이죠. 이런 일이 발생하면서 그 노드에 NoExecute 테인트까지 설정돼 있다면, 적절한 톨러레이션이 없는 한 kubelet이 파드를 내보내 버려요.

다음은 톨러레이션을 정의한 파드의 예시예요.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:
  - key: "example-key"
    operator: "Exists"
    effect: "NoSchedule"

operator의 기본값은 Equal이에요.

톨러레이션이 테인트를 '일치'한다는 건 키가 같고 효과가 같다는 뜻인데, 여기에 다음 조건 중 하나가 추가돼요.

  • operatorExists인 경우(이때는 value를 지정하면 안 돼요), 또는
  • operatorEqual이면서 값도 같은 경우

참고:

여기에는 두 가지 특별한 경우가 있어요.

key가 비어 있으면 operator는 반드시 Exists여야 해요. 이 경우 모든 키와 값을 일치시키죠. 단, effect는 여전히 동시에 일치해야 한다는 점을 기억하세요.

effect가 비어 있으면 키가 key1인 모든 효과와 일치해요.

위 예시에서는 NoSchedule 효과를 썼는데, NoExecutePreferNoSchedule 같은 다른 효과도 사용할 수 있어요.