Skip to content

Commit c048858

Browse files
Support multiple scheduling profiles in a single scheduler
Signed-off-by: Aldo Culquicondor <[email protected]>
1 parent fe9073b commit c048858

32 files changed

+1028
-535
lines changed

cmd/kube-scheduler/app/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ go_library(
1717
"//pkg/scheduler/apis/config:go_default_library",
1818
"//pkg/scheduler/framework/v1alpha1:go_default_library",
1919
"//pkg/scheduler/metrics:go_default_library",
20+
"//pkg/scheduler/profile:go_default_library",
2021
"//pkg/util/configz:go_default_library",
2122
"//pkg/util/flag:go_default_library",
2223
"//staging/src/k8s.io/api/core/v1:go_default_library",

cmd/kube-scheduler/app/config/config.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ type Config struct {
5353
CoreBroadcaster record.EventBroadcaster
5454

5555
EventClient v1beta1.EventsGetter
56-
Recorder events.EventRecorder
5756
Broadcaster events.EventBroadcaster
5857

5958
// LeaderElection is optional.

cmd/kube-scheduler/app/server.go

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package app
1919

2020
import (
2121
"context"
22-
"errors"
2322
"fmt"
2423
"io"
2524
"net/http"
@@ -59,6 +58,7 @@ import (
5958
kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
6059
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
6160
"k8s.io/kubernetes/pkg/scheduler/metrics"
61+
"k8s.io/kubernetes/pkg/scheduler/profile"
6262
"k8s.io/kubernetes/pkg/util/configz"
6363
utilflag "k8s.io/kubernetes/pkg/util/flag"
6464
)
@@ -172,34 +172,19 @@ func Run(ctx context.Context, cc schedulerserverconfig.CompletedConfig, outOfTre
172172
}
173173
}
174174

175-
if len(cc.ComponentConfig.Profiles) != 1 {
176-
// TODO(#85737): Support more than one profile.
177-
return errors.New("multiple scheduling profiles are unsupported")
178-
}
179-
profile := cc.ComponentConfig.Profiles[0]
180-
// Prepare event clients.
181-
if _, err := cc.Client.Discovery().ServerResourcesForGroupVersion(eventsv1beta1.SchemeGroupVersion.String()); err == nil {
182-
cc.Broadcaster = events.NewBroadcaster(&events.EventSinkImpl{Interface: cc.EventClient.Events("")})
183-
cc.Recorder = cc.Broadcaster.NewRecorder(scheme.Scheme, profile.SchedulerName)
184-
} else {
185-
recorder := cc.CoreBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: profile.SchedulerName})
186-
cc.Recorder = record.NewEventRecorderAdapter(recorder)
187-
}
188-
175+
recorderFactory := getRecorderFactory(&cc)
189176
// Create the scheduler.
190177
sched, err := scheduler.New(cc.Client,
191178
cc.InformerFactory,
192179
cc.PodInformer,
193-
cc.Recorder,
180+
recorderFactory,
194181
ctx.Done(),
195-
scheduler.WithName(profile.SchedulerName),
182+
scheduler.WithProfiles(cc.ComponentConfig.Profiles...),
196183
scheduler.WithAlgorithmSource(cc.ComponentConfig.AlgorithmSource),
197184
scheduler.WithPreemptionDisabled(cc.ComponentConfig.DisablePreemption),
198185
scheduler.WithPercentageOfNodesToScore(cc.ComponentConfig.PercentageOfNodesToScore),
199186
scheduler.WithBindTimeoutSeconds(cc.ComponentConfig.BindTimeoutSeconds),
200187
scheduler.WithFrameworkOutOfTreeRegistry(outOfTreeRegistry),
201-
scheduler.WithFrameworkPlugins(profile.Plugins),
202-
scheduler.WithFrameworkPluginConfig(profile.PluginConfig),
203188
scheduler.WithPodMaxBackoffSeconds(cc.ComponentConfig.PodMaxBackoffSeconds),
204189
scheduler.WithPodInitialBackoffSeconds(cc.ComponentConfig.PodInitialBackoffSeconds),
205190
)
@@ -336,6 +321,17 @@ func newHealthzHandler(config *kubeschedulerconfig.KubeSchedulerConfiguration, s
336321
return pathRecorderMux
337322
}
338323

