From 87311e8141048a7746417d569cc928b308276852 Mon Sep 17 00:00:00 2001 From: Sam Huang <19882250+sam-huang1223@users.noreply.github.com> Date: Wed, 28 Oct 2026 17:47:41 -0700 Subject: [PATCH] fix(scheduler): keep PodScheduled in cached pods so unchanged conditions are not re-patched The pod informer transform kept only PodResizePending, so the status updater, which compares the new condition with the cached pod, never found PodScheduled and patched every pending pod's condition on every cycle, with a fresh lastTransitionTime. Keep PodScheduled too: the condition is then patched only when its status, reason or message changes. Fixes #2544 Co-Authored-By: Claude Opus 5.5 Signed-off-by: Sam Huang <19882250+sam-huang1223@users.noreply.github.com> (cherry picked from commit 4cf15ba4d5708fff47e5e8e457a7a3a11eb88681) --- .../unreleased/fixed-20261028-174735.yaml | 6 ++++++ pkg/scheduler/cache/pod_transform.go | 9 ++++++--- pkg/scheduler/cache/pod_transform_test.go | 20 +++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 .changes/unreleased/fixed-20261028-174735.yaml diff --git a/.changes/unreleased/fixed-20261028-174735.yaml b/.changes/unreleased/fixed-20261028-174735.yaml new file mode 100644 index 0000000000..45393cfc64 --- /dev/null +++ b/.changes/unreleased/fixed-20261028-174735.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: |- + Scheduler patches a pending pod's PodScheduled condition only when it changes, not every cycle +custom: + Author: "sam-huang1223" + Issue: "2544" diff --git a/pkg/scheduler/cache/pod_transform.go b/pkg/scheduler/cache/pod_transform.go index 1bfdc5f353..2311edb983 100644 --- a/pkg/scheduler/cache/pod_transform.go +++ b/pkg/scheduler/cache/pod_transform.go @@ -75,13 +75,16 @@ func compactContainerStatuses(statuses []v1.ContainerStatus) []v1.ContainerStatu return compact } +// compactConditions keeps PodResizePending for resize accounting and PodScheduled, which the status +// updater compares against so it patches the condition only when it changes. func compactConditions(conditions []v1.PodCondition) []v1.PodCondition { + var compact []v1.PodCondition for _, c := range conditions { - if c.Type == v1.PodResizePending { - return []v1.PodCondition{c} + if c.Type == v1.PodResizePending || c.Type == v1.PodScheduled { + compact = append(compact, c) } } - return nil + return compact } func compactContainers(containers []v1.Container) []v1.Container { diff --git a/pkg/scheduler/cache/pod_transform_test.go b/pkg/scheduler/cache/pod_transform_test.go index c60b967687..18084bd6c5 100644 --- a/pkg/scheduler/cache/pod_transform_test.go +++ b/pkg/scheduler/cache/pod_transform_test.go @@ -148,5 +148,25 @@ var _ = Describe("compactSchedulerPod", func() { Expect(compact.Annotations).To(HaveLen(2)) Expect(compact.ManagedFields).To(BeNil()) }) + + It("keeps PodScheduled, which the status updater compares before patching it", func() { + pod := succeededPod() + pod.Status.Phase = v1.PodPending + unschedulable := v1.PodCondition{ + Type: v1.PodScheduled, + Status: v1.ConditionFalse, + Reason: v1.PodReasonUnschedulable, + Message: "no nodes with enough resources", + LastTransitionTime: metav1.Unix(1767323045, 0), + } + resizePending := v1.PodCondition{Type: v1.PodResizePending, Status: v1.ConditionTrue} + pod.Status.Conditions = []v1.PodCondition{unschedulable, {Type: v1.PodReady}, resizePending} + + transformed, err := compactSchedulerPod(pod) + Expect(err).NotTo(HaveOccurred()) + + compact := transformed.(*v1.Pod) + Expect(compact.Status.Conditions).To(Equal([]v1.PodCondition{unschedulable, resizePending})) + }) }) })