PodGroup 스케줄링
PodGroup 스케줄링 (PodGroup Scheduling)
이 기능을 사용하려면 사용자(또는 클러스터 관리자)가 클러스터의 모든 관련 컴포넌트에서 GenericWorkload 기능 게이트(feature gate)를 활성화해야 해요.
자세한 내용은 기능 게이트 활성화/비활성화 (Enable Or Disable Feature Gates)를 참고하세요.
표준 Kubernetes 스케줄러는 Pod를 순차적으로 평가합니다. 머신러닝 학습 작업 같은 여러 워크로드가 동시에 제출되면, 이런 순차 평가가 리소스 교착 상태(deadlock)로 이어질 수 있어요. 예를 들어 경쟁하는 두 워크로드가 각각 Pod의 일부를 스케줄해 클러스터 용량을 소모하지만, 어느 쪽도 완전히 시작하기에 충분한 리소스를 갖지 못하는 상황이 생길 수 있어요.
PodGroup 스케줄링 사이클은 Pod 그룹을 하나의 단위로 평가합니다. 스케줄러는 그룹의 모든 Pod에 대한 배치를 동시에 찾으려고 합니다. 전체 그룹의 요구 사항을 충족할 충분한 리소스를 찾지 못하면 어떤 Pod도 바인딩되지 않습니다.
또한 그룹을 통합된 엔티티로 취급하면 다른 그룹 기반 스케줄링 기능을 구현하기 쉬워지는 기반 아키텍처가 마련됩니다.
이 기능은 Workload API에 의존합니다. 클러스터에서 scheduling.k8s.io/v1beta1 API 그룹이 활성화되어 있는지 확인하세요.
출처: 문서
PodGroup 스케줄링 사이클 (PodGroup scheduling cycle)
Pod 그룹을 함께 스케줄링하기 위해 kube-scheduler는 PodGroup 스케줄링 사이클을 사용합니다. Pod를 개별적으로 처리하고 WaitOnPermit 게이트에 보관하는 대신, 스케줄러는 특정 PodGroup에 속한 대기 중인 Pod의 전체 그룹을 집합적으로 평가합니다. 각 Pod에 대해 별도의 스케줄링 사이클을 실행하는 대신, 전체 그룹에 대한 적합성을 평가하고 이후 바인딩 단계로 바로 이동해요.
스케줄러는 PodGroup에 속한 Pod를 관찰하면 그 Pod를 스케줄링 큐에 직접 추가하는 대신 해당 PodGroup과 연관시킵니다. 스케줄러가 PodGroup 객체와 그에 속한 Pod가 최소 하나 관찰할 때까지 PodGroup은 스케줄링 큐에 들어가지 않습니다. 스케줄러가 PodGroup을 꺼내면 그 그룹에서 관찰된 모든 스케줄되지 않은 Pod를 검색합니다. 그런 다음 우선순위와 스케줄러가 처음 관찰한 시간을 기준으로 결정론적으로 정렬하고, 다음과 같이 PodGroup 스케줄링 사이클을 시작합니다.
- 클러스터 상태 스냅샷 (Snapshotting the cluster state): 스케줄러가 PodGroup 평가를 시작하면 사이클 전체 기간 동안 지속되는 클러스터 상태의 단일 스냅샷을 찍습니다. 이는 평가가 전체 그룹에 대해 일관되게 유지되고 다른 이벤트와의 경쟁 조건을 방지하도록 보장합니다.
- 적합한 배치 찾기 (Finding feasible placements): 스케줄러는 PodGroup 스케줄링 알고리즘을 실행해 그룹의 Pod에 대한 유효한 노드 배치를 찾습니다.
- 원자적 결정 (Atomic decision): 알고리즘의 결과에 따라 스케줄링 결정은 전체 PodGroup에 대해 원자적으로 적용됩니다.
- 성공 (Success): 스케줄러가 Pod에 대한 충분한 리소스와 유효한 배치를 찾으면(예: 갱 스케줄링의
minCount제약 충족), 그 Pod들은 선택된 노드로 바인딩 사이클에 직접 진행합니다. 그룹의 나머지 스케줄 불가능한 Pod는 백오프 없이 활성 스케줄링 큐에 직접 다시 큐잉되며, 이전 타임스탬프를 유지해 선점을 시도하기 위해 즉시 재평가됩니다. 또한 다른 Pod가 이미 스케줄된 후 PodGroup에 새 Pod가 추가되면, 사이클은 기존 Pod를 고려하면서 새 Pod를 평가합니다. - 실패 (Failure): 스케줄러가 PodGroup을 적합하게 만들 충분한 리소스를 찾지 못하면(예:
minCount제약 충족 실패), 전체 PodGroup이 스케줄 불가능한 것으로 간주됩니다. 스케줄러는PodGroupPostFilter확장 지점을 실행해 PodGroup이 스케줄 가능해지도록 시도합니다.DefaultPreemption플러그인의PodGroupPostFilter확장 지점은 워크로드 인지 선점을 실행합니다.PodGroupPostFilter확장 지점을 구현하는 어떤 플러그인이든 Success 를 반환하면 더 이상PodGroupPostFilter확장 지점 플러그인은 실행되지 않습니다.PodGroupPostFilter플러그인이 Success 를 반환해도 어떤 Pod도 바인딩되지 않지만, 대신 모두 스케줄링 큐로 돌아갑니다.PodGroupPostFilter가 취한 조치가 다음 스케줄링 사이클에서 PodGroup이 스케줄 가능하게 만들기를 바라는 거죠. 표준 스케줄링 백오프 로직이 적용되어 PodGroup이 나중에 다시 시도될 수 있어요.
- 성공 (Success): 스케줄러가 Pod에 대한 충분한 리소스와 유효한 배치를 찾으면(예: 갱 스케줄링의
이 단일 사이클 방식을 사용함으로써 스케줄러는 부분적으로 스케줄된 그룹이 그룹의 나머지가 들어맞기를 무한정 기다리면서 클러스터 용량을 예약하는 비효율적인 병목을 피합니다.
PodGroup 스케줄링 알고리즘 (PodGroup scheduling algorithm)
기본 PodGroup 스케줄링 알고리즘은 기반 Pod 기반 스케줄링 알고리즘에 크게 의존합니다. Pod를 순회하며 각각에 대해 다음을 수행합니다.
- 표준 per-Pod 필터링 및 점수 계산 단계를 사용해 적합한 노드를 찾습니다. Pod가 들어맞으면 스케줄링 알고리즘이 끝날 때까지 선택된 노드에 일시적으로 가정되고 예약됩니다. Pod가 들어맞지 않으면 스케줄러는 PostFilter 확장 지점을 실행하지 않습니다. 대신 전체 PodGroup에 대해 실행되는
PodGroupPostFilter확장 지점에 의존합니다. - 누적 스케줄링 결과에 대해 그룹의 각 Pod를 평가한 후
PlacementFeasible확장 지점을 호출해 스케줄 가능한 Pod가 그룹의 스케줄링 기준(예: 갱 스케줄링의minCount)을 충족하는지 확인합니다. 어떤 Pod에 대해 Success 상태를 반환하면 PodGroup은 적합한 것으로 간주됩니다. 알고리즘이 Success 상태를 달성하지 못한 채 모든 Pod를 처리하거나, 이 사이클에서 어떤 Pod도 스케줄되지 않으면 PodGroup은 스케줄 불가능한 것으로 간주됩니다.
배치 스케줄링 알고리즘 (Placement scheduling algorithm)
이 기능을 사용하려면 클러스터의 모든 관련 컴포넌트에서 TopologyAwareWorkloadScheduling 기능 게이트를 활성화해야 해요.
자세한 내용은 기능 게이트 활성화/비활성화를 참고하세요.
**배치 스케줄링 알고리즘(Placement scheduling algorithm)**은 고려 중인 PodGroup에 대한 최적 배치를 찾기 위해 스케줄링 플러그인을 사용하는 대안적인 PodGroup 스케줄링 알고리즘이에요. 사용자는 플러그인을 사용·구성해 이 알고리즘을 자신의 특정 요구에 맞출 수 있습니다.
이 알고리즘은 주어진 PodGroup에 대해 세 가지 주요 단계로 진행됩니다.
1단계: 후보 배치 생성 (Phase 1: Candidate placement generation)
예를 들어 PodGroup의 스케줄링 제약(PodGroup 객체에 정의할 수 있음)에 기반해 후보 배치(PodGroup 할당에 이론적으로 적합한 노드의 부분집합)를 생성합니다.
이 단계는 PlacementGeneratePlugin 확장 지점으로 실행됩니다.
2단계: Pod 수준 필터링과 적합성 확인 (Phase 2: Pod-level filtering and feasibility check)
기본 PodGroup 스케줄링 알고리즘을 실행해 각 제안된 배치를 검증합니다. PodGroup에서 요구되는 수의 Pod가 들어맞을 수 있는지 확인하는 거죠. 들어맞을 수 있으면 그 배치는 적합한 것으로 표시됩니다.
3단계: 배치 점수 계산과 선택 (Phase 3: Placement scoring and selection)
모든 적합한 배치에 점수를 매겨 PodGroup에 대한 최적 도메인을 선택합니다.
이 단계는 PlacementScorePlugin 확장 지점으로 실행됩니다.
제한 사항 (Limitations)
PodGroup 스케줄링 알고리즘은 특정 Pod 정렬에 의존하며, 그룹의 Pod를 다른 순서로 처리했다면 발견했을 수 있는 유효한 배치를 찾지 못할 수 있어요. 특히:
- 기본 동질(homogeneous) Pod 그룹(모든 Pod가 동일한 스케줄링 요구 사항을 갖고 어피니티, 안티-어피니티, 토폴로지 분배 제약 같은 Pod 간 의존성이 없는 그룹)의 경우, 알고리즘은 배치가 존재하면 찾을 것으로 예상됩니다.
- 이질(heterogeneous) Pod 그룹의 경우 유효한 배치를 찾는 것이 보장되지 않습니다.
- Pod 간 의존성(Pod-group POD interdependencies)이 있는 Pod 그룹의 경우 유효한 배치를 찾는 것이 보장되지 않습니다.
위 사항에 더해, 그룹 내 의존성(intra-group dependencies)이 있는 경우(예: 파드 간 어피니티를 통해 한 Pod의 스케줄 가능성이 다른 그룹 구성원에 의존하는 경우) 이 알고리즘은 결정론적 처리 순서 때문에 클러스터 상태와 무관하게 배치를 찾지 못할 수 있어요.
전체 사이클 동안 일관된 동작을 위해, 단일 PodGroup에 속한 모든 Pod는 동일한 .spec.schedulerName을 공유해야 합니다. 이 요구 사항은 사이클이 시작되기 전에 검증되며, 제약이 충족되지 않으면 PodGroup은 거부됩니다.
CompositePodGroups를 이용한 계층적 스케줄링 (Hierarchical scheduling with CompositePodGroups)
이 기능을 사용하려면 클러스터의 모든 관련 컴포넌트에서 CompositePodGroup 기능 게이트를 활성화해야 해요.
자세한 내용은 기능 게이트 활성화/비활성화를 참고하세요.
CompositePodGroup 기능 게이트와 scheduling.k8s.io/v1alpha3 API 그룹이 활성화되면 스케줄러는 PodGroup 스케줄링 사이클을 확장해 다중 레벨 그룹 계층을 지원합니다.
계층적 워크로드에서 Pod는 잎 PodGroup 객체에 속하며, 해당 PodGroup은 루트 CompositePodGroup까지의 상위 CompositePodGroup 리소스를 지정합니다. 스케줄러는 그룹의 전체 계층을 단일한 통합 스케줄링 단위로 평가합니다.
계층적 스케줄링 사이클 실행 (Hierarchical scheduling cycle execution)
루트 CompositePodGroup을 관찰한 후, 그 루트의 그룹 계층에 속한 대기 중인 Pod가 최소 하나 있는 한 스케줄러는 그 루트를 스케줄링 큐에 배치합니다.
루트 CompositePodGroup이 계층적 쿼럼(hierarchical quorum)을 충족하면 스케줄링 사이클이 꺼낼 수 있는 활성 스케줄링 큐에 들어갑니다. CompositePodGroup에 대한 스케줄링 사이클의 흐름은 다음과 같습니다.
- 통합 클러스터 스냅샷과 검증 (Unified cluster snapshot and validation): 스케줄러는 최신 관찰된 클러스터 상태를 반영하는 클러스터 리소스의 스냅샷을 찍습니다. 큐에서 꺼낸 그룹 계층의 형태가 스냅샷된 계층과 일치하는지 검증하고, 계층의 구성 일관성(구성원 Pod 간 동일한
.spec.schedulerName과 우선순위 등)을 검증합니다. 계층 형태가 동시에 변경됐거나 검증에 실패하면 사이클은 중단되고 루트 CompositePodGroup을 다시 큐에 넣습니다. - 하향식 후보 배치 생성 (Top-down candidate placement generation): 계층의 각 레벨에서 하위 그룹을 평가하기 전에 스케줄러는
PlacementGeneratePlugin플러그인을 호출해 평가 중인 그룹에 대한 후보 배치(노드의 부분집합)를 생성합니다. 하위 CompositePodGroup이나 잎 PodGroup에 대한 후보 배치는 상위 그룹의 현재 평가 중인 배치에 속한 노드 부분집합에서만 생성됩니다. 루트 CompositePodGroup의 경우 모든 사용 가능한 클러스터 노드에서 후보 배치가 생성됩니다. - 재귀적 하위 트리 시뮬레이션과 적합성 확인 (Recursive subtree simulation and feasibility check): 스케줄러는 클러스터 스냅샷에서 그 배치를 일시적으로 가정하고 하위 그룹을 재귀적으로 스케줄링해 CompositePodGroup의 각 후보 배치를 평가합니다.
- 재귀 순회 (Recursive traversal): 스케줄러는 사전 정렬된 순서로 하위 그룹을 순회하며, CompositePodGroup에서 잎 PodGroup 객체까지 재귀적으로 자신을 호출합니다. 각 잎 PodGroup에 대해 스케줄러는 상위의 후보 배치에 범위가 제한된 배치 스케줄링 알고리즘을 실행해 메모리 내에서 잠정적인 Pod 할당을 만듭니다.
- 적합성 확인 (Feasibility checks): 각 하위 그룹을 평가한 후 스케줄러는
PlacementFeasible플러그인을 호출해 상위 그룹의 스케줄링 정책이 여전히 충족될 수 있는지 판단합니다. 정책 제약이 여전히 달성 가능하다면(또는 이미 충족됐다면) 스케줄러는 이후 형제 그룹 평가를 계속합니다. 정책 제약을 더 이상 충족할 수 없으면 스케줄러는 그 CompositePodGroup의 평가를 즉시 중단하고 그 그룹에 대해 만든 모든 잠정적 메모리 내 Pod 할당을 되돌립니다. - 시뮬레이션 롤백 (Simulation rollback): 후보 배치를 시뮬레이션한 후(성공 여부와 무관하게) 스케줄러는 다음 후보 배치를 평가하기 전에 그 시뮬레이션 중 만든 잠정적 노드 예약을 되돌립니다.
- 배치 점수 계산과 하위 트리 확정 (Placement scoring and subtree commitment): CompositePodGroup에 대한 모든 후보 배치가 평가된 후:
- 점수 계산 (Scoring): 하나 이상의 후보 배치가 적합하면 스케줄러는
PlacementScorePlugin플러그인을 호출해 모든 적합한 후보 배치에 점수를 매깁니다. 점수 계산 플러그인은 하위 트리의 모든 하위 잎 PodGroup 객체에 걸친 결합된 제안된 Pod 할당을 평가하고 가장 높은 전체 점수를 가진 배치를 선택합니다. - 확정 (Commitment): 승리 배치를 선택한 후 스케줄러는 그 최적 배치에 해당하는 잠정적 Pod 할당을 메모리에서 확정(가정)합니다. 이는 이후 형제 그룹 평가나 상위 레벨 평가가 그 하위 트리에 대해 일관되고 최적의 스케줄링 결정을 관찰하도록 보장합니다. 생성된 모든 후보 중 적합한 배치를 찾지 못하면 전체 CompositePodGroup은 스케줄 불가능한 것으로 간주됩니다.
- 점수 계산 (Scoring): 하나 이상의 후보 배치가 적합하면 스케줄러는
- 원자적 바인딩 (Atomic binding): 루트 레벨 재귀 평가가 성공하고 최소 하나의 Pod가 성공적으로 스케줄되면 스케줄러는 바인딩 사이클로 진행해 Pod 할당을 확정합니다. 그렇지 않으면 전체 CompositePodGroup이 스케줄 불가능한 것으로 간주됩니다.
제한 사항 (Limitations)
PodGroup 스케줄링 알고리즘이 특정 Pod 정렬에 의존하는 것처럼, 계층적 스케줄링 알고리즘은 모든 CompositePodGroup 계층 내에서 하위 그룹의 특정 정렬에 의존합니다. 그 결과 다른 순서로 하위 그룹을 처리했다면 발견했을 수 있는 유효한 배치를 찾지 못할 수 있어요.
또한 스케줄러가 그리디(greedy) 방식으로 그룹 계층을 평가하기 때문에:
- 클러스터에 배치가 존재하더라도 모든 경우에 유효한 배치를 찾는 것이 보장되지 않습니다.
- 스케줄러가 CompositePodGroup 계층에 대한 유효한 배치를 성공적으로 찾더라도 그 배치가 클러스터 전체에서 최적이라고 보장되지 않습니다.
PodGroup 컨디션 (PodGroup conditions)
PodGroup 스케줄링 사이클이 완료된 후 스케줄러는 PodGroup의 status.conditions에 컨디션을 업데이트합니다.
- PodGroupInitiallyScheduled: PodGroup이 처음으로 성공적으로 스케줄됐는지 보고합니다.
PodGroupInitiallyScheduled
스케줄링 사이클이 성공하면 컨디션은 이유 Scheduled와 함께 True로 설정됩니다. gang 정책 PodGroup의 경우 최소 minCount 개의 Pod가 배치됐다는 뜻입니다.
스케줄링이 실패하면 컨디션은 다음 이유 중 하나와 함께 False로 설정됩니다.
- Unschedulable — 리소스 제약, 어피니티 또는 안티-어피니티 규칙, 또는 갱에 대한 충분한 용량 부족으로 그룹을 배치할 수 없음.
- SchedulerError — 내부 스케줄러 오류(예:
nodeAffinity같은 스케줄링 제약을 파싱하는 동안)로 스케줄링이 실패함.
이 컨디션이 True로 설정되면 다시는 변하지 않습니다.
컨디션은 다음과 같이 확인할 수 있어요.
kubectl get podgroup <name> -o jsonpath='{.status.conditions}'
CompositePodGroup 컨디션 (CompositePodGroup conditions)
이 기능을 사용하려면 클러스터의 모든 관련 컴포넌트에서 CompositePodGroup 기능 게이트를 활성화해야 해요.
자세한 내용은 기능 게이트 활성화/비활성화를 참고하세요.
CompositePodGroup API도 status.conditions 필드를 노출합니다.
다만 v1.37에서는 스케줄러가 이 필드를 채우지 않습니다.
다음 단계 (What's next)
- Workload API 알아보기
- CompositePodGroup API와 그 수명 주기 읽어보기
- 토폴로지 인지 워크로드 스케줄링 (Topology-aware workload scheduling) 알아보기
- Pod에서 Workload 참조하는 방법 보기
- 갱 스케줄링 읽어보기