6.7 테인트(Taints)와 톨러레이션(Tolerations)의 파드 할당 조건
🎯 학습 목표
- 테인트와 톨러레이션의 동작 원리 이해
- Equal/Exists 연산자별 매칭 규칙 습득
- 실제 YAML 코드 작성 및 적용 방법 학습
📋 기본 개념
테인트(Taints)
- 노드에 설정되어 특정 파드의 스케줄링을 제한하는 메커니즘
- Key, Value, Effect 3가지 요소로 구성
톨러레이션(Tolerations)
- 파드에 설정되어 테인트가 있는 노드에 스케줄링될 수 있도록 허용하는 메커니즘
- 테인트와 매칭되는 Key, Value, Effect와 Operator 설정
🛠️ 실습 환경 설정
노드에 테인트 설정
# 노드에 테인트 추가
kubectl taint nodes <node-name> key=value:NoSchedule
# 예시: worker 노드에 특수 용도 테인트 설정
kubectl taint nodes worker1 special=true:NoSchedule
kubectl taint nodes worker2 gpu=nvidia:NoSchedule
# 테인트 확인
kubectl describe node <node-name> | grep Taints
# 테인트 제거
kubectl taint nodes <node-name> key=value:NoSchedule-마스터 노드 테인트 확인
# 마스터 노드의 기본 테인트 확인
kubectl describe node master | grep Taints
# 일반적으로: node-role.kubernetes.io/master:NoSchedule🔍 매칭 규칙
Operator: Equal (값 비교)
✅ 파드 할당 성공 조건
-
모든 요소 완전 일치
- 테인트:
K=a, V=1, E=NoSchedule - 톨러레이션:
K=a, V=1, E=NoSchedule - 결과: K(O), V(O), E(O) → ✅ 배포 가능
- 테인트:
-
Value 생략 (와일드카드)
- 테인트:
K=a, V=1, E=NoSchedule - 톨러레이션:
K=a, V=-, E=NoSchedule - 결과: K(O), V(-), E(O) → ✅ 배포 가능
- 테인트:
❌ 파드 할당 거부 조건
-
Key 불일치
- 테인트:
K=a, V=1, E=NoSchedule - 톨러레이션:
K=b, V=1, E=NoSchedule - 결과: K(X), V(X), E(X) → ❌ 배포 불가
- 테인트:
-
Value만 불일치
- 테인트:
K=a, V=1, E=NoSchedule - 톨러레이션:
K=a, V=2, E=NoSchedule - 결과: K(O), V(X), E(X) → ❌ 배포 불가
- 테인트:
-
Effect만 불일치
- 테인트:
K=a, V=1, E=NoSchedule - 톨러레이션:
K=a, V=1, E=PreferNoSchedule - 결과: K(O), V(O), E(X) → ❌ 배포 불가
- 테인트:
Operator: Exists (존재 여부만 확인)
✅ 파드 할당 성공 조건
-
Key와 Effect 일치, Value 무시
- 테인트:
K=a, V=1, E=NoSchedule - 톨러레이션:
K=a, E=NoSchedule (Operator: Exists) - 결과: K(O), E(O) → ✅ 배포 가능
- 테인트:
-
Key만 일치, Effect 생략
- 테인트:
K=a, V=1, E=NoSchedule - 톨러레이션:
K=a (Operator: Exists) - 결과: K(O) → ✅ 배포 가능 (모든 Effect 허용)
- 테인트:
-
완전 와일드카드
- 테인트:
K=a, V=1, E=NoSchedule - 톨러레이션:
(빈 톨러레이션, Operator: Exists) - 결과: ✅ 모든 테인트 무시하고 배포 가능
- 테인트:
🔧 YAML 코드 예제
1. Equal 연산자 예제
기본 톨러레이션 (완전 일치)
# pod-with-toleration-equal.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-equal-match
spec:
tolerations:
- key: "special"
operator: "Equal"
value: "true"
effect: "NoSchedule"
containers:
- name: nginx
image: nginx:1.20Value 생략 톨러레이션
# pod-with-toleration-equal-wildcard.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-equal-wildcard
spec:
tolerations:
- key: "special"
operator: "Equal"
# value 생략 - 모든 값에 대해 허용
effect: "NoSchedule"
containers:
- name: nginx
image: nginx:1.202. Exists 연산자 예제
Key와 Effect 매칭
# pod-with-toleration-exists.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-exists-match
spec:
tolerations:
- key: "gpu"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: cuda-app
image: nvidia/cuda:11.0-baseKey만 매칭 (Effect 생략)
# pod-with-toleration-exists-key-only.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-exists-key-only
spec:
tolerations:
- key: "special"
operator: "Exists"
# effect 생략 - 모든 effect에 대해 허용
containers:
- name: nginx
image: nginx:1.20완전 와일드카드 (모든 테인트 허용)
# pod-with-toleration-wildcard.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-wildcard-toleration
spec:
tolerations:
- operator: "Exists"
# key, value, effect 모두 생략 - 모든 테인트 허용
containers:
- name: nginx
image: nginx:1.203. 다중 톨러레이션 예제
# pod-with-multiple-tolerations.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-multiple-tolerations
spec:
tolerations:
- key: "special"
operator: "Equal"
value: "true"
effect: "NoSchedule"
- key: "gpu"
operator: "Exists"
effect: "NoSchedule"
- key: "dedicated"
operator: "Equal"
value: "database"
effect: "NoExecute"
tolerationSeconds: 3600 # 1시간 후 eviction
containers:
- name: multi-toleration-app
image: nginx:1.204. tolerationSeconds 활용 예제
# pod-with-toleration-seconds.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-time-limit
spec:
tolerations:
- key: "maintenance"
operator: "Equal"
value: "true"
effect: "NoExecute"
tolerationSeconds: 300 # 5분 후 eviction
containers:
- name: temporary-app
image: nginx:1.20🧪 실습 시나리오
시나리오 1: 특수 목적 노드 구성
# 1. GPU 전용 노드 테인트 설정
kubectl taint nodes worker-gpu gpu=nvidia:NoSchedule
# 2. GPU 워크로드 파드 배포
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: gpu-workload
spec:
tolerations:
- key: "gpu"
operator: "Equal"
value: "nvidia"
effect: "NoSchedule"
containers:
- name: cuda-app
image: nvidia/cuda:11.0-base
command: ["sleep", "3600"]
nodeSelector:
gpu: "nvidia"
EOF
# 3. 결과 확인
kubectl get pods -o wide
kubectl describe pod gpu-workload시나리오 2: 데이터베이스 전용 노드
# 1. 데이터베이스 전용 노드 설정
kubectl taint nodes worker-db dedicated=database:NoSchedule
kubectl taint nodes worker-db dedicated=database:NoExecute
# 2. 데이터베이스 파드 배포
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: database-pod
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "database"
effect: "NoSchedule"
- key: "dedicated"
operator: "Equal"
value: "database"
effect: "NoExecute"
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
nodeSelector:
dedicated: "database"
EOF시나리오 3: 마스터 노드에 파드 배포
# 1. 마스터 노드 테인트 확인
kubectl describe node master | grep Taints
# 2. 마스터 노드에 배포 가능한 파드 생성
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: master-pod
spec:
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: nginx
image: nginx:1.20
nodeSelector:
kubernetes.io/hostname: "master"
EOF🔬 트러블슈팅 가이드
일반적인 문제와 해결방법
1. 파드가 Pending 상태로 남아있는 경우
# 문제 진단
kubectl describe pod <pod-name>
kubectl get events --sort-by='.lastTimestamp'
# 노드 테인트 확인
kubectl describe nodes | grep -A5 Taints
# 해결방법: 적절한 톨러레이션 추가 또는 테인트 제거2. 마스터 노드에 파드가 스케줄되지 않는 경우
# 마스터 노드 테인트 확인
kubectl describe node master | grep Taints
# 해결방법: 마스터 노드용 톨러레이션 추가
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"3. NoExecute 테인트로 인한 예상치 못한 파드 종료
# 이벤트 로그 확인
kubectl get events --field-selector involvedObject.name=<pod-name>
# 해결방법: tolerationSeconds 조정 또는 적절한 톨러레이션 추가
tolerations:
- key: "maintenance"
operator: "Equal"
value: "true"
effect: "NoExecute"
tolerationSeconds: 7200 # 2시간으로 연장테스트 및 검증 명령어
# 1. 모든 노드의 테인트 상태 확인
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints --no-headers
# 2. 특정 테인트가 있는 노드 찾기
kubectl get nodes -o json | jq '.items[] | select(.spec.taints[]?.key=="gpu") | .metadata.name'
# 3. 파드의 톨러레이션 확인
kubectl get pod <pod-name> -o jsonpath='{.spec.tolerations}'
# 4. 노드별 파드 배치 현황 확인
kubectl get pods -o wide --all-namespaces | grep <node-name>📚 심화 학습 내용
1. 시스템 기본 톨러레이션
쿠버네티스는 특정 상황에서 자동으로 톨러레이션을 추가합니다:
# DaemonSet은 기본적으로 다음 톨러레이션을 가집니다
tolerations:
- effect: NoSchedule
operator: Exists
- key: CriticalAddonsOnly
operator: Exists
- effect: NoExecute
operator: Exists2. PodDisruptionBudget과의 연관성
# NoExecute와 PDB 함께 사용 예제
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: db-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: database3. 클러스터 오토스케일러와 테인트
# 오토스케일러가 테인트된 노드를 고려하도록 설정
cluster-autoscaler.kubernetes.io/safe-to-evict: "true"⚠️ 주의사항 및 베스트 프랙티스
주의사항
- NoExecute 사용 시 주의: 기존 파드를 즉시 종료시킬 수 있음
- tolerationSeconds 적절히 설정: 너무 짧으면 서비스 중단, 너무 길면 리소스 낭비
- 와일드카드 톨러레이션 남용 금지: 보안상 위험할 수 있음
베스트 프랙티스
-
목적별 네이밍 컨벤션 사용:
# 좋은 예 kubectl taint nodes gpu-node1 hardware=gpu:NoSchedule kubectl taint nodes db-node1 workload=database:NoSchedule # 나쁜 예 kubectl taint nodes worker1 a=b:NoSchedule -
문서화 및 라벨링:
kubectl label nodes gpu-node1 description="GPU-enabled node for ML workloads" -
단계적 적용:
# 1단계: PreferNoSchedule로 시작 kubectl taint nodes worker1 special=true:PreferNoSchedule # 2단계: 검증 후 NoSchedule로 변경 kubectl taint nodes worker1 special=true:PreferNoSchedule- kubectl taint nodes worker1 special=true:NoSchedule
❌ 파드 할당 거부 조건
-
Key 불일치
- 테인트:
K=a, V=1, E=NoSchedule - 톨러레이션:
K=b, E=NoSchedule (Operator: Exists) - 결과: K(X) → ❌ 배포 불가
- 테인트:
-
Effect 불일치
- 테인트:
K=a, V=1, E=NoSchedule - 톨러레이션:
K=a, E=PreferNoSchedule (Operator: Exists) - 결과: K(O), E(X) → ❌ 배포 불가
- 테인트:
🎯 Effect 유형
| Effect | 설명 |
|---|---|
| NoSchedule | 가장 기본적인 설정. 노드에 테인트가 설정되어 있지 않은 경우 파드가 노드에 스케줄되지 않음. 톨러레이션을 통한 배포만 가능 |
| PreferNoSchedule | NoSchedule과 유사하지만 스케줄러에서 더 이상 할당할 수 있는 노드가 없는 경우 테인트 설정을 무시하고 스케줄함 |
| NoExecute | NoSchedule에 현재 할당된 파드에도 바로 적용되도록 스케줄을 다시 조정하는 기능 추가. 톨러레이션이 없는 파드는 모두 노드에서 제거함 |
💡 핵심 정리
Equal 연산자
- 엄격한 매칭: Key, Value, Effect가 정확히 일치해야 함
- Value 생략 가능:
-로 표시하면 Value 무시 - 하나라도 불일치하면 배포 불가
Exists 연산자
- 느슨한 매칭: Key의 존재만 확인, Value는 자동 무시
- Effect는 여전히 중요: Effect가 일치해야 함
- 완전 와일드카드 가능: 모든 항목 생략 시 모든 테인트 허용
📖 범례
| 기호 | 의미 |
|---|---|
| O | 값을 입력하며 일치 |
| X | 값을 입력하며 불일치 |
| - | 값을 입력하지 않고 생략 |
| K | Key |
| V | Value |
| E | Effect |
출처: 컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커
제작: 조훈심, 근우문, 성주
관련 강의:
- 쉽게 시작하는 쿠버네티스
- 그림으로 배우는 쿠버네티스
- 실습으로 배우는 프로메테우스