Skip to content

Commit aee77bf

Browse files
committed
DRA scheduler: add special ActionType for ResourceClaim changes
Having a dedicated ActionType which only gets used when the scheduler itself already detects some change in the list of generated ResourceClaims of a pod avoids calling the DRA plugin for unrelated Pod changes.
1 parent d425353 commit aee77bf

File tree

9 files changed

+366
-99
lines changed

9 files changed

+366
-99
lines changed

pkg/scheduler/framework/events.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
v1 "k8s.io/api/core/v1"
2121
"k8s.io/apimachinery/pkg/api/equality"
2222
utilfeature "k8s.io/apiserver/pkg/util/feature"
23+
"k8s.io/dynamic-resource-allocation/resourceclaim"
2324
"k8s.io/kubernetes/pkg/api/v1/resource"
2425
"k8s.io/kubernetes/pkg/features"
2526
)
@@ -65,6 +66,8 @@ var (
6566
PodTolerationChange = ClusterEvent{Resource: Pod, ActionType: UpdatePodTolerations, Label: "PodTolerationChange"}
6667
// PodSchedulingGateEliminatedChange is the event when a pod's scheduling gate is changed.
6768
PodSchedulingGateEliminatedChange = ClusterEvent{Resource: Pod, ActionType: UpdatePodSchedulingGatesEliminated, Label: "PodSchedulingGateChange"}
69+
// PodGeneratedResourceClaimChange is the event when a pod's list of generated ResourceClaims changes.
70+
PodGeneratedResourceClaimChange = ClusterEvent{Resource: Pod, ActionType: UpdatePodGeneratedResourceClaim, Label: "PodGeneratedResourceClaimChange"}
6871
// NodeSpecUnschedulableChange is the event when unschedulable node spec is changed.
6972
NodeSpecUnschedulableChange = ClusterEvent{Resource: Node, ActionType: UpdateNodeTaint, Label: "NodeSpecUnschedulableChange"}
7073
// NodeAllocatableChange is the event when node allocatable is changed.
@@ -152,6 +155,9 @@ func PodSchedulingPropertiesChange(newPod *v1.Pod, oldPod *v1.Pod) (events []Clu
152155
extractPodSchedulingGateEliminatedChange,
153156
extractPodTolerationChange,
154157
}
158+
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) {
159+
podChangeExtracters = append(podChangeExtracters, extractPodGeneratedResourceClaimChange)
160+
}
155161

