Skip to content

NodeResourceTopology scoring: three no-aligned-resource edge cases surfaced by #1214 #1216

Description

@thc1006

Follow-up to #1214 / #1215. While fixing the weightSum == 0 divide-by-zero in the score strategies, three related scoring behaviors surfaced when a container or scope contributes no aligned resource. They are distinct from the panic fix and are filed separately so #1215 stays a focused bug fix. Each was verified on current main.

1. Native pod-scope scores 0 for every node (inconsistent with native container-scope)

podScopeScore (pkg/scheduler/plugins/noderesourcetopology/score.go:189) scores with nativeAlignedResources, an empty but non-nil set (plugin.go:46, var nativeAlignedResources = sets.NewString()). The score strategies skip a resource when alignedResource != nil && !alignedResource.Has(...), so an empty non-nil set skips every requested resource, weightSum is 0, and the node score is 0 for all nodes.

The native container-scope path passes nil instead (score.go:112, containerScopeScore(..., nil)), which does score all resources. So a native pod on a SingleNUMANodePodLevel node scores 0 everywhere, while the same pod on a SingleNUMANodeContainerLevel node scores normally. This looks unintended; podScopeScore likely should pass nil too. (Before #1215 this path panicked rather than returning 0.)

Verified: mostAllocatedScoreStrategy({cpu:2}, {cpu:4}, {}, sets.NewString()) returns 0 (same for least).

2. A container with no aligned resource dilutes the container-scope mean

containerScopeScore (score.go:164-175) scores every container in append(InitContainers, Containers...) and returns int64(stat.Mean(contScore, nil)). A container with no aligned resource now scores 0 (after #1215) and that 0 is averaged in, so an init container with no requests pulls a node from 3 to mean([0,3]) = 1. "No scoring signal" and "lowest score" are currently the same 0.

Worth deciding whether a no-signal container should be excluded from the mean, or given a neutral contribution.

Verified: stat.Mean([0,3]) = 1.5 -> int64 1.

3. BalancedAllocation returns MinInt64 for an empty aligned-resource set

balanced_allocation.go builds resourceFractions per aligned resource and returns int64((1 - stat.Variance(resourceFractions, nil)) * MaxNodeScore) (:44, :49). When no aligned resource contributes, resourceFractions is empty, stat.Variance returns NaN, and int64((1 - NaN) * 100) is -9223372036854775808. This is a garbage score rather than a value in [0, MaxNodeScore]. The weightSum == 0 guard from #1215 does not cover this strategy, since it does not divide by weightSum.

Suggested: guard the empty fraction list before Variance and return a neutral score.

Verified: stat.Variance([]) = NaN, int64((1-NaN)*100) = -9223372036854775808.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions