본문 바로가기
프로그래밍/Kubernetes

Kubernetes Multi Scheduler: 기초부터 실전까지 - Part 1

by Hwan2 2025. 10. 30.
반응형

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 학습 작업 시작 🚀

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

이 방법은 같은 스케줄링 로직을 사용하지만 이름만 다른 스케줄러를 만드는 것입니다.

다음 섹션에서는 스케줄링 로직을 커스터마이징하는 방법을 살펴보겠습니다.

참고 자료

 

 
 
 
 
재시도
반응형

댓글


스킨편집 -> html 편집에서