@@ -461,9 +461,14 @@ func (allocator *defaultAllocator) Schedule(ctx context.Context, spec *AllocSpec
461461 }
462462
463463 // Build a set of live pool pod names for dead-pod detection during allocation requests.
464+ // Running pods (regardless of readiness) are considered live to avoid churn from transient
465+ // readiness probe flaps. Only truly terminal pods (Failed/Succeeded) or deleted pods
466+ // should trigger re-allocation.
464467 livePodSet := make (map [string ]struct {}, len (spec .Pods ))
465468 for _ , p := range spec .Pods {
466- livePodSet [p .Name ] = struct {}{}
469+ if p .Status .Phase == corev1 .PodRunning || p .Status .Phase == corev1 .PodPending {
470+ livePodSet [p .Name ] = struct {}{}
471+ }
467472 }
468473
469474 // Fetch pool allocation once and reuse it for both stale-sandbox cleanup and available-pod filtering.
@@ -545,21 +550,26 @@ func (allocator *defaultAllocator) getSandboxRequest(ctx context.Context, sandbo
545550 releasedSet [r ] = struct {}{}
546551 }
547552
548- // Filter out pods that no longer exist in the pool (e.g. externally deleted).
549- // Dead pods are treated as released so the sandbox can receive replacement allocations.
553+ // Filter out pods that no longer exist in the pool (e.g. externally deleted) and
554+ // pods that have been released AND are no longer live. Only unreleased live pods
555+ // should count toward the effective allocation when computing supplement.
556+ // Released pods that are still alive keep their slot to avoid premature supplement
557+ // (the recycle flow will eventually remove them from alloc-status).
550558 liveAllocated := make ([]string , 0 , len (allocated ))
551559 deadPods := make ([]string , 0 )
552560 for _ , p := range allocated {
553- if _ , exists := releasedSet [p ]; exists {
554- // Already released, keep in allocated for bookkeeping consistency.
555- liveAllocated = append (liveAllocated , p )
561+ _ , isReleased := releasedSet [p ]
562+ _ , isAlive := livePodSet [p ]
563+ if isReleased && ! isAlive {
564+ // Released and gone — no longer occupies a slot.
556565 continue
557566 }
558- if _ , alive := livePodSet [p ]; alive {
559- liveAllocated = append (liveAllocated , p )
560- } else {
567+ if ! isReleased && ! isAlive {
568+ // Not released but gone — externally deleted, needs re-allocation.
561569 deadPods = append (deadPods , p )
570+ continue
562571 }
572+ liveAllocated = append (liveAllocated , p )
563573 }
564574 if len (deadPods ) > 0 {
565575 log .Info ("Detected dead allocated pods, queuing for release to trigger re-allocation" ,
@@ -594,13 +604,20 @@ func (allocator *defaultAllocator) getSandboxRequest(ctx context.Context, sandbo
594604 }
595605
596606 toRelease := make ([]string , 0 )
607+ toReleaseSet := make (map [string ]struct {})
597608 for _ , r := range release {
598609 if _ , exists := releasedSet [r ]; ! exists {
599610 toRelease = append (toRelease , r )
611+ toReleaseSet [r ] = struct {}{}
600612 }
601613 }
602614 // Also queue dead pods for release so their allocation records are cleaned up.
603- toRelease = append (toRelease , deadPods ... )
615+ // Deduplicate against pods already in alloc-release to avoid duplicate recycle operations.
616+ for _ , dp := range deadPods {
617+ if _ , exists := toReleaseSet [dp ]; ! exists {
618+ toRelease = append (toRelease , dp )
619+ }
620+ }
604621
605622 replica := int32 (0 )
606623 if sandbox .Spec .Replicas != nil {
0 commit comments