diff --git a/pkg/scheduler/core/generic_scheduler.go b/pkg/scheduler/core/generic_scheduler.go index 73d6aa802a..c84d9f773c 100644 --- a/pkg/scheduler/core/generic_scheduler.go +++ b/pkg/scheduler/core/generic_scheduler.go @@ -986,11 +986,19 @@ func nodesWherePreemptionMightHelp(nodes []*v1.Node, failedPredicatesMap FailedP switch failedPredicate { case predicates.ErrNodeSelectorNotMatch, + predicates.ErrPodAffinityRulesNotMatch, predicates.ErrPodNotMatchHostName, predicates.ErrTaintsTolerationsNotMatch, predicates.ErrNodeLabelPresenceViolated, + // Node conditions won't change when scheduler simulates removal of preemption victims. + // So, it is pointless to try nodes that have not been able to host the pod due to node + // conditions. These include ErrNodeNotReady, ErrNodeUnderPIDPressure, ErrNodeUnderMemoryPressure, .... predicates.ErrNodeNotReady, predicates.ErrNodeNetworkUnavailable, + predicates.ErrNodeUnderDiskPressure, + predicates.ErrNodeUnderPIDPressure, + predicates.ErrNodeUnderMemoryPressure, + predicates.ErrNodeOutOfDisk, predicates.ErrNodeUnschedulable, predicates.ErrNodeUnknownCondition, predicates.ErrVolumeZoneConflict, @@ -998,7 +1006,6 @@ func nodesWherePreemptionMightHelp(nodes []*v1.Node, failedPredicatesMap FailedP predicates.ErrVolumeBindConflict: unresolvableReasonExist = true break - // TODO(bsalamat): Please add affinity failure cases once we have specific affinity failure errors. } } if !found || !unresolvableReasonExist { diff --git a/pkg/scheduler/core/generic_scheduler_test.go b/pkg/scheduler/core/generic_scheduler_test.go index d0611c55a5..6a6a1ee27a 100644 --- a/pkg/scheduler/core/generic_scheduler_test.go +++ b/pkg/scheduler/core/generic_scheduler_test.go @@ -1112,7 +1112,7 @@ func TestNodesWherePreemptionMightHelp(t *testing.T) { expected: map[string]bool{}, }, { - name: "pod affinity should be tried", + name: "ErrPodAffinityNotMatch should be tried as it indicates that the pod is unschedulable due to inter-pod affinity or anti-affinity", failedPredMap: FailedPredicateMap{ "machine1": []algorithm.PredicateFailureReason{algorithmpredicates.ErrPodAffinityNotMatch}, "machine2": []algorithm.PredicateFailureReason{algorithmpredicates.ErrPodNotMatchHostName}, @@ -1128,6 +1128,14 @@ func TestNodesWherePreemptionMightHelp(t *testing.T) { }, expected: map[string]bool{"machine1": true, "machine3": true, "machine4": true}, }, + { + name: "ErrPodAffinityRulesNotMatch should not be tried as it indicates that the pod is unschedulable due to inter-pod affinity, but ErrPodAffinityNotMatch should be tried as it indicates that the pod is unschedulable due to inter-pod affinity or anti-affinity", + failedPredMap: FailedPredicateMap{ + "machine1": []algorithm.PredicateFailureReason{algorithmpredicates.ErrPodAffinityRulesNotMatch}, + "machine2": []algorithm.PredicateFailureReason{algorithmpredicates.ErrPodAffinityNotMatch}, + }, + expected: map[string]bool{"machine2": true, "machine3": true, "machine4": true}, + }, { name: "Mix of failed predicates works fine", failedPredMap: FailedPredicateMap{ @@ -1138,6 +1146,16 @@ func TestNodesWherePreemptionMightHelp(t *testing.T) { }, expected: map[string]bool{"machine3": true, "machine4": true}, }, + { + name: "Node condition errors should be considered unresolvable", + failedPredMap: FailedPredicateMap{ + "machine1": []algorithm.PredicateFailureReason{algorithmpredicates.ErrNodeUnderDiskPressure}, + "machine2": []algorithm.PredicateFailureReason{algorithmpredicates.ErrNodeUnderPIDPressure}, + "machine3": []algorithm.PredicateFailureReason{algorithmpredicates.ErrNodeUnderMemoryPressure}, + "machine4": []algorithm.PredicateFailureReason{algorithmpredicates.ErrNodeOutOfDisk}, + }, + expected: map[string]bool{}, + }, } for _, test := range tests {