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들이 붙을 가능성이 존재한다.