Pod를 수동으로 특정 Node에 배치하는 방법
이 강의는 스케줄러 없이 Pod를 Node에 배치하는 방법을 설명함.
보통 Kubernetes에서는 Scheduler가 어떤 Pod를 어떤 Node에 올릴지 결정함.
그런데 다음과 같은 상황이 있을 수 있음.
- 클러스터에 Scheduler가 없음
- 기본 Scheduler를 쓰지 않고
- 직접 Pod를 원하는 Node에 배치하고 싶음
이럴 때 사용할 수 있는 방법을 이해하는 것이 이 강의의 핵심임.
1. Scheduler는 원래 어떻게 동작하는가
먼저 기본 동작부터 보면 이해가 쉬움.
Pod 정의 파일에는 nodeName 이라는 필드가 있음.
nodeName: ...
그런데 일반적으로는 이 값을 직접 적지 않음.
Pod를 생성할 때 보통 비워두고 생성함.
왜냐하면 원래는 Scheduler가 이 값을 채우기 때문임.
Scheduler의 동작 흐름은 대략 다음과 같음.
- 클러스터 안의 Pod들을 확인함
- 그중에서 nodeName이 아직 설정되지 않은 Pod를 찾음
- 그런 Pod들을 스케줄링 대상(candidate) 으로 봄
- 스케줄링 알고리즘으로 어떤 Node가 적절한지 결정함
- 적절한 Node를 찾으면 Pod를 그 Node에 배치함
- 이 과정에서 내부적으로 Binding Object를 만들어 연결함
즉, 핵심은 다음임.
- nodeName이 없는 Pod = 아직 어느 Node에도 배치되지 않음
- Scheduler가 적절한 Node를 골라서 nodeName을 설정해 줌
2. Scheduler가 없으면 무슨 일이 생기는가
클러스터에 Scheduler가 없으면,
nodeName이 비어 있는 Pod를 아무도 처리하지 못함.
그 결과 Pod는 계속 다음 상태로 남음.
- Pending
즉, Pod는 생성되었지만
어느 Node에서 실행되어야 하는지 정해지지 않았기 때문에 실제로 올라가지 못하는 상태임.
3. Scheduler 없이 Pod를 수동으로 배치하는 가장 쉬운 방법
가장 쉬운 방법은 Pod 생성 시점에 nodeName을 직접 지정하는 것임.
예를 들어 Pod manifest에 이렇게 적을 수 있음.
kind: Pod
metadata:
name: my-pod
spec:
nodeName: node01
containers:
- name: nginx
image: nginx
이렇게 하면 Scheduler가 없어도
Pod는 바로 node01에 배치됨.
즉,
- Pod를 처음 만들 때
- spec.nodeName에 원하는 Node 이름을 적으면
- 해당 Node에 직접 할당 가능함
4. 이미 생성된 Pod에는 nodeName을 바꿀 수 없음
여기서 중요한 제약이 있음.
Pod가 이미 생성된 뒤에는 nodeName을 수정할 수 없음.
즉 이런 식은 안 됨.
- Pod를 먼저 만들고
- 나중에 nodeName만 수정해서 다른 Node에 붙이기
Kubernetes는 기존 Pod의 nodeName 변경을 허용하지 않음.
5. 이미 만들어진 Pod를 Node에 붙이고 싶다면
이미 생성된 Pod를 특정 Node에 연결하려면
실제 Scheduler가 하는 것처럼 Binding Object를 만들어서 API 요청을 보내야 함.
즉, 직접 Scheduler처럼 동작을 흉내 내는 방식임.
흐름은 다음과 같음.
- Binding Object를 만듦
- 그 안에 목표 Node 이름을 적음
- Pod의 Binding API로 POST 요청을 보냄
- 그러면 해당 Pod가 그 Node에 바인딩됨
Binding Object에는 어떤 Node에 붙일지에 대한 정보가 들어감.
예를 들어 개념적으로는 다음과 비슷함.
kind: Binding
metadata:
name: my-pod
target:
apiVersion: v1
kind: Node
name: node01
그런데 API로 보낼 때는 보통 JSON 형식으로 보내야 하므로,
YAML을 그대로 보내는 것이 아니라 JSON으로 변환해서 POST 요청해야 함.
2. Labels and Selectors
1. Labels와 Selectors의 기본 개념
Labels와 Selectors는 대상을 분류하고 필터링하기 위한 방법임.
예를 들어 여러 동물이 있다고 하면, 다음과 같은 기준으로 나눌 수 있음.
- class
- kind
- domestic / wild
- color
이렇게 각 대상에 여러 속성을 붙여두면, 원하는 조건으로 쉽게 묶어서 볼 수 있음.
예를 들면 다음과 같음.
- class = mammal → 포유류만 조회
- color = green → 초록색 동물만 조회
- class = bird, color = green → 초록색 새만 조회
즉, Labels는 속성을 붙이는 역할, Selectors는 그 속성을 기준으로 원하는 대상을 찾는 역할을 함.
2. Labels는 무엇인가
Labels는 각 객체에 붙이는 key-value 형태의 속성 정보임.
예를 들어 어떤 대상에 다음과 같은 label을 붙일 수 있음.
- class: mammal
- kind: dog
- color: green
이런 식으로 label을 붙여두면, 나중에 여러 기준으로 객체를 구분할 수 있음.
핵심은 다음과 같음.
- Labels는 객체를 설명하는 속성임
- 필요한 만큼 여러 개를 붙일 수 있음
- 객체를 그룹화할 때 기준이 됨
3. Selectors는 무엇인가
Selectors는 Labels를 기준으로 원하는 객체를 골라내는 조건임.
즉, Labels가 붙어 있어야 Selectors가 동작할 수 있음.
예를 들어 다음과 같이 사용할 수 있음.
- class = mammal
- app = app1
- color = green
또는 여러 조건을 함께 사용할 수도 있음.
즉, Selectors는 단순히 객체를 보는 것이 아니라,
특정 조건에 맞는 객체만 선택하는 역할을 함.
4. 왜 Labels와 Selectors가 필요한가
Kubernetes에서는 다양한 객체를 생성하게 됨.
예를 들면 다음과 같음.
- Pod
- Service
- ReplicaSet
- Deployment
처음에는 객체 수가 적어서 직접 확인할 수 있지만, 시간이 지나면 클러스터 안에 수백 개, 수천 개의 객체가 생길 수 있음.
이때는 객체를 다음과 같은 기준으로 나눠서 봐야 함.
- 어떤 애플리케이션에 속하는지
- 어떤 기능을 담당하는지
- 어떤 종류의 객체인지
이런 구분을 위해 Labels와 Selectors를 사용함.
즉, Kubernetes에서 Labels와 Selectors는
객체를 체계적으로 관리하기 위한 핵심 수단임.
5. Kubernetes에서 Labels를 지정하는 위치
Kubernetes에서 Labels는 객체 정의 파일의 metadata 아래에 작성함.
예를 들어 Pod 정의 파일에서는 metadata.labels 아래에 label을 추가함.
형식은 key-value 방식임.
apiVersion: v1
kind: Pod
metadata:
name: simple-webapp
labels:
app: App1
function: Front-end
spec:
containers:
- name: simple-webapp
image: simple-webapp
ports:
- containerPort: 8080

