2024. 12. 31. 14:19ㆍ쿠버네티스/쿠버네티스
Node Selectors와 라벨링
상황 설명
- 클러스터에는 총 3개의 노드가 있습니다:
- 작은 노드 2개: 하드웨어 리소스가 적음.
- 큰 노드 1개: 더 높은 리소스를 제공.
- 다양한 워크로드가 클러스터에서 실행 중이며, 데이터 처리 워크로드는 더 많은 리소스를 요구하므로 큰 노드에서 실행되기를 원합니다.
- 기본 설정에서는 모든 Pod이 임의의 노드에 배치될 수 있습니다. 예를 들어, Pod C가 작은 노드(노드 2 또는 3)에 배치될 수도 있습니다. 이는 원하는 결과가 아닙니다.
해결 방법
Pod이 특정 노드에서만 실행되도록 제한하려면 두 가지 방법이 있습니다:
- Node Selector (간단하고 쉬운 방법)
- Node Affinity/Anti-Affinity (더 복잡한 요구사항에 적합)
Node Selector 사용법
- Pod 정의 파일 수정
- Pod 정의 파일의 spec 섹션에 nodeSelector 속성을 추가하여 특정 노드에서만 Pod이 실행되도록 설정합니다.
- 예시:
spec:
nodeSelector:
size: large
- 여기서 size=large는 라벨로, Kubernetes는 이를 기반으로 적절한 노드를 선택합니다.
노드에 어떻게 라벨 설정하나?
라벨(Label) 설정
- Kubernetes는 노드에 설정된 라벨을 사용하여 Pod을 적절한 노드에 배치합니다.
- 라벨은 키-값 형식으로 구성됩니다. 예: size=large.
- 라벨 설정 명령어:
kubectl label nodes <노드명> <라벨>
# 큰 노드를 라벨링한다면
kubectl label nodes node1 size=large
Pod 생성
- 라벨이 설정된 후, nodeSelector를 포함한 Pod 정의 파일을 사용하여 Pod을 생성하면 해당 Pod은 지정된 라벨 조건을 만족하는 노드(예: size=large)에 배치
Node Selector의 한계
Node Selector는 단순한 라벨 매칭만 지원하므로 복잡한 조건을 처리할 수 없습니다. 예를 들어:
- "Pod을 큰(Large) 또는 중간(Medium) 노드에 배치"하거나,
- "작은(Small) 노드를 제외한 모든 노드에 배치"와 같은 조건은 Node Selector로 구현할 수 없습니다.
이를 해결하기 위해 Kubernetes는 Node Affinity 및 Anti-Affinity 기능을 제공합니다. 이 기능들은 더 복잡한 요구사항을 처리
Node Affinity란?
- Node Affinity는 Kubernetes에서 Pod이 특정 노드에 배치되도록 제어하는 기능입니다.
- 기존 Node Selector보다 더 유연하며, 논리 연산자(In, NotIn, Exists 등)를 사용해 복잡한 조건을 설정할 수 있습니다.
- 주로 다음과 같은 경우에 사용됩니다:
- 특정 하드웨어(예: SSD, GPU)가 필요한 Pod 배치.
- 고성능 컴퓨팅 작업을 특정 노드에 제한.
- 특정 라벨 조건을 만족하는 노드에서만 실행.
Node Affinity 사용 방법
- Pod 정의 파일 수정
- Node Affinity는 spec.affinity.nodeAffinity 섹션에 정의됩니다.
- 주요 구성 요소:
- requiredDuringSchedulingIgnoredDuringExecution: Pod이 반드시 조건을 만족하는 노드에만 배치됩니다. 조건을 만족하는 노드가 없으면 Pod은 스케줄되지 않습니다.
- preferredDuringSchedulingIgnoredDuringExecution: 조건을 만족하는 노드를 선호하지만, 없으면 다른 노드에도 배치될 수 있습니다.
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: size
operator: In
values:
- large
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: size
operator: NotIn
values:
- small
라벨(Label) 설정
- Node Affinity는 노드의 라벨을 기반으로 동작합니다.
- 라벨 추가 명령어:
kubectl label nodes <노드명> <라벨>
kubectl label nodes node1 size=large
Node Affinity의 동작 방식
1. 스케줄링 중 동작 (during scheduling)
- Pod이 처음 생성될 때, Node Affinity 규칙이 적용되어 적합한 노드가 선택됩니다.
- requiredDuringSchedulingIgnoredDuringExecution:
- 조건을 만족하지 않는 노드가 있으면 Pod은 스케줄되지 않습니다.
- preferredDuringSchedulingIgnoredDuringExecution:
- 조건을 만족하는 노드를 우선적으로 선택하지만, 없으면 다른 노드에도 배치 가능합니다.
2. 실행 중 동작 (during execution)
- Pod이 실행 중일 때 환경(예: 라벨 변경)이 바뀌더라도 현재 Node Affinity 규칙은 적용되지 않습니다.
- 현재 사용 가능한 옵션(IgnoredDuringExecution)에서는 실행 중인 Pod은 영향을 받지 않습니다.
- 향후 지원될 예정인 옵션(RequiredDuringExecution)에서는 규칙을 위반하는 경우 Pod이 종료되거나 재배치될 수 있습니다.
Node Affinity의 주요 연산자
- In: 지정된 값 리스트 중 하나를 포함하는 경우 매칭.
- NotIn: 지정된 값 리스트에 포함되지 않는 경우 매칭.
- Exists: 특정 키가 존재하면 매칭(값은 필요 없음).
- DoesNotExist: 특정 키가 존재하지 않으면 매칭.
Apply a label color=blue to node node01
- kubectl label node node01 color=blue
Create a new deployment named blue with the nginx image and 3 replicas.
- kubectl create deployment blue --image=nginx --replicas=3
Which nodes can the pods for the blue deployment be placed on?
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
blue-6dc9b889f5-chx2z 1/1 Running 0 42s 172.17.0.4 controlplane <none> <none>
blue-6dc9b889f5-hl7b2 1/1 Running 0 42s 172.17.1.3 node01 <none> <none>
blue-6dc9b889f5-njg8m 1/1 Running 0 42s 172.17.1.2 node01 <none> <none>
Set Node Affinity to the deployment to place the pods on node01 only.
- kubectl edit deployment blue(디플로이먼트이름)
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: color
operator: In
values:
- blue
https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/
Assign Pods to Nodes using Node Affinity
This page shows how to assign a Kubernetes Pod to a particular node using Node Affinity in a Kubernetes cluster. Before you begin You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster.
kubernetes.io

