MR: Sync kube-queue recent commits to koord-queue - #13
Open
KunWuLuan wants to merge 15 commits into
Open
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
The controllers image (golang:alpine) has no git and cannot reach the private gitlab.alibaba-inc.com/eml/kubequeue-api module that replaces github.com/kube-queue/api. Because go.work is committed and copied by `ADD .`, `go build` ran in workspace mode, which ignores the module vendor/ directory and tried to resolve modules over the network — failing with `exec: "git": executable file not found`. Add a .dockerignore that drops go.work/go.work.sum from the build context so the image builds in module mode and uses the committed vendor/ (verified offline with an empty module cache for both cmd/main.go and cmd/controllers/main.go).
…ue/queue-policy Both the tree ElasticQuota plugin (quota Attributes) and the elasticquotav2 plugin (ElasticQuota labels) now resolve the per-queue policy from either the kube-queue/queue-policy or koord-queue/queue-policy key, via a shared queuepolicies.GetQueuePolicyFromLabels helper (kube-queue key takes precedence when both are set). The elasticquotav2 update-detection now compares against the resolved policy so a change via either key triggers a Queue update. Signed-off-by: yueming.wk <[email protected]>
…eueGroupPlugin env NewInTreeRegistry now registers all in-tree plugins (Priority, DefaultGroup, ResourceQuota, ElasticQuota, ElasticQuotaV2) unconditionally, following the KubeSchedulerConfiguration / koord-queue model. Which group plugin is active is decided by the KubeQueueConfiguration `plugins` list (NewFramework only instantiates the enabled ones); the QueueGroupPlugin env var no longer gates registration. Defaulting still yields [Priority, ElasticQuota], so the chart's default behavior is unchanged. The env-based NewFakeRegistry is left for tests. Signed-off-by: yueming.wk <[email protected]>
Explains how the ElasticQuota (tree) plugin resolves which quota a workload is charged against and which Queue it waits in, from the workload's labels/annotations. Signed-off-by: yueming.wk <[email protected]>
…on suite Add an envtest Ginkgo suite exercising the queue-level q.Preempt path: a higher-priority QueueUnit that exhausts its quota causes the scheduler to set ReclaimState on a lower-priority reserved victim (dequeue-to-preempt). Uses the elasticquotav1alpha1 (ElasticQuotaV2) plugin, whose Filter returns Unschedulable when over quota and thus routes into q.Preempt. Ships a minimal ElasticQuota v1alpha1 CRD (none exists in-repo). Also fix a nil-map panic in utils.UpdateQueueUnitStatusAndAnnotations: it wrote to newQueueUnit.Annotations without guarding a nil map, crashing the scheduler goroutine on the dequeue path for any QueueUnit created without annotations (the v1alpha1 Filter sets an oversold annotation; the tree plugin masked this by never setting one). Add doc/preemption.md documenting both preemption mechanisms. Signed-off-by: yueming.wk <[email protected]>
Signed-off-by: yueming.wk <[email protected]>
Signed-off-by: yueming.wk <[email protected]>
When a job's spec changes (e.g. priority class or annotation), the related QueueUnit's priority was not being updated because the reconciler only synced PodSets via updateQueueUnitReplicas. Add updateQueueUnitPriority to compare and sync PriorityClassName and Priority (including annotation override) from the job extension to the QueueUnit. This logic is gated on PAI_ENV being unset, as PAI uses a different priority management path. Signed-off-by: yueming.wk <[email protected]>
Key changes: 1. Remove TransGpuResource and oversold system to align with koord-queue open-source implementation 2. Optimize Resize logging: silently swap when resources unchanged, output a single log line when changed 3. Disable reconcilePodDeletion: the method cannot distinguish between pod-not-yet-created and pod-deleted, causing Replicas to be wrongly set to 0 after Dequeue, leading to used underestimation and over-admission 4. Modify IsQueueUnitDequeued: remove from queue when Request is satisfied to avoid duplicate scheduling; add IsQueueUnitFullyDequeued to preserve the old logic for preempt.go 5. Change QueueNotFound log to Warning event Affected files: - elasticquotainfo.go: remove TransGpuResource/oversold, add ResizeQueueUnit - elasticquota.go: simplify Filter, remove oversold logic - cache.go: CheckUsage interface drops oversold parameter, add resizeInPlace - api_handler.go: remove OverSoldUsed and related fields - resource_report_controller.go: disable reconcilePodDeletion - util.go: simplify IsQueueUnitDequeued, add IsQueueUnitFullyDequeued - const.go: remove oversold constants - gpu_transformer.go: delete entire file - preempt.go: use IsQueueUnitFullyDequeued - multi_scheduling_queue.go: QueueNotFound to Event - scheduler.go: remove oversold annotation propagation Signed-off-by: yueming.wk <[email protected]>
…NotFound
1. Fix updating flag not cleared after preemption reclaim:
- When IsQueueUnitReservedAnyResource=false AND IsQueueUnitSatisfied=false
(job-extension has reclaimed resources), clear the updating flag so
findNextQueueUnit can re-schedule the preempted victim.
- Before this fix, preempted victims were stuck in the queue forever
because updating prevented findNextQueueUnit from picking them up.
2. Add EventRecorder events at key preemption/reclaim points:
- Preempted (Warning): when ReclaimState is set on a victim
- Reclaimed (Normal): when updating is cleared after resource reclaim
3. Dedup QueueNotFound events:
- Add queueUnitNotFoundNotified set to track which QueueUnits have
already had their QueueNotFound event fired.
- Only fire the event once per QueueUnit, not every 10 seconds.
- Clear the tracking when a QueueUnit is successfully added to a queue.
4. Add integration tests:
- reserve_preemption_test.go: quota sufficient → Reserve preemption
- reclaim_reschedule_test.go: victim re-scheduled after reclaim
- priority_order_test.go: remaining tasks scheduled in priority order
5. Add preemption configuration guide (doc/preemption-guide.zh.md)
Signed-off-by: yueming.wk <[email protected]>
… port 1. Add nil check for EventRecorder in preempt.go and schedulingqueuev2.go to prevent nil pointer dereference in unit tests where EventRecorder returns nil. 2. Use random port (:0) for controller-runtime metrics server in filterpreemption test suite to avoid port 8080 conflicts. 3. Merge Priority and Block policy preemption tests into a single DescribeTable that runs the same test logic for both policies, verifying that preemption works regardless of QueuePolicy. Signed-off-by: yueming.wk <[email protected]>
When a Queue is auto-created from an ElasticQuota (v1alpha1) or
ElasticQuotaTree, all annotations with the 'kube-queue/' prefix are
now automatically synced to the Queue.
This allows users to configure preemption and other queue behaviors
directly on the ElasticQuota, e.g.:
metadata:
annotations:
kube-queue/wait-for-pods-running: "true"
kube-queue/enable-queueunit-preemption: "true"
For ElasticQuotaTree, attributes with the 'kube-queue/' prefix in
the tree node's spec.attributes are also synced to the Queue.
Changes:
- elasticquotav1alpha1: makeNewestQueueCr copies kube-queue/ annotations
from ElasticQuota to Queue (both create and update paths)
- elasticquotatree: ElasticQuotaInfo stores raw Attributes, exposes
GetKubeQueueAnnotations() method
- elastic_quota_tree: GetExpectedQuotas returns annotationsByQuota,
createQueues/syncQueues merge kube-queue/ annotations into Queue
Signed-off-by: yueming.wk <[email protected]>
…ait-for-pods-running queues - syncInFlightWorkers now also runs in Dequeued phase and counts pods with NodeName set as Running, so wait-for-pods-running queues are released as soon as pods are scheduled, even if they never reach Running (e.g. image pull failures) - keep quota accounting admission-based during Dequeued: do not back-fill Admissions[i].Resources from actual pod requests until the unit is Running - add overadmission envtest suite: submit a batch of queued units and churn by repeatedly deleting the scheduled-but-not-running head, asserting at most one unit holds the quota at any moment - add status.lastAllocateTime to the test QueueUnit CRD; the field was pruned by apiserver, which silently disabled the reconcilePodDeletion grace period and caused flaky over-admission in envtest Signed-off-by: yueming.wk <[email protected]>
Cherry-picked test files from kube-queue used kube-queue/ import paths and annotation prefixes. Replace with koord-queue/ equivalents. Also remove import of non-existent elasticquota tree plugin package in overadmission test suite. Signed-off-by: yueming.wk <[email protected]>
Fix CI failures: 1. Replace GetClient() with GetElasticQuotaClient() in schedulingqueuev2 and intelligentqueue test suites 2. Remove import of non-existent elasticquotatree package in elasticquotav1alpha1preemption suite_test.go, replace elasticquotatree.Name with string constant "ElasticQuota" Signed-off-by: yueming.wk <[email protected]>
KunWuLuan
force-pushed
the
cherry-pick-to-koord
branch
from
August 10, 2026 12:44
f7094b6 to
43efcac
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MR: Sync kube-queue recent commits to koord-queue
Overview
This MR cherry-picks 13 commits from the kube-queue repository (branch
fix/elasticquota-used-bias) into koord-queue, plus 1 adaptation commit that fixes import paths and annotation prefixes for the koord-queue codebase.All main code (
cmd/...andpkg/...) compiles successfully withgo build.fix/elasticquota-used-bias(kube-queue), since commit6be86910(last port from koord-queue)main(koord-queue)Commits
1.
d0e8024c— fix(build): exclude go.work from Docker context so builds use vendorProblem: When building the controllers Docker image (
golang:alpine),go.workis copied byADD .into the build context, causinggo buildto run in workspace mode. This ignores thevendor/directory and tries to resolve modules over the network. Since the image has no git and cannot reach the privategitlab.alibaba-inc.com/eml/kubequeue-apimodule, the build fails withexec: "git": executable file not found.Fix: Add a
.dockerignorethat dropsgo.work/go.work.sumfrom the Docker build context so the image builds in module mode and uses the committedvendor/.Files:
.dockerignore(new)2.
9fd65d33— feat(elasticquota): accept both kube-queue/queue-policy and koord-queue/queue-policyChange: The ElasticQuotaV2 plugin (
elasticquotav1alpha1) now resolves the per-queue policy from either thekoord-queue/queue-policyorkube-queue/queue-policylabel key, via a new sharedqueuepolicies.GetQueuePolicyFromLabels()helper. koord-queue key takes precedence when both are set.The
elasticquotav2update-detection now compares against the resolved policy, so a change via either key triggers a Queue update.koord-queue adaptation:
koord-queue/queue-policy(QueuePolicyLabelKey)QueuePolicyLabelKeyKubeQueue = "kube-queue/queue-policy"GetQueuePolicyFromLabels()checks koord-queue key first, falls back to kube-queue keyfindMatchedSupportPolicy()usesGetQueuePolicyFromLabels()instead of directQueuePolicyLabelKeyaccessFiles:
pkg/queue/queuepolicies/types.go— new constant + helper functionpkg/queue/queuepolicies/policykey_test.go(new) — tests for dual-key resolutionpkg/framework/plugins/elasticquotav1alpha1/elasticquota_handler.go— useGetQueuePolicyFromLabels()3.
17d6af0b— feat(plugins): select group plugin via KoordQueueConfiguration, not QueueGroupPlugin envChange:
NewInTreeRegistry()no longer selects plugins based on theQueueGroupPluginenvironment variable. Instead, all in-tree plugins (Priority, DefaultGroup, ResourceQuota, ElasticQuotaV2) are registered unconditionally. Which group plugin is actually active is decided by theKoordQueueConfigurationpluginslist (NewFrameworkonly instantiates the enabled ones), following theKubeSchedulerConfigurationmodel.The env-based
NewFakeRegistry()is preserved for tests.koord-queue adaptation:
KoordQueueConfiguration(notKubeQueueConfiguration)elasticquota(tree-based) plugin — package does not exist in koord-queueNewFakeRegistry()retains env-based logic for test compatibilityFiles:
pkg/framework/plugins/registry.go— refactorNewInTreeRegistry()pkg/framework/plugins/registry_test.go(new) — verify unconditional registration4.
c325b659— docs(elasticquota): add quota/queue mapping guide (EN + ZH)Change: New documentation explaining how the ElasticQuota plugin resolves which quota a workload is charged against and which Queue it waits in, from the workload's labels/annotations.
Files:
doc/elasticquota-queue-mapping.md,doc/elasticquota-queue-mapping.zh.md(new)5.
ecbd5c1d— test(preemption): add ElasticQuotaV2 queue-level preemption integration suiteChange: New envtest Ginkgo test suite exercising the queue-level
q.Preemptpath: a higher-priority QueueUnit that exhausts its quota causes the scheduler to setReclaimStateon a lower-priority reserved victim (dequeue-to-preempt). Uses theelasticquotav1alpha1(ElasticQuotaV2) plugin, whoseFilterreturnsUnschedulablewhen over quota and thus routes intoq.Preempt.Also fixes a nil-map panic in
utils.UpdateQueueUnitStatusAndAnnotations: it wrote tonewQueueUnit.Annotationswithout guarding a nil map, crashing the scheduler goroutine on the dequeue path for any QueueUnit created without annotations.Files:
doc/preemption.md(new) — documents both preemption mechanismspkg/test/integration/elasticquotav1alpha1preemption/crd/elasticquota-v1alpha1.yaml(new) — minimal CRDpkg/test/integration/elasticquotav1alpha1preemption/preemption_test.go(new)pkg/test/integration/elasticquotav1alpha1preemption/suite_test.go(new)pkg/utils/util.go— nil-map guard6.
0c73e92c— docs(preemption): add Chinese translation (preemption.zh.md)Files:
doc/preemption.zh.md(new)7.
8ce70d84— docs(preemption): drop the Tests section from both docsFiles:
doc/preemption.md,doc/preemption.zh.md8.
6452ed38— fix: sync queueunit priority when job spec changes in non-PAI scenariosProblem: When a job's spec changes (e.g. priority class or annotation), the related QueueUnit's priority was not being updated because the reconciler only synced PodSets via
updateQueueUnitReplicas.Fix: Add
updateQueueUnitPriority()to compare and syncPriorityClassNameandPriority(including annotation override) from the job extension to the QueueUnit. This logic is gated onPAI_ENVbeing unset, as PAI uses a different priority management path.koord-queue adaptation:
priorityFromAnnotation()function andPriorityAnnotationKeyconstant (absent in koord-queue, introduced in kube-queue commit6be86910)klogandstrconvimportsgithub.com/kube-queue/api/togithub.com/koordinator-sh/koord-queue/Files:
pkg/jobext/framework/default_job_reconciler.go— newupdateQueueUnitPriority(),priorityFromAnnotation(),priorityEqual()pkg/jobext/framework/update_priority_test.go(new) — parameterized tests9.
1a237380— fix: fix elastic quota used underestimation and over-admissionKey changes:
Remove TransGpuResource and oversold system to align with koord-queue open-source implementation
gpu_transformer.go(entire file)const.goelasticquotainfo.gousesutils.NewResource()instead ofutils.TransResourceList()elasticquota.gosimplifiesFilter(), removes oversold type switchcache.goCheckUsage()interface dropsisOversoldparameterOptimize Resize logging: silently swap when resources unchanged (
reflect.DeepEqual), output a single log line when changedDisable
reconcilePodDeletion: the method cannot distinguish between "pod not yet created" and "pod deleted", causing Replicas to be wrongly set to 0 after Dequeue, leading to used underestimation and over-admissionModify
IsQueueUnitDequeued: remove from queue when Request is satisfied to avoid duplicate scheduling; addIsQueueUnitFullyDequeuedto preserve the old logic forpreempt.goChange QueueNotFound log to Warning event
koord-queue adaptation:
elasticquota_handler.goremoves unusedutilsimportgit rm)Files (19 files, +438 / -507):
pkg/framework/plugins/elasticquotav1alpha1/elasticquotainfo.go— refactor resource conversionpkg/framework/plugins/elasticquotav1alpha1/elasticquota.go— simplify Filterpkg/framework/plugins/elasticquotav1alpha1/cache.go— CheckUsage interface changepkg/framework/plugins/elasticquotav1alpha1/api_handler.go— remove OverSoldUsed fieldspkg/utils/const.go— remove oversold constantspkg/utils/gpu_transformer.go— delete entire filepkg/utils/util.go— simplify IsQueueUnitDequeuedpkg/scheduler/scheduler.go— remove oversold annotation propagation10.
2cc0c497— fix: clear updating after reclaim, add preemption events, dedup QueueNotFoundKey changes:
Fix updating flag not cleared after preemption reclaim: when
IsQueueUnitReservedAnyResource=falseANDIsQueueUnitSatisfied=false(job-extension has reclaimed resources), clear the updating flag sofindNextQueueUnitcan re-schedule the preempted victim. Before this fix, preempted victims were stuck in the queue forever because updating preventedfindNextQueueUnitfrom picking them up.Add EventRecorder events at key preemption/reclaim points:
Preempted(Warning): when ReclaimState is set on a victimReclaimed(Normal): when updating is cleared after resource reclaimDedup QueueNotFound events: add
queueUnitNotFoundNotifiedset to track which QueueUnits have already had their QueueNotFound event fired. Only fire the event once per QueueUnit, not every 10 seconds. Clear the tracking when a QueueUnit is successfully added to a queue.Add integration tests:
reserve_preemption_test.go: quota sufficient → Reserve preemptionreclaim_reschedule_test.go: victim re-scheduled after reclaimpriority_order_test.go: remaining tasks scheduled in priority orderAdd preemption configuration guide (
doc/preemption-guide.zh.md)Files (7 files, +830 / -17):
pkg/queue/multischedulingqueue/multi_scheduling_queue.go— event enhancement and deduppkg/queue/queuepolicies/schedulingqueuev2/preempt.go— useIsQueueUnitFullyDequeuedpkg/queue/queuepolicies/schedulingqueuev2/schedulingqueuev2.go— updating clear logicdoc/preemption-guide.zh.md(new)11.
d5e7053c— test: add Block policy test, fix EventRecorder nil check, fix metrics portChanges:
EventRecorder nil check: add nil guard in
preempt.goandschedulingqueuev2.goto prevent nil pointer dereference in unit tests where EventRecorder returns nilRandom port: filterpreemption test suite uses
:0(random port) instead of fixed 8080 for controller-runtime metrics server to avoid port conflictsMerge Priority and Block policy tests: combine into a single
DescribeTablethat runs the same test logic for both policies, verifying preemption works regardless of QueuePolicyFiles (3 files, +67 / -67):
pkg/queue/queuepolicies/schedulingqueuev2/preempt.go— nil guardpkg/queue/queuepolicies/schedulingqueuev2/schedulingqueuev2.go— nil guardpkg/test/integration/elasticquotav1alpha1preemption/reserve_preemption_test.go— parameterized merge12.
42cbaf05— feat: sync koord-queue/ prefixed annotations from ElasticQuota to QueueChange: When a Queue is auto-created from an ElasticQuota (v1alpha1), all annotations with the
koord-queue/prefix are now automatically synced to the Queue object. This allows users to configure preemption and other queue behaviors directly on the ElasticQuota:koord-queue adaptation:
kube-queue/tokoord-queue/shouldSyncAnnotation()checkskoord-queue/prefixutils.QuotaKoordQueueEnableinstead ofutils.QuotaKubeQueueEnableFiles:
pkg/framework/plugins/elasticquotav1alpha1/elasticquota_handler.go—makeNewestQueueCrand update path add annotation sync13.
aa131d72— fix(jobext): count scheduled pods as running in Dequeued to unblock wait-for-pods-running queuesProblem: Queues using the
wait-for-pods-runningpolicy were not released in the Dequeued phase becausesyncInFlightWorkersonly ran during Running. If pods were scheduled but never reached Running (e.g. image pull failures), the queue would block indefinitely.Fix:
syncInFlightWorkersnow also runs in Dequeued phase and counts pods withNodeNameset as Running, sowait-for-pods-runningqueues are released as soon as pods are scheduledAdmissions[i].Resourcesfrom actual pod requests until the unit is Runningstatus.lastAllocateTimeto the test QueueUnit CRD; the field was pruned by apiserver, which silently disabled thereconcilePodDeletiongrace period and caused flaky over-admission in envtestFiles (6 files, +2803 / -23):
pkg/jobext/framework/resource_report_controller.go— syncInFlightWorkers extended to Dequeuedpkg/jobext/framework/resource_report_controller_test.go— test updatespkg/jobext/test/config/crd/queueunit-v1alpha1.yaml— add lastAllocateTimepkg/test/integration/overadmission/overadmission_test.go(new)pkg/test/integration/overadmission/suite_test.go(new)14.
f7094b6b— fix: adjust import paths and annotation prefixes for koord-queueChange: Adaptation commit that fixes import paths and annotation prefixes in cherry-picked test files. Replaces
github.com/kube-queue/kube-queue/andgithub.com/kube-queue/api/withgithub.com/koordinator-sh/koord-queue/equivalents. Also removes import of non-existentelasticquotatree plugin package in overadmission test suite, replacingelasticquotatree.Namewith string constant"ElasticQuota".Files (7 test files, +39 / -40)
koord-queue Adaptation Summary
github.com/kube-queue/kube-queue/→github.com/koordinator-sh/koord-queue/;github.com/kube-queue/api/→github.com/koordinator-sh/koord-queue/"kube-queue/→"koord-queue/in test fileskoord-queue/queue-policy; aliasQueuePolicyLabelKeyKubeQueueKubeQueueConfiguration→KoordQueueConfiguration"ElasticQuota"or removedpriorityFromAnnotationshouldSyncAnnotationkube-queue/tokoord-queue/QuotaKoordQueueEnableBuild Status
go build ./cmd/... ./pkg/...— PASSpartialRunningFirstSeen,GetClient) between the two codebases; these are not introduced by this MR.How to Review