이번 강의는 한 문장으로 요약하면 이겁니다.
- NodeSelector: “라벨이 딱 일치하는 노드에서만 실행”
- Node Affinity: NodeSelector보다 더 표현력이 큰 “고급 조건(OR/NOT/EXISTS 등)”으로 실행 노드를 제어
그리고 중요한 결론 하나:
- 둘 다 ‘파드를 특정 노드로 보내는’ 기능이고,
- 이전에 배운 Taint/Toleration은 ‘노드가 어떤 파드를 받아줄지’ 제한하는 기능입니다. (방향이 반대)
1) 문제 상황: 큰 노드가 1대뿐인데, 데이터 처리 파드가 작은 노드로 갈 수도 있다
클러스터에 노드가 3개 있다고 합시다.
- node1: 큰 노드(고사양)
- node2, node3: 작은 노드(저사양)
데이터 처리 워크로드(리소스 많이 필요)가 있는데, 아무 제약이 없으면 스케줄러는 기본적으로 분산 배치를 하려 해서 node2나 node3로도 갈 수 있습니다.
그래서 “이 파드는 큰 노드에서만 돌려라”가 필요합니다.
2) NodeSelector: 가장 단순한 해결책 (정확히 일치, AND만 가능)
(1) 노드에 라벨을 붙인다
쿠버네티스는 “어떤 노드가 큰 노드인지”를 스스로 알지 못합니다.
우리가 노드에 라벨을 붙여서 알려줘야 합니다.
kubectl label node node1 size=large
(2) 파드에 nodeSelector를 지정한다
apiVersion: v1
kind: Pod
metadata:
name: data-processor
spec:
nodeSelector:
size: large
containers:
- name: app
image: your-data-processing-image
이제 스케줄러는 size=large 라벨이 있는 노드(node1)로만 파드를 배치합니다.
NodeSelector의 한계
NodeSelector는 사실상 “정확히 같은 라벨”만 가능하고, 조건 표현이 제한적입니다.
- “large 또는 medium”
- “small이 아닌 모든 노드”
- “size 라벨이 있는 노드”
- “지역은 ap-northeast-2 이면서, 디스크 타입이 ssd인 노드” 같은 복합 조건
이런 건 NodeSelector만으로는 어렵습니다.
3) Node Affinity: 복잡한 조건(OR/NOT/EXISTS)을 표현하는 고급 기능
NodeSelector와 같은 목적(특정 노드에만 배치)이지만, 표현식 기반으로 더 유연합니다.
NodeSelector를 Node Affinity로 똑같이 표현하면
아래는 “size=large 인 노드에만 배치”를 NodeAffinity로 쓴 것입니다.
apiVersion: v1
kind: Pod
metadata:
name: data-processor
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: size
operator: In
values:
- large
containers:
- name: app
image: your-data-processing-image
구조만 보면 복잡해 보이지만 의미는 단순합니다.
affinity.nodeAffinity: 노드에 대한 선호/제약requiredDuringScheduling...: 스케줄링할 때 “반드시 만족해야 하는 조건”matchExpressions: 조건식들operator: In+values: [large]: size 라벨 값이 large인 노드
4) Node Affinity의 “연산자(operator)”가 핵심이다
1) In: OR 조건 구현 (large 또는 medium)
- key: size
operator: In
values: ["large", "medium"]
2) NotIn: 제외 조건 (small이 아닌 것)
- key: size
operator: NotIn
values: ["small"]
3) Exists: “그 라벨이 존재하는 노드면 OK”
- key: size
operator: Exists
Exists는 값을 비교하지 않으므로values가 필요 없습니다.
강의에서 “작은 노드는 size 라벨 자체가 없다” 같은 상황이면,Exists로 “size 라벨이 있는 노드(=중/대형)”만 타겟팅할 수 있습니다.
5) “requiredDuringSchedulingIgnoredDuringExecution” 이 긴 이름의 뜻을 정확히 분해하기
이 부분이 가장 헷갈리는데, 문장을 쪼개면 명확합니다.
A) DuringScheduling = “스케줄링 시점(파드가 배치될 때)”
파드가 아직 노드에 없고, 지금 막 배치될 때 조건을 체크합니다.
B) Required = “반드시 만족해야 한다”
조건을 만족하는 노드가 없으면:
- 파드는 스케줄되지 않고 Pending에 머뭅니다.
C) IgnoredDuringExecution = “실행 중에는 무시한다”
파드가 이미 어떤 노드에 올라가서 실행 중인 상태에서
- 노드 라벨이 바뀌거나
- 조건이 더 이상 맞지 않게 되더라도
기본적으로 파드를 쫓아내지 않습니다. 계속 실행됩니다.
강의에서 말한 사례:
- 원래 node1에
size=large가 있어서 파드가 배치됨 - 나중에 관리자가 그 라벨을 제거함
- 그래도 파드는 계속 node1에서 실행됨 (IgnoredDuringExecution)
6) Node Affinity 유형 2가지(강의 기준)
1) requiredDuringSchedulingIgnoredDuringExecution
- 없으면 안 됨(강제)
- 조건 만족 노드가 없으면 Pending
2) preferredDuringSchedulingIgnoredDuringExecution
- 되도록 그 노드로(선호)
- 조건 만족 노드가 없으면 다른 노드에도 배치 가능
즉, “배치 위치보다 실행이 더 중요”하면 preferred,
“반드시 그 노드여야만 함”이면 required를 씁니다.
7) 한 문장으로 정리 (시험/실무용)
- NodeSelector: 간단한 정확 매칭
- NodeAffinity: 복잡한 조건(OR/NOT/EXISTS) + 강제/선호 선택 가능
- 둘 다 공통적으로:
- 스케줄링 시점에만 강하게 작동하고,
- 기본적으로 실행 중에는(노드 라벨이 바뀌어도) 파드를 자동 이동시키지 않는다.
바로 써먹는 미니 레시피
“큰 노드에만 배치하고 싶다”
- 노드 라벨:
kubectl label node node1 size=large
- 파드: nodeSelector 또는 required nodeAffinity
“큰/중간이면 되고 작은 건 안 돼”
- nodeAffinity +
In [large, medium]또는Exists
“그 노드로 가면 좋지만, 안 되면 아무 데나”
preferredDuringSchedulingIgnoredDuringExecution
Link to Practice Test: https://uklabs.kodekloud.com/topic/practice-test-node-affinity-3/
'CKA' 카테고리의 다른 글
| Scheduling- DaemonSet (0) | 2025.12.29 |
|---|---|
| Scheduling - Resource Limit (0) | 2025.12.29 |
| Scheduling - Taint & Toleration (0) | 2025.12.29 |
| Scheduling- Label & Selector (0) | 2025.12.29 |
| Scheduling- 수동 스케줄링 (0) | 2025.12.29 |