Scheduling - Taint & Toleration

2025. 12. 29. 11:52·CKA

이번 글은 파드(Pod)가 어떤 노드(Node)에 배치될 수 있는지 제한하는 대표 기능인 Taint(테인트) 와 Toleration(톨러레이션) 을 정리합니다.
초보자가 헷갈리기 쉬운 주제라서, 강의에서 사용한 “벌레(파드) ↔ 사람(노드) ↔ 기피제(테인트)” 비유를 그대로 가져오되, 실무에서 자주 실수하는 포인트(“테인트/톨러레이션만으로는 특정 노드에 ‘고정 배치’가 안 됨”)까지 함께 다듬어 설명하겠습니다.

Taint: 오염

Toleration: 내성


1) 비유로 이해하기: 테인트(오염) vs 톨러레이션(내성)

  • 노드에 테인트를 바른다: “이 노드는 특정 조건을 만족하는 파드만 받아”
  • 파드에 톨러레이션을 준다: “이 파드는 그 테인트를 견딜 수 있어(내성 있음)”

즉, 결정 요소는 2개입니다.

  1. 노드에 어떤 테인트가 있는가
  2. 파드가 그 테인트를 허용(톨러레이션)하는가

중요: 이 기능은 “보안/침입 방지” 개념이 아니라, 스케줄링 제약(배치 제한) 기능입니다.


2) 기본 상황: 아무 제약이 없으면 스케줄러는 균형 있게 배치한다

예를 들어 노드가 3개(node1, node2, node3)이고 파드가 A,B,C,D라면,
기본적으로는 제약이 없으니 스케줄러가 분산 배치(균형)하려고 합니다.


3) 요구사항: node1은 특정 워크로드(예: D) 전용으로 쓰고 싶다

목표

  • node1에는 원치 않는 파드(A,B,C) 가 올라오면 안 됨
  • node1에는 특정 파드(D) 는 올라올 수 있어야 함

이때 사용하는 것이:

  • node1에 테인트 설정 (다른 파드를 밀어냄)
  • pod D에 톨러레이션 설정 (D만 통과)

4) 테인트는 노드에 설정한다: kubectl taint nodes

예: app=blue 라는 테인트를 node1에 설정하고, “견디지 못하면 스케줄하지 마라(NoSchedule)” 효과를 준다.

kubectl taint nodes node1 app=blue:NoSchedule

테인트 효과(Effect) 3가지

1) NoSchedule

  • 톨러레이션 없는 파드는 해당 노드에 스케줄링되지 않음
  • 가장 흔히 쓰는 “출입 금지” 모드

2) PreferNoSchedule

  • “가급적 스케줄하지 말자” (소프트 제약)
  • 상황에 따라 스케줄될 수도 있음(보장 X)

3) NoExecute

  • 신규 스케줄링 차단 + 기존에 돌고 있던 파드도 톨러레이션 없으면 축출(evict)
  • 노드를 전용화하거나 격리할 때 강력함

5) 톨러레이션은 파드에 설정한다: spec.tolerations

pod D만 node1의 app=blue:NoSchedule를 견디게 만들려면 파드 매니페스트에 톨러레이션을 추가합니다.

apiVersion: v1
kind: Pod
metadata:
  name: pod-d
spec:
  tolerations:
  - key: "app"
    operator: "Equal"
    value: "blue"
    effect: "NoSchedule"
  containers:
  - name: nginx
    image: nginx:1.27

강의에서 강조한 것처럼, 예제에서는 값을 " "로 감싸서 보여주곤 합니다(문자열로 명확히).
핵심은 key/value/effect가 노드에 준 테인트와 일치해야 한다는 점입니다.


6) 동작 흐름: 왜 A/B/C는 튕기고 D만 통과하나?

  • node1: app=blue:NoSchedule 테인트가 있음
  • 기본 파드(A/B/C): 톨러레이션 없음 → node1에 “들어갈 수 없음”
  • pod D: app=blue:NoSchedule 톨러레이션 있음 → node1에 “들어갈 수 있음”

그래서 스케줄러가 node1을 후보로 봤을 때:

  • A/B/C는 node1에서 거절 → node2/3로 감
  • D는 node1에서도 OK → node1에 배치될 수 있음

7) 가장 중요한 함정: 테인트/톨러레이션만으로 “D는 반드시 node1”이 되지 않는다

여기가 초보자들이 가장 많이 오해하는 부분입니다.

  • 테인트/톨러레이션은 노드 입장에서 “누가 들어올 수 있는가”를 제한할 뿐입니다.
  • 파드 입장에서 “반드시 이 노드로 가라”를 지시하지 않습니다.

즉, node1이 D를 “받을 수는 있어도”,
node2/node3에 아무 제약이 없다면 D는 그쪽으로도 배치될 수 있습니다.

“D를 node1에 고정”하려면?

다음 강의에서 언급된 것처럼 Node Affinity(노드 선호/고정) 또는 더 단순하게는:

  • nodeSelector
  • nodeAffinity (requiredDuringScheduling...)

같은 “파드 → 노드 방향의 제약”이 추가로 필요합니다.