156162
for _, fn := range podChangeExtracters {
157163
if event := fn(newPod, oldPod); event != nil {
@@ -222,6 +228,14 @@ func extractPodSchedulingGateEliminatedChange(newPod *v1.Pod, oldPod *v1.Pod) *C
222228
return nil
223229
}
224230

231+
func extractPodGeneratedResourceClaimChange(newPod *v1.Pod, oldPod *v1.Pod) *ClusterEvent {
232+
if !resourceclaim.PodStatusEqual(newPod.Status.ResourceClaimStatuses, oldPod.Status.ResourceClaimStatuses) {
233+
return &PodGeneratedResourceClaimChange
234+
}
235+
236+
return nil
237+
}
238+
225239
// NodeSchedulingPropertiesChange interprets the update of a node and returns corresponding UpdateNodeXYZ event(s).
226240
func NodeSchedulingPropertiesChange(newNode *v1.Node, oldNode *v1.Node) (events []ClusterEvent) {
227241
nodeChangeExtracters := []nodeChangeExtractor{

pkg/scheduler/framework/events_test.go

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ import (
2424
v1 "k8s.io/api/core/v1"
2525
"k8s.io/apimachinery/pkg/api/resource"
2626
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+
utilfeature "k8s.io/apiserver/pkg/util/feature"
28+
featuregatetesting "k8s.io/component-base/featuregate/testing"
29+
"k8s.io/kubernetes/pkg/features"
2730
st "k8s.io/kubernetes/pkg/scheduler/testing"
31+
"k8s.io/utils/ptr"
2832
)
2933

3034
func TestNodeAllocatableChange(t *testing.T) {
@@ -334,11 +338,20 @@ func Test_podSchedulingPropertiesChange(t *testing.T) {
334338
},
335339
},
336340
}
341+
claimStatusA := v1.PodResourceClaimStatus{
342+
Name: "my-claim",
343+
ResourceClaimName: ptr.To("claim"),
344+
}
345+
claimStatusB := v1.PodResourceClaimStatus{
346+
Name: "my-claim-2",
347+
ResourceClaimName: ptr.To("claim-2"),
348+
}
337349
tests := []struct {
338-
name string
339-
newPod *v1.Pod
340-
oldPod *v1.Pod
341-
want []ClusterEvent
350+
name string
351+
newPod *v1.Pod
352+
oldPod *v1.Pod
353+
draDisabled bool
354+
want []ClusterEvent
342355
}{
343356
{
344357
name: "only label is updated",
@@ -388,9 +401,35 @@ func Test_podSchedulingPropertiesChange(t *testing.T) {
388401
oldPod: st.MakePod().Toleration("key").Obj(),
389402
want: []ClusterEvent{PodTolerationChange},
390403
},
404+
{
405+
name: "pod claim statuses change, feature disabled",
406+
draDisabled: true,
407+
newPod: st.MakePod().ResourceClaimStatuses(claimStatusA).Obj(),
408+
oldPod: st.MakePod().Obj(),
409+
want: []ClusterEvent{assignedPodOtherUpdate},
410+
},
411+
{
412+
name: "pod claim statuses change, feature enabled",
413+
newPod: st.MakePod().ResourceClaimStatuses(claimStatusA).Obj(),
414+
oldPod: st.MakePod().Obj(),
415+
want: []ClusterEvent{PodGeneratedResourceClaimChange},
416+
},
417+
{
418+
name: "pod claim statuses swapped",
419+
newPod: st.MakePod().ResourceClaimStatuses(claimStatusA, claimStatusB).Obj(),
420+
oldPod: st.MakePod().ResourceClaimStatuses(claimStatusB, claimStatusA).Obj(),
421+
want: []ClusterEvent{PodGeneratedResourceClaimChange},
422+
},
423+
{
424+
name: "pod claim statuses extended",
425+
newPod: st.MakePod().ResourceClaimStatuses(claimStatusA, claimStatusB).Obj(),
426+
oldPod: st.MakePod().ResourceClaimStatuses(claimStatusA).Obj(),
427+
want: []ClusterEvent{PodGeneratedResourceClaimChange},
428+
},
391429
}
392430
for _, tt := range tests {
393431
t.Run(tt.name, func(t *testing.T) {
432+
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DynamicResourceAllocation, !tt.draDisabled)
394433
got := PodSchedulingPropertiesChange(tt.newPod, tt.oldPod)
395434
if diff := cmp.Diff(tt.want, got); diff != "" {
396435
t.Errorf("unexpected event is returned from podSchedulingPropertiesChange (-want, +got):\n%s", diff)

pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ func (pl *dynamicResources) EventsToRegister(_ context.Context) ([]framework.Clu
400400
// Allocation is tracked in ResourceClaims, so any changes may make the pods schedulable.
401401
{Event: framework.ClusterEvent{Resource: framework.ResourceClaim, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterClaimChange},
402402
// Adding the ResourceClaim name to the pod status makes pods waiting for their ResourceClaim schedulable.
403-
{Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.Update}, QueueingHintFn: pl.isSchedulableAfterPodChange},
403+
{Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.UpdatePodGeneratedResourceClaim}, QueueingHintFn: pl.isSchedulableAfterPodChange},
404404
// A pod might be waiting for a class to get created or modified.
405405
{Event: framework.ClusterEvent{Resource: framework.DeviceClass, ActionType: framework.Add | framework.Update}},
406406
// Adding or updating a ResourceSlice might make a pod schedulable because new resources became available.

0 commit comments

Comments
 (0)