324+
func getRecorderFactory(cc *schedulerserverconfig.CompletedConfig) profile.RecorderFactory {
325+
if _, err := cc.Client.Discovery().ServerResourcesForGroupVersion(eventsv1beta1.SchemeGroupVersion.String()); err == nil {
326+
cc.Broadcaster = events.NewBroadcaster(&events.EventSinkImpl{Interface: cc.EventClient.Events("")})
327+
return profile.NewRecorderFactory(cc.Broadcaster)
328+
}
329+
return func(name string) events.EventRecorder {
330+
r := cc.CoreBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: name})
331+
return record.NewEventRecorderAdapter(r)
332+
}
333+
}
334+
339335
// WithPlugin creates an Option based on plugin name and factory. This function is used to register out-of-tree plugins.
340336
func WithPlugin(name string, factory framework.PluginFactory) Option {
341337
return func(registry framework.Registry) error {

pkg/scheduler/BUILD

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ go_library(
2727
"//pkg/scheduler/internal/cache/debugger:go_default_library",
2828
"//pkg/scheduler/internal/queue:go_default_library",
2929
"//pkg/scheduler/metrics:go_default_library",
30+
"//pkg/scheduler/profile:go_default_library",
3031
"//pkg/scheduler/volumebinder:go_default_library",
3132
"//staging/src/k8s.io/api/core/v1:go_default_library",
3233
"//staging/src/k8s.io/api/storage/v1:go_default_library",
@@ -45,7 +46,6 @@ go_library(
4546
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
4647
"//staging/src/k8s.io/client-go/listers/policy/v1beta1:go_default_library",
4748
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
48-
"//staging/src/k8s.io/client-go/tools/events:go_default_library",
4949
"//vendor/k8s.io/klog:go_default_library",
5050
],
5151
)
@@ -81,6 +81,7 @@ go_test(
8181
"//pkg/scheduler/internal/queue:go_default_library",
8282
"//pkg/scheduler/listers:go_default_library",
8383
"//pkg/scheduler/nodeinfo:go_default_library",
84+
"//pkg/scheduler/profile:go_default_library",
8485
"//pkg/scheduler/testing:go_default_library",
8586
"//pkg/scheduler/volumebinder:go_default_library",
8687
"//staging/src/k8s.io/api/core/v1:go_default_library",
@@ -128,6 +129,7 @@ filegroup(
128129
"//pkg/scheduler/listers:all-srcs",
129130
"//pkg/scheduler/metrics:all-srcs",
130131
"//pkg/scheduler/nodeinfo:all-srcs",
132+
"//pkg/scheduler/profile:all-srcs",
131133
"//pkg/scheduler/testing:all-srcs",
132134
"//pkg/scheduler/util:all-srcs",
133135
"//pkg/scheduler/volumebinder:all-srcs",

pkg/scheduler/apis/config/testing/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ go_test(
1414
"//pkg/scheduler/apis/config:go_default_library",
1515
"//pkg/scheduler/apis/config/scheme:go_default_library",
1616
"//pkg/scheduler/core:go_default_library",
17+
"//pkg/scheduler/profile:go_default_library",
1718
"//staging/src/k8s.io/api/core/v1:go_default_library",
1819
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
1920
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
2021
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
2122
"//staging/src/k8s.io/client-go/informers:go_default_library",
2223
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
24+
"//staging/src/k8s.io/client-go/tools/events:go_default_library",
2325
"//staging/src/k8s.io/component-base/featuregate:go_default_library",
2426
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
2527
"//vendor/github.com/google/go-cmp/cmp:go_default_library",

pkg/scheduler/apis/config/testing/compatibility_test.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"testing"
2121

2222
"github.com/google/go-cmp/cmp"
23+
"k8s.io/client-go/tools/events"
24+
"k8s.io/kubernetes/pkg/scheduler/profile"
2325

2426
v1 "k8s.io/api/core/v1"
2527
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -1376,12 +1378,13 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
13761378
},
13771379
}
13781380
informerFactory := informers.NewSharedInformerFactory(client, 0)
1381+
recorderFactory := profile.NewRecorderFactory(events.NewBroadcaster(&events.EventSinkImpl{Interface: client.EventsV1beta1().Events("")}))
13791382

13801383
sched, err := scheduler.New(
13811384
client,
13821385
informerFactory,
13831386
informerFactory.Core().V1().Pods(),
1384-
nil,
1387+
recorderFactory,
13851388
make(chan struct{}),
13861389
scheduler.WithAlgorithmSource(algorithmSrc),
13871390
)
@@ -1390,7 +1393,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
13901393
t.Fatalf("Error constructing: %v", err)
13911394
}
13921395

1393-
gotPlugins := sched.Framework.ListPlugins()
1396+
defProf := sched.Profiles["default-scheduler"]
1397+
gotPlugins := defProf.Framework.ListPlugins()
13941398
if diff := cmp.Diff(tc.wantPlugins, gotPlugins); diff != "" {
13951399
t.Errorf("unexpected plugins diff (-want, +got): %s", diff)
13961400
}
@@ -1538,12 +1542,13 @@ func TestAlgorithmProviderCompatibility(t *testing.T) {
15381542

15391543
client := fake.NewSimpleClientset()
15401544
informerFactory := informers.NewSharedInformerFactory(client, 0)
1545+
recorderFactory := profile.NewRecorderFactory(events.NewBroadcaster(&events.EventSinkImpl{Interface: client.EventsV1beta1().Events("")}))
15411546

15421547
sched, err := scheduler.New(
15431548
client,
15441549
informerFactory,
15451550
informerFactory.Core().V1().Pods(),
1546-
nil,
1551+
recorderFactory,
15471552
make(chan struct{}),
15481553
opts...,
15491554
)
@@ -1552,7 +1557,8 @@ func TestAlgorithmProviderCompatibility(t *testing.T) {
15521557
t.Fatalf("Error constructing: %v", err)
15531558
}
15541559

1555-
gotPlugins := sched.Framework.ListPlugins()
1560+
defProf := sched.Profiles["default-scheduler"]
1561+
gotPlugins := defProf.ListPlugins()
15561562
if diff := cmp.Diff(tc.wantPlugins, gotPlugins); diff != "" {
15571563
t.Errorf("unexpected plugins diff (-want, +got): %s", diff)
15581564
}

pkg/scheduler/core/BUILD

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ go_library(
1818
"//pkg/scheduler/listers:go_default_library",
1919
"//pkg/scheduler/metrics:go_default_library",
2020
"//pkg/scheduler/nodeinfo:go_default_library",
21+
"//pkg/scheduler/profile:go_default_library",
2122
"//pkg/scheduler/util:go_default_library",
22-
"//pkg/scheduler/volumebinder:go_default_library",
2323
"//staging/src/k8s.io/api/core/v1:go_default_library",
2424
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
2525
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
@@ -66,6 +66,7 @@ go_test(
6666
"//pkg/scheduler/listers:go_default_library",
6767
"//pkg/scheduler/listers/fake:go_default_library",
6868
"//pkg/scheduler/nodeinfo:go_default_library",
69+
"//pkg/scheduler/profile:go_default_library",
6970
"//pkg/scheduler/testing:go_default_library",
7071
"//pkg/scheduler/util:go_default_library",
7172
"//staging/src/k8s.io/api/core/v1:go_default_library",

pkg/scheduler/core/extender_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
internalqueue "k8s.io/kubernetes/pkg/scheduler/internal/queue"
4343
"k8s.io/kubernetes/pkg/scheduler/listers"
4444
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
45+
"k8s.io/kubernetes/pkg/scheduler/profile"
4546
st "k8s.io/kubernetes/pkg/scheduler/testing"
4647
"k8s.io/kubernetes/pkg/scheduler/util"
4748
)
@@ -589,21 +590,22 @@ func TestGenericSchedulerWithExtenders(t *testing.T) {
589590
if err != nil {
590591
t.Fatal(err)
591592
}
593+
prof := &profile.Profile{
594+
Framework: fwk,
595+
}
592596

593597
scheduler := NewGenericScheduler(
594598
cache,
595599
queue,
596600
emptySnapshot,
597-
fwk,
598601
extenders,
599-
nil,
600602
informerFactory.Core().V1().PersistentVolumeClaims().Lister(),
601603
informerFactory.Policy().V1beta1().PodDisruptionBudgets().Lister(),
602604
false,
603605
schedulerapi.DefaultPercentageOfNodesToScore,
604606
false)
605607
podIgnored := &v1.Pod{}
606-
result, err := scheduler.Schedule(context.Background(), framework.NewCycleState(), podIgnored)
608+
result, err := scheduler.Schedule(context.Background(), prof, framework.NewCycleState(), podIgnored)
607609
if test.expectsErr {
608610
if err == nil {
609611
t.Errorf("Unexpected non-error, result %+v", result)

0 commit comments

Comments
 (0)