예: node1에 라벨을 붙이고(예: dedicated=blue), pod D에 nodeSelector를 추가하면 “거의 전용 노드”가 됩니다.

kubectl label node node1 dedicated=blue
kubectl taint nodes node1 app=blue:NoSchedule
spec:
  nodeSelector:
    dedicated: "blue"
  tolerations:
  - key: "app"
    operator: "Equal"
    value: "blue"
    effect: "NoSchedule"
  • nodeSelector: D는 dedicated=blue 노드로만 감
  • tolerations: 그 노드가 app=blue 테인트가 있어도 견딤

이 조합이 “전용 노드” 구현의 정석 중 하나입니다.


8) NoExecute 자세히: “기존 파드 축출” + tolerationSeconds

NoExecute는 노드에 테인트가 적용되는 순간:

  • 톨러레이션 없는 기존 파드는 퇴출(evict)
  • 톨러레이션이 있으면 계속 실행 가능

또 하나 중요한 옵션이 있습니다.

tolerationSeconds

NoExecute일 때, “얼마 동안만 버티고 나가라”를 줄 수 있습니다.

tolerations:
- key: "app"
  operator: "Equal"
  value: "blue"
  effect: "NoExecute"
  tolerationSeconds: 60

의미:

  • 테인트가 붙은 후 60초는 버티고, 그 뒤에는 축출될 수 있음

9) 컨트롤 플레인 노드에 파드가 안 올라가는 이유: 기본 테인트

강의 마지막 포인트도 매우 중요합니다.

쿠버네티스 클러스터를 구성하면 보통 control-plane(옛 표현: master) 노드에 기본 테인트가 걸려서 일반 워크로드가 스케줄링되지 않습니다.
(실제로는 클러스터/버전에 따라 키가 node-role.kubernetes.io/control-plane 형태인 경우가 많습니다.)

확인은 이렇게 합니다:

kubectl describe node <control-plane-node-name>
# 출력에서 Taints 섹션 확인

테인트를 제거할 수도 있지만(뒤에 -):

kubectl taint nodes <control-plane-node-name> node-role.kubernetes.io/control-plane:NoSchedule-

운영 관점에서는 보통 권장되지 않습니다. control-plane은 핵심 컴포넌트 안정성이 더 중요하기 때문입니다.


10) 실습/디버깅 체크리스트

“왜 파드가 Pending이지?” 같은 상황에서 아래를 보면 빠르게 원인을 잡을 수 있습니다.

  1. 파드가 어디에 배치됐는지 / Pending인지
kubectl get pods -o wide
  1. 스케줄링 실패 이유(Events가 핵심)
kubectl describe pod <pod-name>
  1. 노드의 테인트 확인
kubectl describe node <node-name>
  1. (서비스 운영 시) “원치 않는 파드가 전용 노드에 올라왔다”
  • 테인트 효과가 PreferNoSchedule인지 확인
  • 파드에 예상치 못한 톨러레이션이 붙었는지 확인
  • 정말 전용화가 목적이면 nodeSelector/nodeAffinity까지 같이 적용했는지 확인

정리

  • 테인트는 노드에, 톨러레이션은 파드에 설정한다.
  • 테인트 효과:
    • NoSchedule: 새 파드 스케줄 금지
    • PreferNoSchedule: 되도록 피함(보장 X)
    • NoExecute: 새 파드 금지 + 기존 파드 축출
  • 테인트/톨러레이션은 “노드가 받아줄 수 있는 파드”만 제한한다.
  • “특정 노드로 보내기(고정)”는 NodeAffinity/nodeSelector 같은 추가 메커니즘이 필요하다.
  • control-plane 노드에 워크로드가 안 올라가는 건 기본 테인트 때문인 경우가 많다.

 

Link to Practice Test: https://uklabs.kodekloud.com/topic/practice-test-taints-and-tolerations-2/

 

'CKA' 카테고리의 다른 글

Scheduling - Resource Limit  (0) 2025.12.29
Scheduling - Node Selector & Node Affinity  (0) 2025.12.29
Scheduling- Label & Selector  (0) 2025.12.29
Scheduling- 수동 스케줄링  (0) 2025.12.29
Core concepts - 총 정리  (1) 2025.12.29
'CKA' 카테고리의 다른 글
  • Scheduling - Resource Limit
  • Scheduling - Node Selector & Node Affinity
  • Scheduling- Label & Selector
  • Scheduling- 수동 스케줄링
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (243)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (119)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      빈 후처리기
      jpq
      김영한
      log trace
      양방향 맵핑
      cglib
      requset scope
      조회 성능 최적화
      버퍼
      gesingleresult
      Thread
      프록시
      자바
      reentarantlock
      락
      @within
      @discriminatorvalue
      JPQL
      스레드
      @args
      jdk 동적 프록시
      hibernate5module
      단방향 맵핑
      페치 조인
      @discriminatorcolumn
      WAS
      typequery
      프록시 팩토리
      Target
      고급
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    Scheduling - Taint & Toleration
    상단으로

    티스토리툴바