여기에 원하는 만큼 label을 추가할 수 있음.
즉, Pod를 만들 때부터 어떤 그룹에 속하는지 미리 표시해두는 것임.
6. Labels로 Pod를 조회하는 방법
Pod가 생성된 후에는 label을 기준으로 Pod를 조회할 수 있음.
이때 kubectl get pods 명령어와 --selector 옵션을 함께 사용함.
예를 들어 다음과 같은 조건으로 조회할 수 있음.
$ kubectl get pods --selector app=App1
이렇게 하면 해당 label을 가진 Pod만 확인할 수 있음.
즉, label은 단순한 메모가 아니라
실제로 원하는 객체를 찾는 기준으로 사용됨.
7. ReplicaSet에서 Labels와 Selectors가 어떻게 연결되는가

7. 1 metadata.labels → ReplicaSet 객체 자신에게 붙는 라벨
metadata:
labels:
app: myapp
-> 즉 ReplicaSet 리소스를 분류할 때 의미가 있음.
kubectl get rs --selector app=myapp
7.2 spec.template.metadata.labels → ReplicaSet이 생성할 Pod들에 붙는 라벨
selector:
matchLabels:
app: myapp
"label이 app=myapp인 Pod를 내가 관리하겠다."
7.3 spec.selector → ReplicaSet이 어떤 Pod를 자기 관리 대상으로 볼지 고르는 조건
template:
metadata:
labels:
app: myapp
-> ReplicaSet이 Pod를 만들면, 그 Pod는 app=myapp label을 가지고 생성됨.
spec.selector.matchLabels와 spec.template.metadata.labels는 반드시 맞춰야 함
selector가 app=myapp인데,
template에서 생성되는 Pod label이 app=nginx라면 어떻게 되느냐?
ReplicaSet은 자기가 만든 Pod조차 자기 Pod로 인식하지 못할 수 있음!
metadata.labels는 달라도 ReplicaSet 동작에는 직접 문제 없음.
8. Service에서도 같은 방식이 사용됨
Service도 Labels와 Selectors를 이용해 Pod를 찾음.
동작 방식은 ReplicaSet과 거의 같음.
- Pod에 labels가 붙어 있음
- Service에 selector가 정의되어 있음
- Service가 selector와 일치하는 Pod를 찾음
- 그 Pod들로 트래픽을 전달함
즉, Service도 Pod 이름이나 IP를 직접 기준으로 연결하는 것이 아니라
label 기준으로 연결 대상 Pod를 선택함

