Kubernetes를 공부하다 보면 "멀티 스케줄러"라는 개념을 접하게 됩니다. 처음에는 "왜 스케줄러가 여러 개 필요하지?"라는 의문이 들었고, 관련 문서를 찾아봐도 이론적인 설명만 가득해서 감이 잘 오지 않았습니다. 이 글에서는 기본 개념부터 차근차근 설명하고, 실제 시나리오와 구현 방법까지 다뤄보겠습니다.
1. 기본 개념: 스케줄링이란?
스케줄링의 본질
스케줄링은 간단하게 말해 "Pod를 어떤 노드에 배치할지 결정하는 과정"입니다.
Pod 생성 요청
↓
어느 노드에 배치할까? ← 스케줄러가 결정
↓
Node1, Node2, Node3 중 선택
↓
Pod 실행
### 스케줄링 과정 (단계별)
Kubernetes 스케줄러는 여러 단계를 거쳐 최적의 노드를 선택합니다.
스케줄링은 여러 단계(Extension Points)를 거칩니다.
┌─────────────────────────────────────┐
│ 1. queueSort (큐 정렬) │
│ "어떤 Pod를 먼저 처리할까?" │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 2. filter (필터링) │
│ "이 Pod를 실행할 수 없는 │
│ 노드를 제거" │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 3. score (점수 매기기) │
│ "남은 노드들 중 어디가 │
│ 가장 좋을까?" │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 4. bind (바인딩) │
│ "Pod를 선택된 노드에 배치" │
└─────────────────────────────────────┘
※각 단계를 "Extension Point"라고 부릅니다.
기본 스케줄러는 이 과정을 자동으로 처리하며, 대부분의 경우 잘 작동합니다.
2. 멀티 스케줄러란?
기본: 하나의 스케줄러
Kubernetes는 기본적으로 하나의 스케줄러(default-scheduler)를 사용합니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Kubernetes 클러스터
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
default-scheduler
↓
모든 Pod 스케줄링 담당
• Web Pod
• GPU Pod
• Database Pod
• ...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
모든 Pod가 이 하나의 스케줄러를 거쳐서 노드에 배치됩니다.
멀티 스케줄러: 여러 개의 스케줄러
멀티 스케줄러는 클러스터에 여러 개의 스케줄러를 동시에 실행하고, 각 Pod가 원하는 스케줄러를 선택할 수 있게 하는 방식입니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Kubernetes 클러스터
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
default-scheduler gpu-scheduler
↓ ↓
일반 워크로드 GPU 워크로드
• Web Pod • ML Training
• API Pod • Inference
premium-scheduler batch-scheduler
↓ ↓
VIP 고객용 배치 작업용
• Critical App • Cron Jobs
• High Priority • Data Processing
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Pod가 스케줄러 선택하기
각 Pod는 schedulerName 필드로 어떤 스케줄러를 사용할지 지정합니다:
# 일반 웹 애플리케이션 - 기본 스케줄러 사용
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
# schedulerName 생략 시 자동으로 default-scheduler 사용
containers:
- name: nginx
image: nginx
---
# GPU 학습 작업 - GPU 전용 스케줄러 사용
apiVersion: v1
kind: Pod
metadata:
name: ml-training
spec:
schedulerName: gpu-scheduler # ← 이 스케줄러 사용!
containers:
- name: trainer
image: pytorch:latest
resources:
limits:
nvidia.com/gpu: 1
---
# VIP 서비스 - 프리미엄 스케줄러 사용
apiVersion: v1
kind: Pod
metadata:
name: vip-service
spec:
schedulerName: premium-scheduler # ← 이 스케줄러 사용!
containers:
- name: app
image: vip-app:v1
### 비유로 이해하기
공항의 체크인 카운터로 비유하면:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
일반 공항 (단일 스케줄러)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
체크인 카운터 1개
↓
모든 승객이 한 줄로 대기
• 일반석 승객
• 비즈니스석 승객
• 이코노미 승객
같은 기준으로 처리됨
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
대형 공항 (멀티 스케줄러)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
일반석 카운터 비즈니스 카운터
↓ ↓
빠른 처리 VIP 서비스
단체 카운터 마일리지 카운터
↓ ↓
그룹 처리 특별 혜택
각 승객이 자신에게 맞는
카운터 선택 가능
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3. 멀티 스케줄러 만들기
가장 간단한 방법: 별도 스케줄러 실행
멀티 스케줄러를 만드는 가장 간단한 방법은 기본 스케줄러 이미지를 그대로 사용하되, 다른 이름으로 실행하는 것입니다.
핵심 아이디어:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
같은 스케줄러 프로그램을
다른 이름으로 여러 개 실행
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 1: ServiceAccount 생성
스케줄러가 Kubernetes API를 사용하려면 권한이 필요합니다.
# scheduler-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-scheduler
namespace: kube-system
Step 2: 권한 부여
스케줄러에게 필요한 권한을 부여합니다.
# scheduler-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: my-scheduler-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-scheduler # 기본 스케줄러와 같은 권한
subjects:
- kind: ServiceAccount
name: my-scheduler
namespace: kube-system
system:kube-scheduler 권한이 포함하는 것:
- 노드 정보 조회
- Pod 정보 조회 및 업데이트
- Pod를 노드에 바인딩
- 리더 선출 (고가용성)
Step 3: 스케줄러 Deployment 생성
이제 새로운 스케줄러를 실행합니다.
# my-scheduler-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-scheduler
namespace: kube-system
labels:
component: my-scheduler
spec:
replicas: 1
selector:
matchLabels:
component: my-scheduler
template:
metadata:
labels:
component: my-scheduler
spec:
serviceAccountName: my-scheduler
containers:
- name: scheduler
image: registry.k8s.io/kube-scheduler:v1.28.0
command:
- kube-scheduler
- --scheduler-name=my-scheduler # ← 핵심! 스케줄러 이름 지정
- --leader-elect=false # 단순화를 위해 리더 선출 비활성화
- --v=2
중요한 설정:
- --scheduler-name=my-scheduler: 이 스케줄러의 이름 (Pod에서 이 이름으로 지정)
- --leader-elect=false: 고가용성이 필요 없으면 비활성화 (간단하게)
Step 4: 배포하기
# 순서대로 적용
kubectl apply -f scheduler-serviceaccount.yaml
kubectl apply -f scheduler-rbac.yaml
kubectl apply -f my-scheduler-deployment.yaml
# 스케줄러가 잘 실행되는지 확인
kubectl get pods -n kube-system -l component=my-scheduler
# 로그 확인
kubectl logs -n kube-system -l component=my-scheduler
Step 5: 새 스케줄러 사용하기
이제 Pod에서 새로운 스케줄러를 사용할 수 있습니다!
# test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
schedulerName: my-scheduler # ← 새로 만든 스케줄러 사용!
containers:
- name: nginx
image: nginx
# Pod 생성
kubectl apply -f test-pod.yaml
# 어떤 스케줄러가 배치했는지 확인
kubectl get pod test-pod -o yaml | grep schedulerName
### 동작 확인
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
배포 전
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
클러스터:
• default-scheduler만 실행 중
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
배포 후
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
클러스터:
• default-scheduler (계속 실행)
• my-scheduler (새로 추가!) ✨
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
### 전체 구조 한눈에 보기
ServiceAccount: my-scheduler
↓
ClusterRoleBinding
↓
system:kube-scheduler 권한 부여
↓
Deployment: my-scheduler
• 이미지: kube-scheduler:v1.28.0
• 이름: my-scheduler
• 권한: ServiceAccount 사용
↓
Pod가 schedulerName으로 선택
4. 실전 예시: GPU 스케줄러 만들기
위의 방법을 응용해서 GPU 전용 스케줄러를 만들어봅시다.
# gpu-scheduler-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gpu-scheduler
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
component: gpu-scheduler
template:
metadata:
labels:
component: gpu-scheduler
spec:
serviceAccountName: gpu-scheduler # 별도 ServiceAccount
containers:
- name: scheduler
image: registry.k8s.io/kube-scheduler:v1.28.0
command:
- kube-scheduler
- --scheduler-name=gpu-scheduler # GPU 스케줄러
- --leader-elect=false
# gpu-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: ml-training
spec:
schedulerName: gpu-scheduler # GPU 스케줄러 사용
containers:
- name: trainer
image: pytorch:latest
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
gpu: "true" # GPU 노드에만 배치
여러 스케줄러 동시 실행
# 3개의 스케줄러 동시 실행 예시
# 1. 기본 스케줄러
# (이미 실행 중)
# 2. GPU 스케줄러
apiVersion: apps/v1
kind: Deployment
metadata:
name: gpu-scheduler
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
component: gpu-scheduler
template:
spec:
serviceAccountName: gpu-scheduler
containers:
- name: scheduler
image: registry.k8s.io/kube-scheduler:v1.28.0
command:
- kube-scheduler
- --scheduler-name=gpu-scheduler
---
# 3. 배치 작업용 스케줄러
apiVersion: apps/v1
kind: Deployment
metadata:
name: batch-scheduler
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
component: batch-scheduler
template:
spec:
serviceAccountName: batch-scheduler
containers:
- name: scheduler
image: registry.k8s.io/kube-scheduler:v1.28.0
command:
- kube-scheduler
- --scheduler-name=batch-scheduler
각 스케줄러 사용 예시
# 일반 웹 애플리케이션
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
# schedulerName 생략 시 default-scheduler
containers:
- name: nginx
image: nginx
---
# GPU 학습 작업
apiVersion: v1
kind: Pod
metadata:
name: training
spec:
schedulerName: gpu-scheduler # GPU 스케줄러
containers:
- name: trainer
image: pytorch:latest
---
# 배치 작업
apiVersion: v1
kind: Pod
metadata:
name: batch-job
spec:
schedulerName: batch-scheduler # 배치 스케줄러
containers:
- name: processor
image: batch-processor:latest
### 정리
멀티 스케줄러 만들기 (간단한 방법)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. ServiceAccount 생성
└─ 스케줄러 실행 권한
2. RBAC 설정
└─ system:kube-scheduler 권한 부여
3. Deployment 배포
└─ --scheduler-name으로 이름 지정
4. Pod에서 사용
└─ schedulerName 필드로 선택
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
특징:
✅ 구현 간단 (기본 이미지 그대로 사용)
✅ 빠른 시작
⚠️ 스케줄링 로직은 동일
⚠️ 세밀한 제어 불가능
전체 동작 플로우
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
멀티 스케줄러 동작 과정
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 클러스터 상태
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
default-scheduler gpu-scheduler batch-scheduler
↓ ↓ ↓
대기 중 대기 중 대기 중
2. Pod 생성 요청
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
web-app ml-training batch-job
(scheduler 미지정) (gpu-scheduler) (batch-scheduler)
↓ ↓ ↓
default-scheduler gpu-scheduler batch-scheduler
선택 선택 선택
3. 스케줄링 처리
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
default-scheduler gpu-scheduler batch-scheduler
↓ ↓ ↓
일반 노드 검색 GPU 노드 검색 저부하 노드 검색
↓ ↓ ↓
Node2 선택 Node4 선택 Node3 선택
4. 최종 배치
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Node1 (Premium) Node2 (일반) Node3 (Spot)
• • web-app • batch-job
Node4 (GPU) Node5 (일반)
• ml-training •
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
각 Pod가 목적에 맞는 노드에 배치됨!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
상세 동작 예시: GPU Pod 스케줄링
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GPU Pod 스케줄링 상세 과정
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Pod 생성
ml-training (schedulerName: gpu-scheduler)
↓
2. gpu-scheduler가 담당
"이 Pod를 어디에 배치할까?"
↓
3. Filter 단계
Node1 (GPU 없음) → ❌ 제외
Node2 (일반) → ❌ 제외
Node3 (Spot) → ❌ 제외
Node4 (GPU 있음) → ✅ 통과
Node5 (일반) → ❌ 제외
↓
남은 노드: Node4
4. Score 단계 (생략, 1개만 남음)
↓
5. Bind 단계
ml-training → Node4에 배치!
↓
6. 실행
Node4에서 GPU 학습 작업 시작 🚀
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
이 방법은 같은 스케줄링 로직을 사용하지만 이름만 다른 스케줄러를 만드는 것입니다.
다음 섹션에서는 스케줄링 로직을 커스터마이징하는 방법을 살펴보겠습니다.
참고 자료
'프로그래밍 > Kubernetes' 카테고리의 다른 글
| AmazonLinux2에 EC2에 쿠버네티스 설치하기. (0) | 2023.07.02 |
|---|---|
| 쿠버네티스 공부 커리큘럼. (0) | 2023.04.23 |
댓글