본문 바로가기

CKA

[k8s] Taint & Toleration 정리 : Pod 스케줄링 제어와 Pending 디버깅

728x90

Taint/Toleration 한 줄 정의

  • Taint : "이 노드에는 아무나 오지 마"라고 노드가 거는 거부/제한 조건
  • Toleration: "나는 그 taint를 견딜게(허용할게)"라고 파드가 내는 입장권

노드가 막고, 파드가 예외로 들어가는 구조

NodeSelector/Affinity와 차이

  • nodeSelector/affinity: 파드가 '가고 싶은 노드'를 고르는 필터
  • taint/toleration: 노드가 '받고 싶은 파드'를 제한 (허용된 파드만 들어옴)

Taint의 구성 요소 (key=value:effect)

형식:

  • key=value:effect
  • key:effect (value 생략 가능)

effect 3종류:

1. NoSchedule

  • toleration 없는 파드는 스케줄링 불가

2. PreferNoSchedule

  • 가능하면 피함(강제는 아님)

3. NoExecute

  • 스케줄링도 막고, 이미 떠 있던 퇴고(evict) 시킬 수 있음
  • (옵션) tolerationSeconds 로 "몇 초까지 버티기" 기능

Taint 추가

kubectl taint nodes <NODE> dedicated=teamA:NoSchedule

Taint 목록 확인

kubectl describe nodes <NODE> | grep -A3 Taints

Taint 삭제

kubectl taint nodes <NODE> dedicated=teamA:NoSchedule-

같은 key로 값 바꾸기

kubectl taint nodes <NODE> dedicated=teamB:NoSchedule --overwrite

Toleration 핵심 필드

  • key, operator(Exists/Equal), value, effect
  • 가장 흔한 패턴:
    • 특정 key를 그냥 허용: operator: Exists
    • 특정 key=value만 허용: operator: Equal

정확 매칭 (Equal) : key/value/effect를 딱 맞춤

tolerations:
- key: "dedicated"
  operator: "Equal"
  value: "teamA"
  effect: "NoSchedule"

가장 빠른 (Exists) : key만 맞으면 value 무시

tolerations:
- key: "dedicated"
  operator: "Exists"
  effect: "NoSchedule"

실습

  • 노드에  Taint(NoSchedule)를 걸어서 Pod 스케줄링 막아보기
  • Toleration 없는 Pod가 Pending되는 걸 확인하고
  • Pod에 Toleration을 추가해 스케줄링 되게 만들기
  • 마지막에 정리(taint 제거, pod 삭제) 까지

실습 1: NoSchedul로 Pending 만들기 -> toleration으로 해결

# 0) 노드 확인
kubectl get nodes

# 1) taint 추가
kubectl taint node <NODE> dedicated=teamA:NoSchedule

# 2) toleration 없는 Pod 생성 -> Pending
kubectl run p1 --image=nginx:1.27 --restart=Never
kubectl get pod p1 -w

# 3) 원인 확인(Events)
kubectl describe pod p1

# 4) toleration 있는 Pod 생성
cat <<'EOF' > p2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: p2
spec:
  containers:
  - name: app
    image: nginx:1.27
  tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "teamA"
    effect: "NoSchedule"
EOF

kubectl apply -f p2.yaml
kubectl get p2 -o wide

 

실습 2: NoExecute + tolerationSeconds (10초 버티고 축출)

# 노드에 강제로 올릴 Pod
cat <<EOF > p3.yaml
apiVersion: v1
kind: Pod
metadata:
  name: p3
spec:
  nodeName: <NODE>
  containers:
  - name: app
    image: nginx:1.27
  tolerations:
  - key : "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoExecute"
    tolerationSeconds: 10
EOF

kubectl apply -f p3.yaml

# NoExecute taint 걸기
kubectl taint node <NODE> key1=value1:NoExecute

# 관찰
kubectl get pod p3 -w
kubectl describe pod p3

정리(원복)

kubectl delete pod p1 p2 p3 --ignore-not-found
kubectl taint nodes <NODE> dedicated=teamA:NoSchedule-
kubectl taint nodes <NODE> key1=value1:NoExecute-
728x90