9. Labels와 Selectors의 핵심 역할 정리
Kubernetes에서 Labels와 Selectors는 다음 두 가지 목적으로 사용됨.
9-1. 객체를 조회하고 필터링하기 위해
예를 들어 특정 앱에 속한 Pod만 보고 싶을 때 사용함.
9-2. Kubernetes 객체끼리 연결하기 위해
예를 들어 다음과 같은 연결에 사용됨.
- ReplicaSet → Pod 연결
- Service → Pod 연결
즉, Kubernetes에서 Labels와 Selectors는
관리용 기능이면서 동시에 객체 연결의 기준이기도 함.
10. Annotations는 Labels와 어떻게 다른가
Annotations는 Labels와 목적이 다름.
Labels와 Selectors는 객체를 그룹화하고 선택하기 위한 것임.
반면 Annotations는 객체에 부가 정보를 기록하기 위한 것임.
예를 들면 다음과 같은 정보를 넣을 수 있음.
- tool name
- version
- build information
- contact details
- phone numbers
- email IDs
즉, Annotations는 객체를 선택하는 기준이 아니라
참고용 정보나 통합용 정보를 저장하는 용도임.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: simple-webapp
labels:
app: App1
function: Front-end
annotations:
buildversion: 1.34
spec:
replicas: 3
selector:
matchLabels:
app: App1
template:
metadata:
labels:
app: App1
function: Front-end
spec:
containers:
- name: simple-webapp
image: simple-webapp
3. Taints and Tolerations
1. 목적
Taints와 Tolerations는 어떤 Pod가 어떤 Node에 스케줄될 수 있는지를 제한하는 기능임.
즉, 특정 Node에 아무 Pod나 올라가지 못하게 하고,
조건을 만족하는 Pod만 올라가게 할 때 사용함.
2. 어디에 설정하는가
2-1. Taint
Node에 설정함
2-2. Toleration
Pod에 설정함
즉, Node 쪽에는 “이런 Pod만 받을 수 있다”는 제한을 걸고,
Pod 쪽에는 “이 taint를 견딜 수 있다”는 설정을 넣는 구조임.
3. 핵심 동작
Node에 taint가 있으면,
그 taint를 toleration하지 못하는 Pod는 해당 Node에 스케줄되지 않음.
반대로 Pod에 해당 taint에 대한 toleration이 있으면,
그 Node에 스케줄될 수 있음.
중요한 점은 다음과 같음.
- Taint는 Node가 Pod를 거부하는 기준
- Toleration은 Pod가 그 거부 조건을 예외적으로 통과할 수 있게 하는 설정
4. Taint Effect 3가지
4-1. NoSchedule
해당 taint를 toleration하지 않는 Pod는
그 Node에 새로 스케줄되지 않음
4-2. PreferNoSchedule
가능하면 그 Node에 스케줄하지 않으려 하지만
강제는 아님
4-3. NoExecute
해당 taint를 toleration하지 않는 Pod는
- 새로 스케줄되지 않고
- 이미 그 Node에서 실행 중이던 Pod도 evict(제거) 됨

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

