Overview
쿠버네티스에서는 파드를 어떤 노드에 배포할지를 다양한 방법으로 제어할 수 있다.
이 글에서는 대표적인 스케줄링 전략인 NodeSelector, Affinity, Taint & Toleration, Cordon & Drain을 상세하게 정리해본다.
📅 관련 글
2022.08.08 - [Container Orchestration/Kubernetes] - Kubernetes Ingress란? (클러스터 외부 트래픽 관리)
2023.04.14 - [Container Orchestration/Kubernetes] - Kubernetes Resources(쿠버네티스 리소스)
2023.04.17 - [Container Orchestration/Kubernetes] - Kubernetes API Server, Group / RBAC란?
2023.04.25 - [Container Orchestration/Kubernetes] - Kubernetes 플러그인 매니저 Krew란?
2023.05.08 - [Container Orchestration/Kubernetes] - Kubernetes Secret이란?
2023.05.09 - [Container Orchestration/Kubernetes] - Kuberntes Service Account란?
2023.05.23 - [Container Orchestration/Kubernetes] - Kubernetes Autoscaling & Karpenter
2023.05.26 - [AWS] - AWS IRSA(IAM Roles for Service Accounts)란?
2024.02.02 - [Container Orchestration/Kubernetes] - Kubernetes 클러스터 구축하기(kubespray 2024v.)
2024.02.02 - [Container Orchestration/Kubernetes] - Kubernetes Network
2024.05.24 - [Trouble Shooting] - K8s Worker Node에 지정한 Pod 배치하기(Taint, Tolerations)
2024.11.26 - [Container Orchestration/Kubernetes] - Kubernetes Deployment Strategy
2024.12.03 - [Container Orchestration/Kubernetes] - Kubernetes Headless Service란?
2025.01.14 - [Container Orchestration/Kubernetes] - Kubernetes IPVS vs iptables
Kubernetes Affinity and Scheduling
쿠버네티스에서는 다음과 같은 여러 메커니즘을 통해 클러스터 내에서 파드가 배포되는 위치를 제어할 수 있다.
- 노드 셀렉터(NodeSelector)
- 어피니티(Affinity)
- 테인트 & 톨러레이션(Taints & Toleration)
- 커든(Cordon)
- 드레인(Drain)
노드 할당 및 스케줄링 방법
방법 | 설명 |
NodeSelector | 단순한 Key-Value 기반 노드 선택 |
Affinity | 보다 유연한 노드 및 파드 배치 정책 |
Taint & Toleration | 특정 노드에 대한 제한 설정 |
Cordon & Drain | 노드 유지보수 및 스케줄링 제어 |
1️⃣ 노드 셀렉터(NodeSelector)
- 쿠버네티스에서 가장 간단한 스케줄링 제약 조건이다.
- 파드 `.spec.nodeSelector` 필드에 Key-Value 쌍을 설정
- 해당 레이블을 가진 노드에만 스케줄링
사용법
# 노드에 레이블 추가
kubectl label nodes <노드이름> disktype=ssd
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeSelector:
disktype: ssd
- 노드 셀렉터보다 고급이며, 특정 파드 배치에 대한 규칙을 설정한다.
- 주요 유형: 노드 어피니티(Node Affinity) 및 파드 어피니티(Pod Affinity).
- 노드 어피니티
- `requiredDuringSchedulingIgnoredDuringExecution` 또는 `preferredDuringSchedulingIgnoredDuringExecution`으로 설정할 수 있다.
- 조건을 더 세밀하게 설정 가능
- Hard (필수)와 Soft (선호) 조건 지원
유형 | 설명 |
Node Affinity | 특정 노드 조건을 만족하는 노드에 스케줄링 |
Pod Affinity | 특정 파드가 있는 노드에 함께 배포 |
Pod Anti Affinity | 특정 파드가 있는 노드를 피해서 배포 |
Node Affinity 예제
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
- requiredDuringSchedulingIgnoredDuringExecution
- 파드가 스케줄링될 때 반드시 충족해야 하는 요구사항을 정의한다. 규칙을 만족하는 노드에만 파드가 스케줄될 수 있다.
- 특정 노드에 파드를 배치해야 할 때 사용한다. 예를 들어, 특정 라벨이 있는 노드에만 파드를 배치하고 싶은 경우 이 규칙을 사용할 수 있다.
- 만약 이 규칙을 만족하는 노드가 없다면, 파드는 스케줄되지 않는다.
- preferredDuringSchedulingIgnoredDuringExecution
- 스케줄러에게 파드가 스케줄링될 때 선호되는(하지만 필수는 아닌) 요구사항을 알린다. 스케줄러는 이 규칙을 가능한 한 충족시키려고 시도하지만, 규칙을 만족하는 노드가 없어도 파드는 다른 노드에 스케줄될 수 있다.
- 파드의 배치에 더 유연성을 제공하고자 할 때 사용한다. 예를 들어, 특정 노드에 파드를 선호적으로 배치하고 싶지만, 그러한 노드가 없거나 사용할 수 없는 경우 다른 노드에도 배치될 수 있도록 하고 싶을 때 사용할 수 있다.
- 이 규칙을 만족하는 노드가 있으면 그 노드에 파드가 우선적으로 스케줄되지만, 만족하는 노드가 없어도 파드는 스케줄될 수 있다.
- 요약하자면, `requiredDuringSchedulingIgnoredDuringExecution`은 파드의 스케줄링에 있어서 반드시 충족해야 하는 엄격한 요구사항을 정의하는 반면, `preferredDuringSchedulingIgnoredDuringExecution`은 선호되는 조건을 정의하지만, 이 조건이 충족되지 않더라도 파드가 스케줄될 수 있도록 유연성을 제공한다.
- 노드 안티-어피니티
- 특정 노드의 속성이나 라벨을 기반으로 하여 파드를 해당 노드로부터 멀리 배치하고자 할 때 사용한다.
- 노드 안티-어피니티는 노드 어피니티와 유사하게 작동하지만, 반대의 목적을 가지고 있다.
- 이 예제에서 `requiredDuringSchedulingIgnoredDuringExecution`은 disktype이 hdd가 아닌 노드에 파드를 배치하도록 요구한다. 즉, SSD 또는 다른 유형의 디스크를 사용하는 노드에만 파드가 배치될 수 있다. 또한, `preferredDuringSchedulingIgnoredDuringExecution` 설정은 cpu가 high가 아닌 노드를 선호하지만, 이는 필수 조건이 아다. weight는 이 선호도의 중요성을 나타낸다.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: NotIn
values:
- hdd
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: cpu
operator: NotIn
values:
- high
containers:
- name: mycontainer
image: myimage
Pod Affinity 예제
- 파드 어피니티
- 다른 파드의 레이블을 기준으로 규칙을 설정하는 데 사용된다.
- 역시 하드 어피니티와 소프트 어피니티 규칙을 정의할 수 있다.
- 다른 파드와 가깝게 배치되기를 원할 때 사용한다.
- `requiredDuringSchedulingIgnoredDuringExecution` 예제에서, mypod는 `app=database` 레이블을 가진 다른 파드와 같은 호스트(kubernetes.io/hostname)에 배치되어야 한다.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- database
topologyKey: "kubernetes.io/hostname"
containers:
- name: mycontainer
image: myimage
Pod Anti Affinity 예제
- 파드 안티-어피니티
- 파드를 특정 레이블을 가진 다른 파드로부터 멀리 배치하고자 할 때 사용한다.
- `requiredDuringSchedulingIgnoredDuringExecution` 예제에서, mypod는 `app=webserver` 레이블을 가진 다른 파드와는 다른 호스트(kubernetes.io/hostname)에 배치되어야 한다.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- webserver
topologyKey: "kubernetes.io/hostname"
containers:
- name: mycontainer
image: myimage
Affinity의 Operator 정리
Operator | 의미 |
In | 지정 값과 일치하는 경우 |
NotIn | 지정 값과 일치하지 않는 경우 |
Exists | 키가 존재하는 경우 |
DoesNotExist | 키가 존재하지 않는 경우 |
Gt | 지정 값보다 큰 경우 (숫자) |
Lt | 지정 값보다 작은 경우 (숫자) |
3️⃣ 테인트 & 톨러레이션(Taints & Toleration)
- Taint: 노드에 설정하는 제한 조건
- Toleration: 파드에 설정해 Taint를 무시하고 배포 허용
Taint 추가
kubectl taint nodes <노드이름> key=value:NoSchedule
Toleration 설정 예제
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
Taint 효과 정리
효과 | 설명 |
NoSchedule | 해당 노드에 파드 스케줄링 금지 |
PreferNoSchedule | 가능하면 스케줄링 금지, 불가피하면 허용 |
NoExecute | 기존 파드도 퇴출 (즉시 영향) |
4️⃣ 커든(Cordon) &드레인(Drain)
✅ 개념
명령 | 설명 |
cordon | 해당 노드로 신규 파드 스케줄링 금지 |
uncordon | cordon 해제 |
drain | 노드에서 기존 파드를 퇴출 및 재스케줄링 |
사용법
# 노드 cordon (스케줄링 금지)
kubectl cordon <노드이름>
# 노드 uncordon (해제)
kubectl uncordon <노드이름>
# 노드 drain (파드 퇴출 및 재스케줄링)
kubectl drain <노드이름> --ignore-daemonsets --delete-emptydir-data
전체 비교 요약
방법 | 목적 | 주요 필드 | 특징 |
NodeSelector | 특정 노드 지정 | nodeSelector | 단순 Key-Value 매칭 |
Node Affinity | 조건부 노드 지정 | affinity.nodeAffinity | 복잡 조건 가능 |
Pod Affinity | 특정 파드 옆에 배치 | affinity.podAffinity | 파드간 위치 제어 |
Pod Anti Affinity | 특정 파드 피해서 배치 | affinity.podAntiAffinity | 파드간 충돌 방지 |
Taint & Toleration | 특정 노드 제한 | tolerations | Taint와 매칭되는 파드만 허용 |
Cordon & Drain | 노드 유지보수 | cordon, drain | 스케줄링 차단/퇴출 |
마무리
- 쿠버네티스의 파드 스케줄링 전략은 단순히 "아무데나 배포"하는 것이 아니라, 다양한 상황을 고려해 유연하고 전략적으로 설정할 수 있다.
- 실제 운영 환경에서는 하드웨어 성능, 네트워크 존, 파드 간 의존성 등을 고려해 어피니티, 안티 어피니티, 테인트 & 톨러레이션을 적극 활용해야 한다.
- 스케줄링을 잘 설정하는 것만으로도 클러스터 안정성과 성능을 크게 높일 수 있으니, 꼭 숙지하고 현업에서 활용해보자!
Reference
공식문서: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
공식문서: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/
'Container Orchestration > Kubernetes' 카테고리의 다른 글
Ingress Nginx란? (0) | 2024.07.04 |
---|---|
Kubernetes Volumes 및 StorageClass: CSI 드라이버 사용 가이드 (0) | 2024.04.28 |
Kubernetes Network (0) | 2024.02.17 |
Kubernetes 클러스터 구축하기(kubespray 2024v.) (0) | 2024.02.02 |
k3d(k3s in docker)란? (2) | 2024.01.14 |