🔍 Node Selector
- 노드에 key:value 형태의 label을 붙여놓고 파드를 띄울 때 특정 라벨값을 정할 수 있음
- 쿠버네티스 파드는 워커 노드가 3대가 있다면 파드는 그중 아무 노드에나 랜덤으로 배치됨
❓이때, 이 파드는 반드시 워커1에만 배치가 됐으면 좋겠는데? 라든가
❓GPU 있는 노드에만 이 파드를 띄우고 싶은데
라는 생각이 든다면 이때 NodeSelector를 사용함

- 노드 이름에 맞게 라벨 붙여주기
root@master:~# kubectl label nodes worker-1 gpu=false
- 임의로 내가 만든 노드 값 key=value형태
- gpu=false임의로 정한 값

vi selector.yml
- 아무 deployment를 복제후
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-dep
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: my-con
image: 61.254.18.30:5000/ipnginx
nodeSelector:
gpu: "true"

- 레플리카를 5개로 해도 worker2에만 배치됨
🔍 Node Affinity
- 끌림, 노드 설렉터랑 비슷하지만 좀 더 세부적인 조건을 걸어 줄 수 있음
- NodeSeletor는 딱 하나의 조건만 정확히 일치할 때만 동작함
- 조건이 조금만 복잡해져도 못 활용함
이때 Node Affinity를 사용하는데
requiredDuringSchedulingIgnoredDuringExecution | 꼭 이 조건을 만족해야만 파드가 배치됨 | 강제 조건 (NodeSelector처럼 동작) |
preferredDuringSchedulingIgnoredDuringExecution | 가능하면 이 조건을 만족하는 노드에 배치함, 안되면 다른 데도 가능 | 유연한 조건 |
requiredDuringSchedulingRequiredDuringExecution | (거의 안 써) 실행 중에도 강제 조건 유지 | 알기만 해도 OK |
vi affinity-required.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-dep
spec:
replicas: 4
selector:
matchLabels:
app: my-httpd
template:
metadata:
labels:
app: my-httpd
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: #prefer은 되도록이면, required은 반드시
nodeSelectorTerms:
- matchExpressions:
- key: gpu
operator: In
values:
- "false"
containers:
- name: httpd-pod-con
image: 61.254.18.30:5000/nginx

- worker-1에 배치가 잘 된 걸 확인할 수 있음
실습 1)
worker1은 disktype이 ssd이며, worker2는 disktype이 hdd 일 때. 간단한 deployment 파일을 작성하여 ssd-dep는 ssd가 설치된 노드에, hdd-dep는 hdd가 설치된 노드에 배치해 보세요.
nodeSelector와 nodeAffinity를 둘 다 사용해 보세요.
root@master:~/mani/selector# kubectl label node worker-1 disktype=ssd
node/worker-1 labeled
root@master:~/mani/selector# kubectl label node worker-2 disktype=hdd
node/worker-2 labeled
vi hdd.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hdd-dep
spec:
replicas: 1
selector:
matchLabels:
app: hdd
template:
metadata:
labels:
app: hdd
spec:
containers:
- name: my-con
image: 61.254.18.30:5000/ipnginx
nodeSelector:
disktype: hdd
vi sdd.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ssd-dep
spec:
replicas: 1
selector:
matchLabels:
app: ssd
template:
metadata:
labels:
app: ssd
spec:
containers:
- name: my-con
image: 61.254.18.30:5000/ipnginx
nodeSelector:
disktype: ssd
vi ssd-aff.yml
selector:
matchLabels:
app: ssd
template:
metadata:
labels:
app: ssd
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: httpd-pod-con
image: 61.254.18.30:5000/nginx
vi hdd-aff.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hdd-dep
spec:
replicas: 1
selector:
matchLabels:
app: hdd
template:
metadata:
labels:
app: hdd
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- hdd
containers:
- name: httpd-pod-con
image: 61.254.18.30:5000/nginx
root@master:~/mani/selector# kubectl apply -f hdd.yml
deployment.apps/hdd-dep created
root@master:~/mani/selector# kubectl apply -f ssd.yml
deployment.apps/ssd-dep created
root@master:~/mani/selector# kubectl apply -f ssd-aff.yml
deployment.apps/ssd-dep configured
root@master:~/mani/selector# kubectl apply -f hdd-aff.yml
root@master:~/mani/selector# kubectl get node --show-labels

🔍taints & tolerations
taints: 이 노드에 오지 마 = 금지
tolerations: 나는 괜찮아, 갈 수 있어 = 허용
이런 기능이 나온 이유는 기본적으로 쿠버네티스는 파드를 아무 노드나 적절히 골라서 배치를 해줌
- 이 노드는 GPU가 있어서 특별한 작업만 시켜야 함
- 이 노드는 운영 서비스 전용임. 테스트 파드는 오면 안 됨
-> 이럴 때 노드를 보호하는 기능이 필요함
kubectl taint node worker-1 team=dev:NoSchedule
- team=dev라는 toleration이 없다면, pod를 배치 안 하겠다.
kubectl taint node worker-2 team=ops:NoSchedule
- team=ops라는 toleration이 없다면, pod를 배치 안 하겠다.
root@master:~/mani/selector# cp ~/mani/dep.yml .
root@master:~/mani/selector# vi dep.yml
vi dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-dep-tai
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: my-con
image: public.ecr.aws/docker/library/nginx:alpine
root@master:~/mani/selector# kubectl apply -f dep.yml
kubectl get pod -o wide --watch

root@master:~/mani/selector# kubectl describe pod my-dep-tai-76c7fd4d94-r55wb

- taint에 의해 pod를 배치할 수 있는 노드가 없는 걸 확인
cp dep.yml tol-dep.yml
# 톨러레이션 옵션을 줄 deployment
vi tol-dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-dep
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: my-con
image: 61.254.18.30:5000/ipnginx
tolerations:
- key: "team"
operator: "Equal"
value: "dev"
effect: "NoSchedule"
- 톨러레이션에 해당하는 노드에 파드패치를 허용하겠음

root@master:~/mani/selector# kubectl taint node worker-2 team=ops:NoSchedule-
node/worker-2 untainted
root@master:~/mani/selector# kubectl taint node worker-1 team=dev:NoSchedule-
node/worker-1 untainted
- 테인트 삭제
root@master:~/mani/selector# kubectl label node worker-1 gpu-
node/worker-1 unlabeled
root@master:~/mani/selector# kubectl label node worker-2 gpu-
node/worker-2 unlabeled
root@master:~/mani/selector# kubectl label node worker-2 disktype-
node/worker-2 unlabeled
root@master:~/mani/selector# kubectl label node worker-1 disktype-
node/worker-1 unlabeled
- 라벨 삭제
'AWS Cloud School 8기 > 쿠버네티스' 카테고리의 다른 글
AWS CLI 구성/ eksctl/ kubectl 설치/ 클러스터 구축/ EKS/ 클러스터 생성 순서/ NLB 생성 (0) | 2025.05.01 |
---|---|
ubuntu 24.04에 쿠버네티스 클러스터 설치(kubeadm 사용) (0) | 2025.04.29 |
[쿠버네티스] prometheus (0) | 2025.04.23 |
[쿠버네티스] 헬름(Helm) (0) | 2025.04.23 |
[쿠버네티스] 컨테이너의 헬스체크/ livenessProbe/ readinessProbe/ StatefulSet(리소스)/ DaemonSet(리소스) (4) | 2025.04.17 |