이전 글에서 “다중 스케줄러”를 다뤘다면, 이번 파트는 그 진화판입니다.
과거에는 스케줄러를 여러 개 쓰려면 스케줄러 프로세스(바이너리)를 여러 개 띄우는 방식이었는데, Kubernetes v1.18부터는 단일 kube-scheduler 프로세스 안에서 여러 개의 프로필(Profile) 을 정의해, 마치 여러 스케줄러처럼 동작하게 만들 수 있습니다.
핵심 효과:
- 운영 복잡도 감소(프로세스/배포 수 감소)
- 스케줄링 로직 충돌(경쟁 조건) 위험을 줄이는 방향으로 설계
- 워크로드별로 다른 스케줄링 정책을 적용 가능
1) 스케줄링 흐름 요약: Queue → Filter → Score → Bind
스케줄러는 대략 다음 단계를 거칩니다.
- Scheduling Queue(대기열)
생성된 Pod가 들어오고, 우선순위 등 기준에 따라 정렬됩니다. - Filter(필터링)
Pod를 올릴 수 없는 노드를 제외합니다.
예: CPU 10이 필요한데 남은 CPU가 부족한 노드는 탈락 - Score(점수 매기기)
남은 후보 노드들에 점수를 매겨 “가장 적합한 노드”를 선택합니다.
예: 여유가 더 많은 노드에 높은 점수 - Bind(바인딩)
최종 선택된 노드에 Pod를 실제로 바인딩합니다.
2) 이 단계들은 “플러그인”으로 구성된다
Kubernetes 스케줄러는 확장 가능한 Scheduling Framework 구조이며, 각 단계는 플러그인(plugins) 들이 담당합니다.
예시 플러그인 (강의에 나온 것들)
- Queue 정렬:
PrioritySort(우선순위 기반 정렬) - Filter:
NodeResourcesFit(노드 리소스 적합성) - Filter:
NodeName(Pod가 특정 nodeName을 가졌다면 그 노드만 허용) - Filter:
NodeUnschedulable(unschedulable=true 노드 제외) - Score:
NodeResourcesFit(리소스 여유 기반 점수) - Score:
ImageLocality(이미지가 이미 캐시된 노드에 가점) - Bind:
DefaultBinder(최종 바인딩 수행)
중요 포인트:
- 하나의 플러그인이 여러 단계에 걸쳐 동작할 수 있습니다. (
NodeResourcesFit처럼 Filter + Score) - Score 단계는 “거부”가 아니라 “선호”를 반영하는 단계입니다. 후보가 없으면 점수가 낮아도 배치될 수 있습니다(조건만 충족하면).
3) Extension Points: 플러그인이 꽂히는 “확장 지점”
각 단계는 더 세분화된 확장 지점을 제공합니다. 강의에서 언급한 대표 확장 지점들:
queueSortpreFilter,filter,postFilterpreScore,score,reserveScore(표현은 강의 흐름에 따라 다르게 들릴 수 있음)permitpreBind,bind,postBind
이 구조 덕분에:
- 기본 플러그인의 동작을 조정하거나
- 특정 확장 지점에 자체 플러그인을 연결할 수 있습니다.
4) 기존 다중 스케줄러 방식의 문제: 운영 부담 + 경쟁 조건
과거 방식:
default-scheduler,my-scheduler,my-scheduler2같은 서로 다른 스케줄러 프로세스를 각각 띄움- 각 프로세스는 각자 config를 가지고 스케줄링
문제:
- 배포/운영 포인트가 늘어남(프로세스/Deployment 수 증가)
- 서로 다른 스케줄러가 동시에 같은 노드를 대상으로 판단하면서 경쟁 조건(race condition) 이 생길 여지가 있음
5) 해결: v1.18의 “Scheduler Profiles”
Scheduler Profile은 “스케줄러 바이너리(프로세스) 1개” 안에서
profiles를 여러 개 정의하고- 각 profile에 서로 다른
schedulerName을 부여하여
마치 여러 스케줄러처럼 동작하게 합니다.
즉,
- 프로세스는 하나지만
- 워크로드는
spec.schedulerName으로 “어느 프로필을 쓸지” 선택합니다.
6) Scheduler Profile config 예시
6-1) 프로필 2개를 가진 단일 kube-scheduler
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
- schedulerName: my-custom-scheduler
이 상태에서는 “이름만 다른” 두 스케줄러가 생긴 것이고, 동작은 기본값 기준으로 동일합니다.
7) “프로필별로 다르게 동작”시키는 핵심: plugins 커스터마이징
프로필을 다르게 만들려면 각 프로필에서 플러그인을 활성/비활성화하거나, 가중치 등을 조정합니다.
7-1) 예: 특정 프로필에서 특정 플러그인을 끄기(개념 예시)
강의에서 말한 것처럼:
- 스케줄러2에서는
TaintToleration을 비활성화한다거나 - 스케줄러3에서는 사용자 플러그인을 활성화한다거나
- 혹은 score 관련 플러그인을 비활성화한다거나
아래는 “프로필별 plugins 섹션을 가진” 형태 예시입니다(구조 이해용).
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
- schedulerName: my-custom-scheduler
plugins:
filter:
disabled:
- name: TaintToleration
score:
disabled:
- name: "*"
포인트:
plugins.<extensionPoint>.disabled/enabled로 조절name: "*"패턴으로 “전부 끄기” 같은 정책도 표현 가능(강의에서 언급)
실제로 어떤 플러그인을 끄는 게 의미 있는지는 요구사항에 따라 다릅니다. 예컨대
TaintToleration을 끄면 노드 격리 전략이 무력화될 수 있어, 실무에서는 매우 신중해야 합니다.
8) 워크로드가 특정 프로필(스케줄러 이름)을 선택하는 방법
Pod(또는 Deployment 템플릿)에 schedulerName을 지정합니다.
apiVersion: v1
kind: Pod
metadata:
name: critical-batch
spec:
schedulerName: my-custom-scheduler
containers:
- name: app
image: nginx
이렇게 하면 단일 kube-scheduler 프로세스 안에 있더라도, my-custom-scheduler 프로필이 이 Pod를 스케줄링합니다.
9) 관찰/디버깅: 어떤 스케줄러(프로필)가 잡았는지 확인
이벤트 확인
kubectl get events --sort-by=.metadata.creationTimestamp
Scheduling 관련 이벤트의 source/from에 스케줄러 이름이 노출되는 경우가 많습니다.
스케줄러 로그 확인
스케줄러가 kube-system에 파드/디플로이먼트로 떠 있다면:
kubectl -n kube-system logs <kube-scheduler-pod>
10) 정리
- 스케줄링은 Queue → Filter → Score → Bind 흐름으로 이해하면 쉽다
- 각 단계는 플러그인 기반이며, 확장 지점(extension points)에 플러그인을 꽂아 동작을 바꿀 수 있다
- 과거엔 다중 스케줄러를 위해 프로세스를 여러 개 띄웠지만 운영 부담/경쟁 조건 문제가 있다
- Kubernetes v1.18부터는 Scheduler Profiles로 “단일 스케줄러 안에서 여러 스케줄러처럼” 운영 가능
- 프로필별 차별화는
plugins섹션으로 플러그인 활성/비활성화/구성 조정으로 만든다 - 워크로드는
spec.schedulerName으로 어떤 프로필을 쓸지 선택한다
'CKA' 카테고리의 다른 글
| Scheduling - Admission Controller 심화(Custom Webhook) (0) | 2025.12.30 |
|---|---|
| Scheduling - Admission Controller (0) | 2025.12.30 |
| Scheduling - Multiple Schedulers(Custom Scheduler) (0) | 2025.12.29 |
| Scheduling - PriorityClass (0) | 2025.12.29 |
| Scheduling - Static Pod (0) | 2025.12.29 |