5. 반드시 기억할 핵심
Taints와 Tolerations는
Pod를 특정 Node로 보내는 기능이 아님
즉, 이것은
“이 Pod는 반드시 이 Node로 가야 한다”를 의미하지 않음.
정확히는 다음 의미임.
해당 Node는 특정 toleration이 있는 Pod만 받을 수 있다
따라서 특정 Pod를 특정 Node에 반드시 배치하고 싶다면
그건 Node Affinity로 해결해야 함.
6. Master Node 관련
Kubernetes 클러스터에서는 보통 Master Node에 기본 taint가 설정되어 있음.
그래서 일반 Pod는 Master Node에 스케줄되지 않음.
즉, Master Node에 워크로드가 올라가지 않는 이유 중 하나가
바로 이 taint 설정 때문임.
4. Node Selectors
1. 목적
Node Selector는 특정 Pod가 특정 Node에서만 실행되도록 제한하는 기능임.
예를 들어 클러스터에 3개의 Node가 있고,
- 2개는 리소스가 적은 작은 Node
- 1개는 리소스가 많은 큰 Node
라고 할 때,
리소스를 많이 사용하는 데이터 처리 workload는 큰 Node에서만 실행되게 하고 싶을 수 있음.
기본 설정에서는 어떤 Pod든 어떤 Node에나 배치될 수 있기 때문에,
원하는 Pod가 작은 Node에 배치될 수도 있음.
이 문제를 해결하기 위해 Pod가 특정 Node에서만 실행되도록 제한하는 방법이 필요함.
2. Pod를 특정 Node에 배치하는 방법
이 강의에서는 그 방법 중 하나로 Node Selector를 설명함.
Pod를 특정 Node에서만 실행되게 하려면,
Pod 정의 파일의 spec 아래에 nodeSelector를 추가하면 됨.
예를 들어 다음과 같이 설정할 수 있음.
- size: large
이 의미는:
size=large 라는 label이 붙은 Node에만 이 Pod를 배치하라
는 뜻임.
3. Node Selector의 동작 방식
동작 흐름은 아래와 같음.
3-1. Node에 label을 붙임

Syntax
$ kubectl label nodes <node-name> <label-key>=<label-value>
Example
$ kubectl label nodes node-1 size=Large
3-2. Pod에 nodeSelector를 설정함

To create a pod definition
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: data-processor
image: data-processor
nodeSelector:
size: Large
$ kubectl create -f pod-definition.yml
3-3. Scheduler가 label과 selector를 비교함
3-4. 일치하는 Node에 Pod를 배치함
즉 핵심은:
Pod의 nodeSelector와 Node의 label이 일치해야 한다는 것임.
4. Node Selector의 한계
Node Selector는 단순하고 쉬운 방법이지만,
복잡한 조건을 표현하는 데는 한계가 있음.
예를 들어 아래와 같은 조건은 Node Selector로 처리하기 어려움.
- large 또는 medium Node에 배치
- small이 아닌 모든 Node에 배치
즉 Node Selector는
단순한 key-value 일치 조건만 사용할 수 있음.
더 복잡한 조건이 필요하면 Node Selector만으로는 부족함.
이런 경우에는 Node Affinity / Anti-Affinity 기능을 사용해야 함.
즉:
- 간단한 조건 → Node Selector
- 복잡한 조건 → Node Affinity / Anti-Affinity
'Infra > K8S' 카테고리의 다른 글
| [CKA 준비] Core Concepts - 3 (0) | 2026.03.15 |
|---|---|
| [CKA 준비] - Core Concepts - 2 (0) | 2026.03.15 |
| [CKA 준비] Core Conecepts - 1 (4) | 2026.03.04 |
| KEDA 필요성, HPA 와의 차이점 (0) | 2026.01.18 |