Taints와 Tolerations가 해결하는 문제: 노드에 Pod를 “밀어내는” 메커니즘
Kubernetes 스케줄러는 기본적으로 모든 노드에 Pod를 배치할 수 있다. 하지만 GPU 노드에 일반 워크로드가 올라가거나, 마스터 노드에 애플리케이션 Pod가 스케줄되면 안 되는 경우가 있다. Taint는 노드에 “이 노드는 특별하다”는 표식을 남기고, 해당 Taint를 Toleration으로 “견딜 수 있는” Pod만 스케줄되도록 하는 메커니즘이다.
Kubernetes 공식 문서는 Taints를 “노드가 특정 Pod 집합을 거부할 수 있게 하는 것”으로 정의한다. Node Affinity가 Pod를 특정 노드에 끌어당기는(attract) 것이라면, Taints는 Pod를 노드에서 밀어내는(repel) 것이다. 이 글에서는 Taint의 세 가지 Effect, Toleration 매칭 규칙, 그리고 운영 패턴을 공식 문서 기반으로 정리한다.
Taint의 구조: Key=Value:Effect
# 노드에 Taint 추가
kubectl taint nodes node1 dedicated=gpu:NoSchedule
# Taint 확인
kubectl describe node node1 | grep Taints
# Taints: dedicated=gpu:NoSchedule
# Taint 제거 (끝에 - 붙이기)
kubectl taint nodes node1 dedicated=gpu:NoSchedule-
| Effect | 동작 | 이미 실행 중인 Pod | 사용 시점 |
|---|---|---|---|
NoSchedule |
Toleration 없는 Pod 스케줄 거부 | 영향 없음 (계속 실행) | 전용 노드 분리 (GPU, DB) |
PreferNoSchedule |
가능하면 스케줄 회피 (강제 아님) | 영향 없음 | 소프트 분리 (다른 노드가 있으면 그쪽 우선) |
NoExecute |
스케줄 거부 + 기존 Pod 축출(evict) | 축출됨 (Toleration 없으면) | 노드 유지보수, 장애 노드 격리 |
Toleration 문법: Pod가 Taint를 견디는 선언
# Pod (또는 Deployment) spec에 tolerations 추가
apiVersion: apps/v1
kind: Deployment
metadata:
name: gpu-worker
spec:
template:
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
containers:
- name: worker
image: gpu-worker:latest
operator: Equal vs Exists
| operator | 매칭 조건 | value 필요 | 예시 |
|---|---|---|---|
Equal (기본) |
key, value, effect 모두 일치 | ✅ | key: "dedicated", value: "gpu", effect: "NoSchedule" |
Exists |
key만 일치 (value 무시) | ❌ | key: "dedicated", operator: "Exists", effect: "NoSchedule" |
와일드카드 Toleration
# 특정 key의 모든 value와 effect를 견딤
tolerations:
- key: "dedicated"
operator: "Exists" # value 생략 → 모든 value 매칭
# effect 생략 → 모든 effect 매칭
# 모든 Taint를 견디는 "만능" Toleration (DaemonSet에서 자주 사용)
tolerations:
- operator: "Exists" # key도 생략 → 모든 Taint 매칭
NoExecute와 tolerationSeconds: 유예 시간
NoExecute Taint가 추가되면 Toleration이 없는 기존 Pod는 즉시 축출된다. Toleration에 tolerationSeconds를 지정하면 해당 시간 동안은 노드에 머무를 수 있다.
tolerations:
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300 # 5분간 유예 후 축출
# 사용 시나리오:
# 노드 네트워크 장애 시 Pod가 즉시 다른 노드로 이동하면 불필요한 재시작이 발생
# tolerationSeconds로 일시적 장애를 견디고, 지속되면 축출
공식 문서에 따르면 tolerationSeconds를 지정하지 않으면 해당 Taint를 영구히 견딘다(축출 안 됨). 0으로 지정하면 즉시 축출된다.
Kubernetes가 자동으로 추가하는 Taint (Built-in Taints)
Kubernetes는 노드 상태에 따라 자동으로 Taint를 추가한다. 공식 문서에 명시된 주요 빌트인 Taint는 다음과 같다.
| Taint Key | Effect | 발생 조건 |
|---|---|---|
node.kubernetes.io/not-ready |
NoExecute | 노드가 Ready 상태가 아닐 때 |
node.kubernetes.io/unreachable |
NoExecute | 노드가 컨트롤 플레인과 통신 불가 |
node.kubernetes.io/memory-pressure |
NoSchedule | 노드 메모리 부족 |
node.kubernetes.io/disk-pressure |
NoSchedule | 노드 디스크 부족 |
node.kubernetes.io/pid-pressure |
NoSchedule | 노드 PID 부족 |
node.kubernetes.io/unschedulable |
NoSchedule | kubectl cordon 실행 시 |
Kubernetes는 기본적으로 모든 Pod에 not-ready와 unreachable에 대한 Toleration을 tolerationSeconds: 300으로 자동 추가한다. 즉, 노드 장애 후 5분간 유예한다.
Taint + Toleration + Node Affinity 조합
중요: Toleration은 “이 노드에 스케줄해도 된다”는 허용일 뿐, “이 노드에 반드시 스케줄하라”는 강제가 아니다. GPU Toleration이 있는 Pod가 일반 노드에 스케줄될 수 있다. 전용 노드에 반드시 배치하려면 Taint + Toleration + Node Affinity를 함께 사용해야 한다.
# GPU 전용 노드 설정
# 1. 노드에 Taint + Label 추가
kubectl taint nodes gpu-node-1 dedicated=gpu:NoSchedule
kubectl label nodes gpu-node-1 node-type=gpu
# 2. Pod에 Toleration + Node Affinity
apiVersion: apps/v1
kind: Deployment
metadata:
name: ml-training
spec:
template:
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- gpu
containers:
- name: trainer
image: ml-trainer:latest
resources:
limits:
nvidia.com/gpu: 1
| 메커니즘 | 역할 | 단독 사용 시 한계 |
|---|---|---|
| Taint + Toleration | 일반 Pod를 전용 노드에서 밀어냄 | 전용 Pod가 일반 노드에 갈 수 있음 |
| Node Affinity | Pod를 특정 노드로 끌어당김 | 일반 Pod가 전용 노드에 올라갈 수 있음 |
| Taint + Affinity 조합 | 완전한 전용 노드 격리 | — |
DaemonSet과 Taint: 모든 노드에 배포해야 하는 경우
# 모니터링 에이전트 DaemonSet — 모든 Taint를 견딤
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
spec:
template:
spec:
tolerations:
- operator: "Exists" # 모든 Taint 허용
containers:
- name: exporter
image: prom/node-exporter:latest
DaemonSet은 모든 노드에 Pod를 배치해야 하므로, operator: "Exists"로 모든 Taint를 견디는 것이 일반적이다. Kubernetes 시스템 DaemonSet(kube-proxy, CNI 등)은 빌트인 Taint에 대한 Toleration을 자동으로 갖는다.
실전 체크리스트: Taints & Tolerations 설계 7단계
- 전용 노드 식별 — GPU, 고메모리, SSD 등 특수 노드에 Taint를 추가해 일반 워크로드를 차단
- Toleration + Node Affinity 조합 — Toleration만으로는 전용 노드 강제 배치가 안 됨, 반드시 Affinity와 함께
- NoSchedule vs NoExecute 선택 — 기존 Pod를 유지하려면 NoSchedule, 즉시 축출하려면 NoExecute
- tolerationSeconds 설정 — 노드 장애 시 Pod 축출 유예 시간을 워크로드 특성에 맞게 조정
- DaemonSet에 와일드카드 Toleration — 모니터링, 로깅 에이전트는
operator: Exists - 빌트인 Taint 인지 — not-ready, unreachable의 기본 300초 유예를 이해하고 필요시 조정
- kubectl describe node로 확인 — Taint가 의도대로 적용되었는지 반드시 검증
흔한 실수 4가지와 방지법
실수 1: Toleration만 추가하고 Pod가 전용 노드에 배치되길 기대
증상: GPU Toleration이 있는 Pod가 일반 노드에 스케줄된다.
방지: Toleration은 “갈 수 있다”일 뿐 “가야 한다”가 아니다. 전용 노드 배치를 강제하려면 Node Affinity의 requiredDuringSchedulingIgnoredDuringExecution를 함께 사용한다.
실수 2: Taint의 key/value/effect를 Toleration과 정확히 맞추지 않음
증상: Toleration을 추가했는데 여전히 Pending 상태로 스케줄되지 않는다. kubectl describe pod에 node(s) had taint 메시지.
방지: operator: Equal이면 key, value, effect가 모두 정확히 일치해야 한다. 오타를 방지하려면 operator: Exists로 key만 매칭하는 것도 방법이다.
실수 3: NoExecute Taint 추가 시 기존 Pod 축출을 예상하지 못함
증상: 유지보수를 위해 Taint를 추가했더니 해당 노드의 모든 Pod가 즉시 종료되어 서비스 장애 발생.
방지: NoExecute는 기존 Pod를 축출한다. NoSchedule로 먼저 새 Pod 배치를 막고, kubectl drain으로 기존 Pod를 안전하게 이동시킨 후 유지보수한다.
실수 4: 빌트인 Taint의 기본 tolerationSeconds를 무시
증상: 노드 네트워크 순간 단절 후 5분 뒤에 Pod가 다른 노드로 이동하면서 불필요한 재시작.
방지: Stateful 워크로드(DB 등)는 not-ready/unreachable의 tolerationSeconds를 늘려(예: 600~1800초) 순간 장애를 견디게 한다. Stateless 워크로드는 기본값(300초) 또는 더 줄여 빠른 복구를 유도한다.
마무리
Taints & Tolerations는 Kubernetes 스케줄링의 “밀어내기” 메커니즘이다. NoSchedule로 새 Pod를 차단하고, NoExecute로 기존 Pod까지 축출하며, PreferNoSchedule로 소프트 분리를 구현한다. 전용 노드 격리는 Taint + Node Affinity 조합이 필수이고, DaemonSet은 와일드카드 Toleration으로 모든 노드에 배포한다. 이 글의 모든 내용은 Kubernetes 공식 문서(Taints and Tolerations)를 근거로 한다.