To Be myself
[쿠버네티스] Taint and Toleration 본문
Taints and Tolerations
들어가기 앞서, 매번 헷갈리는 Node Affinity vs Taint vs Toleration 을 정리한다.
node affinity : 노드 set을 끌어들이는 파드의 속성
taint: 노드가 파드 셋을 제외시키는 속성
toleration : 파드에 적용되어 노드에 배치될 수 있는 속성. 조건이 맞는 taint가 있으면 해당 파드를 노드에 스케줄링할 수 있다.
단, 스케줄은 가능하지만 항상 완전히 보장하진 않는다.
쿠버네티스 스케줄러가 taint 나 toleration 뿐만 아니라 다른 파라미터들도 고려하기 때문이다.
taint 생성
```
kubectl taint nodes node1 key1=value1:NoSchedule
# 삭제
kubectl taint nodes node1 key1=value1:NoSchedule-
```
이 명령은 `node1`에 다음 taint를 추가한다.
- key: `key1`
- value: `value1`
- effect: `NoSchedule`
즉, 매칭되는 toleration이 없는 Pod는 node1에 스케줄될 수 없다.
해석 : key1=value 조건의 파드가 있지 않는 한 해당 노드에 스케줄링 하지 마라.
taint 매칭된 toleration
```yaml
tolerations:
- key: "key1" # taint 매칭
operator: "Equal"
value: "value1"
effect: "NoSchedule"
tolerations:
- key: "key1" # taint 매칭
operator: "Exists"
effect: "NoSchedule"
```
기본값:
- `operator` 기본값은 `Equal`
매칭 조건:
- key 동일 + effect 동일
- 그리고 다음 중 하나:
- `Exists` → value 없이 매칭
- `Equal` → value까지 동일해야 매칭
스케줄러 동작 + 예외
기본 스케줄러는 taint/toleration을 고려해서 노드를 선택한다.
하지만 `.spec.nodeName`을 직접 지정하면 스케줄러를 우회한다.
- `NoSchedule` taint가 있어도 강제로 배치됨
- 단, `NoExecute` taint가 있으면 kubelet이 Pod를 축출
Effect 종류
NoSchedule
- toleration 없으면 새 Pod 스케줄 불가
- 기존 Pod는 유지
PreferNoSchedule
- 가능하면 피함 (soft rule), 보장 X
NoExecute
- 스케줄 차단 + 기존 Pod 축출
동작:
- toleration 없음 → 즉시 축출
- toleration 있음 + 시간 없음 → 계속 유지
- toleration + `tolerationSeconds` → 일정 시간 후 축출
tolerations:
- key: "key1"
effect: "NoExecute"
tolerationSeconds: 3600
여러 taint 처리 방식
- 노드의 모든 taint 확인
- Pod가 tolerate하는 것 제거
- 남은 taint로 판단
결과:
- `NoSchedule` 남음 → 스케줄 불가
- `PreferNoSchedule`만 남음 → 가능하면 회피
- `NoExecute` 남음 → 스케줄 불가 + 실행 중이면 축출
숫자 비교 연산자
Kubernetes v1.35 alpha (기본값은 disabled)
- `Gt` (>)
- `Lt` (<)
조건:
- 둘 다 정수여야 함 (64-bit integer)
예:
tolerations:
- key: "sla"
operator: "Gt"
value: "900"
effect: "NoSchedule"
→ taint 값이 900보다 크면 매칭
주의:
- 노드 taint 값은 검증 안됨
- 파드 toleration 값만 API 서버가 검증
대표 사용 사례
Dedicated Nodes
특정 팀 전용 노드 구성
dedicated=teamA:NoSchedule
→ 해당 팀 Pod만 toleration으로 접근
※ 완전 강제하려면, label + node affinity 추가 필요
특수 하드웨어 (GPU 등)
- GPU 노드에 일반 Pod 차단
- 필요한 Pod만 toleration 추가
→ `ExtendedResourceToleration` admission controller로 자동 toleration 권장
Taint 기반 Eviction
- 노드 장애 시 Pod 자동 축출 제어
taint 기반 Eviction
특정 노드 상태가 발생하면 자동 생성되는 대표 taint:
- `node.kubernetes.io/not-ready`
- `node.kubernetes.io/unreachable`
- `node.kubernetes.io/memory-pressure`
- `node.kubernetes.io/disk-pressure`
- `node.kubernetes.io/pid-pressure`
- `node.kubernetes.io/network-unavailable`
- `node.kubernetes.io/unschedulable`
특징:
- 스케줄러는 taint만 보고 판단
- 상태 정상화 → taint 제거
- not-ready, unreachable 엔 기본적으로 NoExecute 가 붙어 축출 가능
- 근데 노드가 완전히 unreachable 이면 api 서버가 kubelet 에 삭제 결정 전달 못해서 pod 가 잠시 실행될 수도
기본 toleration 동작
- `not-ready`, `unreachable` → 기본 300초 toleration 자동 추가
→ 즉, 일반 Pod는 **5분 유지 후 축출**
- DaemonSet pod:
- 무제한 toleration 보유
- 장애에도 축출되지 않음
Device taint
- Dynamic Resource Allocation을 사용하는 클러스터에서는 노드 전체가 아니라 개별 디바이스(GPU 등)에 taint 가능
- 더 정밀한 리소스 제어 가능
핵심 요약
- taint = 노드가 Pod를 거르는 규칙
- toleration = Pod가 그 규칙을 무시하겠다는 선언
- `NoSchedule` = 새 배치 차단
- `PreferNoSchedule` = 가능하면 회피
- `NoExecute` = 실행 중 Pod까지 제거
- 여러 taint 는 필터처럼 동작해서, 스케줄링은 “남은 taint” 기준으로 결정됨
- `.spec.nodeName` 지정하면 스케줄러 무시됨
- 노드 장애, 리소스 압박 등에도 taint로 표현됨
원문: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/