kubectl taint nodes node1 gpu=true:NoSchedule
tolerations:
- key: "gpu"
operator: "Equal"
value: "true"
effect: "NoSchedule"
방향이 어피니티와 반대다
어피니티 파드가 "나는 이런 노드로 가고 싶다"
테인트 노드가 "나는 아무나 안 받는다"
톨러레이션 파드가 "나는 그 거부를 견딜 수 있다"
effect 세 가지
- NoSchedule — 새로 배치되지 않는다 (기존 파드는 유지)
- PreferNoSchedule — 가급적 피한다 (강제 아님)
- NoExecute — 기존 파드도 쫓아낸다
- tolerationSeconds 를 주면 그 시간만 버틴다
쓰임
- GPU 노드를 전용으로 — GPU 파드만 톨러레이션을 갖는다
- 컨트롤 플레인 노드에 일반 워크로드가 안 뜨게 (기본 테인트)
- 문제 있는 노드를 격리 (cordon/drain 과 함께)
- 노드가 NotReady 가 되면 쿠버네티스가 자동으로 NoExecute 테인트를 건다
- 그래서 파드가 다른 노드로 옮겨간다
톨러레이션은 유도가 아니다
톨러레이션이 있다고 '그 노드로 간다' 는 뜻이 아니다 '갈 수 있다' 는 뜻일 뿐이다
GPU 노드에 GPU 파드를 보내고 싶으면
테인트 + 톨러레이션 다른 파드가 못 오게 막는다
nodeAffinity/셀렉터 GPU 파드가 그리로 가게 유도한다
둘을 함께 써야 한다
톨러레이션만 걸면 GPU 파드가 일반 노드에 떠 버린다
cordon 과 drain
kubectl cordon node1 # 새 파드를 안 받는다 (기존은 그대로)
kubectl drain node1 --ignore-daemonsets --delete-emptydir-data
kubectl uncordon node1
cordon 은 내부적으로 unschedulable 표시를 한다 drain 은 파드를 다른 곳으로 옮긴다 (퇴출 API 사용)
노드 업그레이드·교체의 표준 절차다
- cordon → drain → 작업 → uncordon
자동으로 걸리는 테인트
쿠버네티스가 노드 상태에 따라 스스로 테인트를 건다
node.kubernetes.io/not-ready NoExecute
node.kubernetes.io/unreachable NoExecute
node.kubernetes.io/memory-pressure NoSchedule
node.kubernetes.io/disk-pressure NoSchedule
node.kubernetes.io/unschedulable NoSchedule (cordon)
모든 파드에는 not-ready·unreachable 에 대한
tolerationSeconds: 300 이 자동으로 붙는다
→ 노드가 죽어도 5분은 버틴 뒤에 옮겨간다
이 값을 줄이면 복구가 빨라지지만,
일시적 네트워크 흔들림에도 파드가 옮겨 다니게 된다
drain 이 안 끝날 때
-
① PDB 가 막고 있다 — kubectl get pdb -A
-
② 컨트롤러 없는 파드가 있다 — --force 가 필요하다 (데이터 손실 주의)
-
③ emptyDir 데이터가 있다 — --delete-emptydir-data
-
④ 종료가 오래 걸린다 — 유예 시간 · PID 1 시그널 처리
-
순서대로 확인한다. ①이 가장 흔하다
면접 함정
- ❌ "톨러레이션을 주면 그 노드로 간다" → 갈 수 있을 뿐이다. 유도는 어피니티가 한다.
- ❌ "테인트를 걸면 기존 파드도 나간다" → NoExecute일 때만이다.