Skip to content

Commit db82fd1

Browse files
authored
Merge pull request kubernetes#124618 from gabesaba/gated_performance
Filter gated pods before calling isPodWorthRequeueing
2 parents 5cb71ec + 5589459 commit db82fd1

File tree

4 files changed

+74
-26
lines changed

4 files changed

+74
-26
lines changed

pkg/scheduler/internal/queue/scheduling_queue.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,11 @@ func (p *PriorityQueue) movePodsToActiveOrBackoffQueue(logger klog.Logger, podIn
11751175

11761176
activated := false
11771177
for _, pInfo := range podInfoList {
1178+
// Since there may be many gated pods and they will not move from the
1179+
// unschedulable pool, we skip calling the expensive isPodWorthRequeueing.
1180+
if pInfo.Gated {
1181+
continue
1182+
}
11781183
schedulingHint := p.isPodWorthRequeuing(logger, pInfo, event, oldObj, newObj)
11791184
if schedulingHint == queueSkip {
11801185
// QueueingHintFn determined that this Pod isn't worth putting to activeQ or backoffQ by this event.

pkg/scheduler/internal/queue/scheduling_queue_test.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ var (
9494
}
9595
)
9696

97+
func setQueuedPodInfoGated(queuedPodInfo *framework.QueuedPodInfo) *framework.QueuedPodInfo {
98+
queuedPodInfo.Gated = true
99+
return queuedPodInfo
100+
}
101+
97102
func getUnschedulablePod(p *PriorityQueue, pod *v1.Pod) *v1.Pod {
98103
pInfo := p.unschedulablePods.get(pod)
99104
if pInfo != nil {
@@ -1452,6 +1457,14 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueueWithQueueingHint(t *testing.
14521457
hint: queueHintReturnSkip,
14531458
expectedQ: unschedulablePods,
14541459
},
1460+
{
1461+
name: "QueueHintFunction is not called when Pod is gated",
1462+
podInfo: setQueuedPodInfoGated(&framework.QueuedPodInfo{PodInfo: mustNewPodInfo(p), UnschedulablePlugins: sets.New("foo")}),
1463+
hint: func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
1464+
return framework.Queue, fmt.Errorf("QueueingHintFn should not be called as pod is gated")
1465+
},
1466+
expectedQ: unschedulablePods,
1467+
},
14551468
}
14561469

14571470
for _, test := range tests {
@@ -2733,7 +2746,7 @@ func TestPendingPodsMetric(t *testing.T) {
27332746
gated := makeQueuedPodInfos(total-queueableNum, "y", failme, timestamp)
27342747
// Manually mark them as gated=true.
27352748
for _, pInfo := range gated {
2736-
pInfo.Gated = true
2749+
setQueuedPodInfoGated(pInfo)
27372750
}
27382751
pInfos = append(pInfos, gated...)
27392752
totalWithDelay := 20

test/integration/scheduler/plugins/plugins_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2677,7 +2677,7 @@ func TestSchedulingGatesPluginEventsToRegister(t *testing.T) {
26772677
{
26782678
name: "preEnqueue plugin with event registered",
26792679
enqueuePlugin: &SchedulingGatesPluginWithEvents{SchedulingGates: schedulinggates.SchedulingGates{}},
2680-
count: 3,
2680+
count: 2,
26812681
},
26822682
}
26832683

test/integration/scheduler/queue_test.go

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,27 +57,27 @@ import (
5757

5858
func TestSchedulingGates(t *testing.T) {
5959
tests := []struct {
60-
name string
61-
pods []*v1.Pod
62-
want []string
63-
rmPodsSchedulingGates []int
64-
wantPostGatesRemoval []string
60+
name string
61+
pods []*v1.Pod
62+
schedule []string
63+
delete []string
64+
rmGates []string
6565
}{
6666
{
6767
name: "regular pods",
6868
pods: []*v1.Pod{
6969
st.MakePod().Name("p1").Container("pause").Obj(),
7070
st.MakePod().Name("p2").Container("pause").Obj(),
7171
},
72-
want: []string{"p1", "p2"},
72+
schedule: []string{"p1", "p2"},
7373
},
7474
{
7575
name: "one pod carrying scheduling gates",
7676
pods: []*v1.Pod{
7777
st.MakePod().Name("p1").SchedulingGates([]string{"foo"}).Container("pause").Obj(),
7878
st.MakePod().Name("p2").Container("pause").Obj(),
7979
},
80-
want: []string{"p2"},
80+
schedule: []string{"p2"},
8181
},
8282
{
8383
name: "two pod carrying scheduling gates, and remove gates of one pod",
@@ -86,9 +86,18 @@ func TestSchedulingGates(t *testing.T) {
8686
st.MakePod().Name("p2").SchedulingGates([]string{"bar"}).Container("pause").Obj(),
8787
st.MakePod().Name("p3").Container("pause").Obj(),
8888
},
89-
want: []string{"p3"},
90-
rmPodsSchedulingGates: []int{1}, // remove gates of 'p2'
91-
wantPostGatesRemoval: []string{"p2"},
89+
schedule: []string{"p3"},
90+
rmGates: []string{"p2"},
91+
},
92+
{
93+
name: "gated pod schedulable after deleting the scheduled pod and removing gate",
94+
pods: []*v1.Pod{
95+
st.MakePod().Name("p1").SchedulingGates([]string{"foo"}).Container("pause").Obj(),
96+
st.MakePod().Name("p2").Container("pause").Obj(),
97+
},
98+
schedule: []string{"p2"},
99+
delete: []string{"p2"},
100+
rmGates: []string{"p1"},
92101
},
93102
}
94103

@@ -107,6 +116,15 @@ func TestSchedulingGates(t *testing.T) {
107116
testutils.SyncSchedulerInformerFactory(testCtx)
108117

109118
cs, ns, ctx := testCtx.ClientSet, testCtx.NS.Name, testCtx.Ctx
119+
120+
// Create node, so we can schedule pods.
121+
node := st.MakeNode().Name("node").Obj()
122+
if _, err := cs.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}); err != nil {
123+
t.Fatal("Failed to create node")
124+
125+
}
126+
127+
// Create pods.
110128
for _, p := range tt.pods {
111129
p.Namespace = ns
112130
if _, err := cs.CoreV1().Pods(ns).Create(ctx, p, metav1.CreateOptions{}); err != nil {
@@ -122,30 +140,42 @@ func TestSchedulingGates(t *testing.T) {
122140
t.Fatal(err)
123141
}
124142

125-
// Pop the expected pods out. They should be de-queueable.
126-
for _, wantPod := range tt.want {
127-
podInfo := testutils.NextPodOrDie(t, testCtx)
128-
if got := podInfo.Pod.Name; got != wantPod {
129-
t.Errorf("Want %v to be popped out, but got %v", wantPod, got)
143+
// Schedule pods.
144+
for _, podName := range tt.schedule {
145+
testCtx.Scheduler.ScheduleOne(testCtx.Ctx)
146+
if err := wait.PollUntilContextTimeout(ctx, time.Millisecond*200, wait.ForeverTestTimeout, false, testutils.PodScheduled(cs, ns, podName)); err != nil {
147+
t.Fatalf("Failed to schedule %s", podName)
148+
}
149+
}
150+
151+
// Delete pods, which triggers AssignedPodDelete event in the scheduling queue.
152+
for _, podName := range tt.delete {
153+
if err := cs.CoreV1().Pods(ns).Delete(ctx, podName, metav1.DeleteOptions{}); err != nil {
154+
t.Fatalf("Error calling Delete on %s", podName)
155+
}
156+
if err := wait.PollUntilContextTimeout(ctx, time.Millisecond*200, wait.ForeverTestTimeout, false, testutils.PodDeleted(ctx, cs, ns, podName)); err != nil {
157+
t.Fatalf("Failed to delete %s", podName)
130158
}
131159
}
132160

133-
if len(tt.rmPodsSchedulingGates) == 0 {
134-
return
161+
// Ensure gated pods are not in ActiveQ
162+
if len(testCtx.Scheduler.SchedulingQueue.PodsInActiveQ()) > 0 {
163+
t.Fatal("Expected no schedulable pods")
135164
}
165+
136166
// Remove scheduling gates from the pod spec.
137-
for _, idx := range tt.rmPodsSchedulingGates {
167+
for _, podName := range tt.rmGates {
138168
patch := `{"spec": {"schedulingGates": null}}`
139-
podName := tt.pods[idx].Name
140169
if _, err := cs.CoreV1().Pods(ns).Patch(ctx, podName, types.StrategicMergePatchType, []byte(patch), metav1.PatchOptions{}); err != nil {
141170
t.Fatalf("Failed to patch pod %v: %v", podName, err)
142171
}
143172
}
144-
// Pop the expected pods out. They should be de-queueable.
145-
for _, wantPod := range tt.wantPostGatesRemoval {
146-
podInfo := testutils.NextPodOrDie(t, testCtx)
147-
if got := podInfo.Pod.Name; got != wantPod {
148-
t.Errorf("Want %v to be popped out, but got %v", wantPod, got)
173+
174+
// Schedule pods which no longer have gates.
175+
for _, podName := range tt.rmGates {
176+
testCtx.Scheduler.ScheduleOne(testCtx.Ctx)
177+
if err := wait.PollUntilContextTimeout(ctx, time.Millisecond*200, wait.ForeverTestTimeout, false, testutils.PodScheduled(cs, ns, podName)); err != nil {
178+
t.Fatalf("Failed to schedule %s", podName)
149179
}
150180
}
151181
})

0 commit comments

Comments
 (0)