Merge pull request #127109 from sanposhiho/precheck-move

feat: disable preCheck when QHint is enabled
This commit is contained in:
Kubernetes Prow Robot 2024-09-05 17:19:57 +01:00 committed by GitHub
commit 52d4972901
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 6 deletions

View File

@ -111,10 +111,9 @@ type SchedulingQueue interface {
Done(types.UID)
Update(logger klog.Logger, oldPod, newPod *v1.Pod)
Delete(pod *v1.Pod)
// TODO(sanposhiho): move all PreEnqueueCheck to Requeue and delete it from this parameter eventually.
// Some PreEnqueueCheck include event filtering logic based on some in-tree plugins
// and it affect badly to other plugins.
// See https://github.com/kubernetes/kubernetes/issues/110175
// Important Note: preCheck shouldn't include anything that depends on the in-tree plugins' logic.
// (e.g., filter Pods based on added/updated Node's capacity, etc.)
// We know currently some do, but we'll eventually remove them in favor of the scheduling queue hint.
MoveAllToActiveOrBackoffQueue(logger klog.Logger, event framework.ClusterEvent, oldObj, newObj interface{}, preCheck PreEnqueueCheck)
AssignedPodAdded(logger klog.Logger, pod *v1.Pod)
AssignedPodUpdated(logger klog.Logger, oldPod, newPod *v1.Pod, event framework.ClusterEvent)

View File

@ -605,6 +605,13 @@ func addAllEventHandlers(
}
func preCheckForNode(nodeInfo *framework.NodeInfo) queue.PreEnqueueCheck {
if utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) {
// QHint is initially created from the motivation of replacing this preCheck.
// It assumes that the scheduler only has in-tree plugins, which is problematic for our extensibility.
// Here, we skip preCheck if QHint is enabled, and we eventually remove it after QHint is graduated.
return nil
}
// Note: the following checks doesn't take preemption into considerations, in very rare
// cases (e.g., node resizing), "pod" may still fail a check but preemption helps. We deliberately
// chose to ignore those cases as unschedulable pods will be re-queued eventually.

View File

@ -115,6 +115,7 @@ func TestPreCheckForNode(t *testing.T) {
nodeFn func() *v1.Node
existingPods, pods []*v1.Pod
want []bool
qHintEnabled bool
}{
{
name: "regular node, pods with a single constraint",
@ -137,6 +138,28 @@ func TestPreCheckForNode(t *testing.T) {
},
want: []bool{true, false, false, true, false, true, false, true, false},
},
{
name: "no filtering when QHint is enabled",
nodeFn: func() *v1.Node {
return st.MakeNode().Name("fake-node").Label("hostname", "fake-node").Capacity(cpu8).Obj()
},
existingPods: []*v1.Pod{
st.MakePod().Name("p").HostPort(80).Obj(),
},
pods: []*v1.Pod{
st.MakePod().Name("p1").Req(cpu4).Obj(),
st.MakePod().Name("p2").Req(cpu16).Obj(),
st.MakePod().Name("p3").Req(cpu4).Req(cpu8).Obj(),
st.MakePod().Name("p4").NodeAffinityIn("hostname", []string{"fake-node"}).Obj(),
st.MakePod().Name("p5").NodeAffinityNotIn("hostname", []string{"fake-node"}).Obj(),
st.MakePod().Name("p6").Obj(),
st.MakePod().Name("p7").Node("invalid-node").Obj(),
st.MakePod().Name("p8").HostPort(8080).Obj(),
st.MakePod().Name("p9").HostPort(80).Obj(),
},
qHintEnabled: true,
want: []bool{true, true, true, true, true, true, true, true, true},
},
{
name: "tainted node, pods with a single constraint",
nodeFn: func() *v1.Node {
@ -194,13 +217,15 @@ func TestPreCheckForNode(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerQueueingHints, tt.qHintEnabled)
nodeInfo := framework.NewNodeInfo(tt.existingPods...)
nodeInfo.SetNode(tt.nodeFn())
preCheckFn := preCheckForNode(nodeInfo)
var got []bool
got := make([]bool, 0, len(tt.pods))
for _, pod := range tt.pods {
got = append(got, preCheckFn(pod))
got = append(got, preCheckFn == nil || preCheckFn(pod))
}
if diff := cmp.Diff(tt.want, got); diff != "" {