Kube-scheduler의 구조: 파드가 노드에 할당되기까지의 여정
쿠버네티스 클러스터에서 파드(Pod)가 생성되면, 이 파드가 실제로 어느 워커 노드에서 실행될지 결정하는 과정은 전적으로 Kube-scheduler의 몫입니다. 사용자가 API 서버에 파드 생성을 요청하면, API 서버는 파드 객체를 etcd에 저장하지만 파드의 명세(Spec) 중 nodeName 필드는 비어있는 상태(Pending)로 남겨둡니다. Kube-scheduler는 바로 이 nodeName이 비어있는 파드들을 감시(Watch)하다가 가장 적절한 노드를 찾아 짝지어주는 중매쟁이 역할을 수행합니다. 파드가 큐에 진입하여 최종적으로 노드에 바인딩되기까지의 여정은 매우 정교한 다단계 필터링과 채점 과정을 거치게 됩니다.

1. 스케줄링 큐 (Scheduling Queue) 아키텍처
Kube-scheduler가 파드를 처리하는 첫 관문은 스케줄링 큐입니다. 수많은 파드가 동시에 생성될 때, 스케줄러는 이를 무작위로 처리하지 않고 내부적인 3개의 큐를 통해 효율적으로 관리합니다.
- activeQ (활성 대기열): 스케줄링을 즉시 시도할 파드들이 대기하는 큐입니다. 스케줄러의 워커 스레드는 이 큐에서 파드를 하나씩 꺼내어 노드 할당을 시작합니다.
- podBackoffQ (백오프 대기열): 스케줄링에 실패한 파드들이 잠시 대기하는 공간입니다. 스케줄링에 실패하자마자 다시 activeQ로 들어가면 시스템 자원만 낭비되므로, 지수 백오프(Exponential Backoff) 알고리즘을 적용하여 점진적으로 대기 시간을 늘려가며 재시도를 유도합니다.
- unschedulableQ (스케줄링 불가 대기열): 현재 클러스터의 상태로는 절대 스케줄링될 수 없는 파드(예: 클러스터 전체 리소스 부족, 조건을 만족하는 노드 없음)가 머무는 큐입니다. 클러스터에 새로운 노드가 추가되거나 기존 파드가 삭제되어 리소스가 확보되는 등 상태 변화 이벤트가 발생하면, 이 큐에 있던 파드들은 다시 activeQ나 podBackoffQ로 이동하여 스케줄링 기회를 얻습니다.
2. 노드 필터링 (Filtering / Predicates)
activeQ에서 파드를 꺼내면 본격적인 '스케줄링 사이클(Scheduling Cycle)'이 시작됩니다. 첫 번째 핵심 단계는 필터링입니다. 이 단계에서는 클러스터 내의 모든 노드를 대상으로 해당 파드를 수용할 수 있는 '최소한의 자격 요건'을 갖추었는지 검사합니다. 통과하지 못한 노드는 후보군에서 즉시 탈락합니다.
- NodeResourcesFit: 파드가 요구하는 CPU와 메모리(Requests)를 노드가 현재 할당해 줄 수 있는지 검사합니다.
- NodePorts: 파드가 특정 호스트 포트(HostPort)를 요구할 경우, 해당 노드에서 그 포트가 이미 사용 중인지 확인합니다.
- TaintToleration: 노드에 설정된 테인트(Taint)를 파드가 톨러레이션(Toleration)으로 무시하고 들어갈 수 있는지 검사합니다.
- NodeAffinity (Required): 파드 명세에 반드시 특정 레이블(예:
disktype: ssd)을 가진 노드에만 배포되도록 강제(RequiredDuringSchedulingIgnoredDuringExecution) 설정되어 있다면 이를 검증합니다.
필터링 단계를 거친 후 남은 노드가 단 하나도 없다면 파드는 Pending 상태로 남게 되며 unschedulableQ로 이동합니다. 통과한 노드가 존재한다면 다음 단계인 스코어링으로 넘어갑니다.
3. 노드 스코어링 (Scoring / Priorities)
필터링이 '자격 미달'을 걸러내는 하드 제약(Hard Constraint)이라면, 스코어링은 합격한 노드들 중에서 '가장 최적의 노드'를 찾기 위해 점수를 매기는 소프트 제약(Soft Constraint) 과정입니다. 스케줄러는 통과한 각 노드에 대해 0점부터 100점까지의 점수를 부여하고 가중치를 합산합니다.
- ImageLocality: 파드가 실행하는 데 필요한 컨테이너 이미지가 이미 해당 노드에 다운로드되어 있는지 확인합니다. 이미지가 존재하면 이미지 풀링 시간을 절약할 수 있으므로 높은 점수를 부여합니다.
- NodeResourcesBalancedAllocation: 파드가 할당되었을 때 노드의 CPU와 메모리 사용 비율이 균형을 이루는지 평가합니다. 자원 편중을 막기 위해 밸런스가 좋은 노드에 가점을 줍니다.
- PodTopologySpread: 클러스터의 고가용성을 위해 파드들이 여러 가용 영역(AZ)이나 특정 토폴로지에 고르게 분산되도록 유도하여 점수를 계산합니다.
- NodeAffinity (Preferred): 강제 조건이 아닌 선호 조건(PreferredDuringSchedulingIgnoredDuringExecution)으로 지정된 레이블을 가진 노드에 더 높은 점수를 줍니다.
모든 플러그인의 점수와 가중치가 합산된 후, 가장 높은 총점을 획득한 노드가 최종 승리자가 됩니다. 만약 최고 동점자가 여러 명일 경우 스케줄러가 무작위로 하나를 선택합니다.
4. 스케줄링 프레임워크 (Scheduling Framework) 구조
과거 쿠버네티스의 스케줄링 로직은 핵심 코드에 강하게 결합되어 있어 커스터마이징이 매우 어려웠습니다. 이를 해결하기 위해 도입된 것이 스케줄링 프레임워크입니다. 스케줄링의 전체 흐름을 여러 개의 '확장 지점(Extension Points)'으로 쪼개어, 개발자가 기존 코드를 수정하지 않고도 플러그인 형태로 원하는 스케줄링 로직을 주입할 수 있게 만든 혁신적인 아키텍처입니다.
확장 지점은 앞서 설명한 필터링과 스코어링을 더욱 세분화합니다. 예를 들어 PreFilter에서는 노드 검사를 시작하기 전 파드의 정보를 미리 전처리하고, PostFilter는 필터링을 통과한 노드가 없을 때 우선순위가 낮은 다른 파드를 밀어내는 파드 선점(Preemption) 로직을 실행합니다. 또한 PreBind, Bind, PostBind와 같이 노드 할당이 확정된 이후의 작업까지 세밀하게 플러그인으로 제어할 수 있습니다. 이를 통해 클라우드 제공자나 엔터프라이즈 환경에 맞는 고도의 맞춤형 스케줄러를 쉽게 구성할 수 있습니다.
5. 바인딩 사이클 (Binding Cycle)과 충돌 제어
최적의 노드가 선택되면 스케줄링 사이클이 종료되고 '바인딩 사이클'이 시작됩니다. 바인딩 사이클은 스케줄러 내부가 아닌 실제 API 서버와 통신하여 파드의 상태를 변경하는 비동기 프로세스입니다.
가장 먼저 스케줄러는 내부 캐시에 해당 파드가 선택된 노드에 할당되었다고 가상으로 기록하는 AssumePod 작업을 수행합니다. API 서버와의 통신 및 etcd 저장에는 시간 지연이 발생하므로, 그사이에 다른 파드를 스케줄링할 때 리소스가 중복으로 계산되는 경쟁 상태(Race Condition)를 막기 위한 낙관적 잠금(Optimistic Locking) 기법입니다.
내부 캐시 업데이트가 완료되면, 스케줄러는 API 서버에 파드의 nodeName 필드를 선택된 노드의 이름으로 채워 넣은 Binding 오브젝트를 전송합니다. API 서버가 이 바인딩 정보를 etcd에 최종 커밋하게 되면, 해당 노드에서 대기하고 있던 Kubelet이 API 서버의 Watch 스트림을 통해 자신의 노드에 새로운 파드가 할당되었음을 감지하고 비로소 컨테이너 런타임을 호출하여 파드의 실제 실행 프로세스를 시작하게 됩니다. 이 전체 과정이 마이크로초 단위로 끊임없이 반복되며 클러스터의 거대한 자원 배분이 이루어집니다.
'1. K8s Core & Architecture > 1.1. 컨트롤 플레인 (Control Plane) 심층 분석' 카테고리의 다른 글
| 쿠버네티스 API 오브젝트 모델 이해: GVK(Group, Version, Kind)란? (0) | 2026.03.17 |
|---|---|
| 컨트롤 플레인 컴포넌트 간의 통신 아키텍처: 누가 누구와 어떻게 대화할까? (0) | 2026.03.16 |
| 컨트롤러 패턴(Controller Pattern) 완벽 이해: Reconcile 루프의 마법 (0) | 2026.03.16 |
| Kube-controller-manager의 역할: 클러스터의 상태를 유지하는 핵심 루프 (0) | 2026.03.16 |
| etcd의 Watcher 메커니즘과 Kube-apiserver의 실시간 동기화 원리 (0) | 2026.03.16 |