편집 tip
v를 눌러 visual모드에서 원하는 부분 아래그림처럼 선택한 후 ' shift+.'을하면 왼쪽으로 한칸씩 들어감

Create a new deployment named red with the nginx image and 2 replicas, and ensure it gets placed on the controlplane node only.
Use the label key - node-role.kubernetes.io/control-plane - which is already set on the controlplane node.

kubectl create deployment red --image=nginx --replicas=2 --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: red
name: red
spec:
replicas: 2
selector:
matchLabels:
app: red
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: red
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
kubectl create deployment red --image=nginx --replicas=2 --dry-run=client -o yaml > red.yaml
###
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: red
name: red
spec:
replicas: 2
selector:
matchLabels:
app: red
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: red
spec:
containers:
- image: nginx
name: nginx
resources: {}
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: Exists
values:
status: {}
kubectl create -f red.yaml
Taints and Tolerations VS Node Affinity
문제 정의
- 목표:
- 파란색 Pod은 파란색 노드에, 빨간색 Pod은 빨간색 노드에, 초록색 Pod은 초록색 노드에 배치.
- 다른 팀의 Pod이 우리의 노드에 배치되지 않도록 방지.
- 우리의 Pod이 다른 팀의 노드에 배치되지 않도록 방지.
Taints와 Tolerations으로 해결
- Taints 추가
- 각 노드에 색상별로 taint를 추가합니다.
kubectl taint nodes blue-node color=blue:NoSchedule
kubectl taint nodes red-node color=red:NoSchedule
kubectl taint nodes green-node color=green:NoSchedule
Tolerations 추가
- 각 Pod에 해당 색상의 toleration을 추가합니다.
tolerations:
- key: "color"
operator: "Equal"
value: "blue"
effect: "NoSchedule"
- 이 설정으로 특정 색상의 Pod만 해당 색상의 taint가 있는 노드에서 실행될 수 있습니다.
- 단, 반듯이 해당 생삭의 노드에 실행되는 건 아님.
- 결과
- 파란색 Pod은 파란색 노드에서 실행되고, 빨간색과 초록색도 동일하게 배치됩니다.
- 그러나 Taints와 Tolerations만 사용하면 다른 Pod이 taint가 없는 노드에 배치될 가능성이 있습니다. 예를 들어, 빨간색 Pod이 taints가 없는 다른 팀의 노드로 이동할 수 있습니다.
Node Affinity로 해결
- 라벨 추가
- 각 노드에 색상별 라벨을 추가합니다.
kubectl label nodes blue-node color=blue
kubectl label nodes red-node color=red
kubectl label nodes green-node color=green
Node Affinity 설정
- 각 Pod에 Node Affinity 규칙을 추가하여 특정 라벨을 가진 노드에서만 실행되도록 설정합니다.
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: color
operator: In
values:
- blue
- 이 설정으로 파란색 Pod은 color=blue 라벨이 있는 노드에서만 실행됩니다.
결과
- Node Affinity는 특정 Pod이 지정된 라벨 조건을 만족하는 노드에서만 실행되도록 보장합니다.
- 그러나 Node Affinity만 사용하면 다른 팀의 Pod도 해당 라벨 조건을 만족하는 우리의 노드에 배치될 수 있습니다.
Taints & Tolerations + Node Affinity 결합
- Taints와 Tolerations
- 각 노드에 taint를 추가하여 다른 팀의 Pod이 우리의 노드로 스케줄링되지 않도록 방지합니다.
- 우리의 Pod에는 해당 taint를 허용하는 toleration을 추가합니다.
- Node Affinity
- 우리의 Pod에는 Node Affinity 규칙을 추가하여 지정된 라벨 조건을 만족하는 특정 노드에서만 실행되도록 보장합니다.
- 결과
- Taints와 Tolerations는 다른 팀의 Pod이 우리의 노드로 들어오는 것을 막고,
- Node Affinity는 우리의 Pod이 다른 팀의 노드로 이동하지 않도록 보장합니다.
- 이 조합으로 완벽하게 격리된 환경을 구축할 수 있습니다.
요약
- Taints와 Tolerations: 특정 Pod만 지정된 노드에서 실행되도록 제한하며, 다른 팀의 Pod 접근을 차단.
- Node Affinity: 특정 라벨 조건을 만족하는 노드에서만 우리의 Pod이 실행되도록 보장.
- 두 기능을 조합하면 다중 테넌트 환경에서도 완벽히 격리된 클러스터 운영 가능.
'쿠버네티스 > 쿠버네티스' 카테고리의 다른 글
Scheduling-DaemonSets (0) | 2024.12.31 |
---|---|
Scheduling-Resource Requirements and Limits (0) | 2024.12.31 |
Scheduling-Taints and Tolerations (0) | 2024.12.31 |
Scheduling-Labels and Selectors (0) | 2024.12.31 |
Scheduling-Manual Scheduling (0) | 2024.12.31 |