쿠버네티스 스케줄러 (Kube-Scheduler, Scheduler Framework)

A. Kube-Scheduler
A.1. Kube-Shceduler란 무엇인가
Scheduling[A-1]은 파드가 node[A-2]에 적합한지를 확인하는 과정이며,
해당 node에서 실행된 kubelet[A-3]이 파드를 실행할 수 있도록 조치해줍니다.
Kube-Scheduler[A-1]는 아래의 책임을 가지고 있습니다.
노드에 할당되지 않은 새로 생성된 파드들을 감시합니다.
감시한 모든 파드가 실행될 최적의 노드를 갖는 책임을 가집니다.
[명령어 1] Kube Scheduler
1. kube-scheduler 파드 조회하기
kubectl get pods -n kube-system | grep kube-scheduler
kube-scheduler-cp-k8s 1/1 Running 224 (13d ago) 39d
1. kube-scheduler 파드 Manifest 조회하기
kubectl get pod kube-scheduler-cp-k8s -n kube-system -o yaml | grep image
image: registry.k8s.io/kube-scheduler:v1.31.6
imagePullPolicy: IfNotPresent
image: registry.k8s.io/kube-scheduler:v1.31.6
imageID: registry.k8s.io/kube-scheduler@sha256:8a64af33c57346355dc3cc6f9225dbe771da30e2f427e802ce2340ec3b5dd9b5
즉, Scheduling을 간단하게 말하면,
파드[A-2]가 노드[A-3]에 적합한지 확인하는 과정이며,
해당 노드에서 실행된 Kubelet[A-3]이 파드를 실행할 수 있게 조치해줍니다.
A.2. Kube-Scheduler 추상적으로 이해하기
Kube-Shceduler는 추상적으로 보면 3단계로 구성되어 있습니다.
Filtering : 파드 요구사항과 노드 상태를 취합해 사용 가능한 노드 목록 추출
Scoring : 노드 목록 중에서 가장 최적의 노드를 고르기 위한 점수 계산
Binding : 파드를 실제로 해당 노드에서 실행하는 단계
즉, Filtering과 Scoring을 통해서 스케줄링 대상 노드를 1개로 특정하게 됩니다.
이 과정을 Scheduling Context라고 부르며 작업 특성에 따라 2종류로 구분합니다.
Scheduling Cycle : 파드를 배치할 노드를 탐색
Binding Cycle : 파드를 노드에 배치, 낙관적 바인딩*(Optimistic Binding)[A.2-1]
💡
[낙관적 바인딩*] Binding이 성공할 것이라고 낙관적으로 예측하여, Kube-Scheduler는 Binding의 완료를 기다리지 않고 다음 대상을 탐색한다.
이런 구조는 Scheduler Framework[A.2-2]에서 더 자세히 볼 수 있었습니다.
(Kube-Scheduler가 사용하는 프레임워크가 Scheduler Framework이다.)
A.3. Scheduler Framework 기본
Scheduler Framework의 실행 과정을 큰 범위에서부터 2, 3단계로 분류하였습니다.
하지만 실제로는 복잡하고 체계적으로 작동하며 몇 가지 이슈 포인트*가 있습니다.
Scheduling 대상을 찾고 지정하는 Queueing mechanism이 별도로 존재한다.
Scheduling 대상에 대한 11단계의 Scheduling 과정이 존재한다.
💡
[이슈 포인트*] 1. Scheduling 과정 중의 Race Condition 발생 가능성 2. Optimistic Binding 으로 인한 Resource Leak 발생 가능성
A.4. 파드 Queueing Mechanism
Queueing Mechanism[A.4-1]에서는 3가지 포인트를 이해하면 좋습니다.
3종류의 큐(Q, Queue)의 목적
각 큐 간에 메세지를 옮기는 고루틴(Goroutine)와 고함수(GoFunction)
활성 큐(ActiveQ)에서 선택(추출, pop)되는 대상
기본적으로 Queueing Mechanism에서는 3종류의 큐(Q)가 있습니다.
활성 큐(ActiveQ) : 즉각적인 스케줄링을 위한 파드
실패 큐(BackoOffQ) : 예약에 실패한 포드로 일반적으로 재시도함
스케쥴 불가 큐(UnschedulableQ) : 특정 조건의 발생하기를 기다리는 대기(parking) 파드용
또한 Queueing Mecahnism에는 메세지를 옮기는 2종류의 고루틴이 있습니다.
(정확한 명칭으로는 주기적 플러싱 고루틴(Periodic Flushing Goroutine)입니다.)
고루틴 이름 | flushUnschedulableQLeftover [A.4-2] | flushBackoffQCompleted [A.4-3] |
---|---|---|
주기 (최악) | 30초 (60초) | 1초 |
최소 시간* |
|
|
또한 특수한 경우에 이벤트 기반으로 호출되는 2종류의 고함수가 존재합니다.
물론 노드 추가, 업데이트, 기존 파드 삭제 등의 경우에는 아래 고함수를 호출합니다.
고루틴 이름 | MoveAllToActiveOrBackoffQueue [A.4-4] | movePodsToActiveOrBackkoffQueue (==moveRequest) [A.4-5] |
---|---|---|
이벤트 | 노드 추가 및 업데이트 | Pod, Node, Service, PV, PVC, StorageClass, CSI Node 변경 |
이유 | 환경이 변경된 이후에는 | 특정 설정이 변경된 이후에는 |
마지막으로 활성 큐(ActiveQ) [A.4-6]에서는 2가지 기준으로 파드를 선택합니다.
.spec.priority와 같은 우선순위*값
우선순위값이 동일한 경우에는 큐에 먼저 들어온 시간부터
시리즈 문서 중 PriorityClass란? [A.4-7]의 일부
파드의 우선순위(.spec.priority)는 기본적으로 0이며,
우선순위 클래스 이름(.spec.priorityClassName)이 할당된 경우,
우선순위 클래스(PriorityClass)의 값(.value)를 참조하게 됩니다.
-21억 ~ 10억은 사용자가 우선순위 클래스에서 할당할 수 있는 범위이며
10억 ~ 21억은 시스템에서 우선적으로 점유하고 있는 범위입니다.
따라서 시스템에서 사용되는 파드가 먼저 배포되는 현상을 이해할 수 있을 것입니다.
(노드가 새로 뜨면 반드시 aws-vpc-cni, coredns 등이 먼저 스케줄되는 현상)
A.5. 파드 Scheduling 11단계
[그림 3] 에서는 2, 3단계로 표현한 kube-scheduler는 실제로는 11단계입니다.
각 단계는 플러그인 API인지 내부 API인지에 따라서 2가지로 구분됩니다.
살구색 실선 박스(Extensible API)
회색 점선 박스(Internal API)
각 단계의 대략적인 목적(역할)을 이해하는 것을 우선으로 합니다.
이 과정에서 다양한 플러그인들 [A.5-1]들이 활용됩니다.
Filtering
PreFilter : 전제 조건 확인 또는 전처리
Filter : 조건에 맞는 노드 필터링
PostFilter(생략) : 조건에 맞는 노드가 없을 경우 호출 (DefaultPreemption)
Scoring
PreScore : Score 계산을 위한 전처리
Score : 여러 기준에 따라서 Score 계산
NomalizeScore : 다양한 Score의 합산을 100으로 만들기 위한 정규화
Reserve : 자원 경합을 방지하기 위한 Cache 업데이트 기능
Premit : Bind 시작을 의도적으로 지연 시킬 수 있음
Binding
WaitonPremit : Premit에서 건 Bind 지연을 위한 트리거가 풀릴 때까지 대기
PreBind : Bind 전에 필요한 리소스 준비
Bind : 파드를 노드에 Bind (Default Bind plugin)
PostBind : Bind 완료 후 처리 단계 (리소스 정리, 로깅 등)
A.6. 더 공부할 부분
작성일(25.04.09) 시점,
PriorityClass 공부를 위한 최소한의 수준을 배우는 목적을 달성했다고 생각합니다.
만약 이 글을 이어서 작성하게 된다면 아래 부분을 작성할 예정입니다.
Scheduler Framework default plugins 들의 코드 분석
Scheduler Framework 성능 튜닝과 관련된 테크닉
Scheduler Framework 실습