Skip to content

Commit f13e2ed

Browse files
authored
Merge pull request kubernetes#86591 from ahg-g/ahg1-default
Added scheduler algorithm provider registrey.
2 parents c84b1a8 + 8fc2171 commit f13e2ed

File tree

3 files changed

+297
-3
lines changed

3 files changed

+297
-3
lines changed

pkg/scheduler/algorithmprovider/BUILD

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,53 @@ load(
88

99
go_library(
1010
name = "go_default_library",
11-
srcs = ["plugins.go"],
11+
srcs = [
12+
"plugins.go",
13+
"registry.go",
14+
],
1215
importpath = "k8s.io/kubernetes/pkg/scheduler/algorithmprovider",
13-
deps = ["//pkg/scheduler/algorithmprovider/defaults:go_default_library"],
16+
deps = [
17+
"//pkg/features:go_default_library",
18+
"//pkg/scheduler/algorithmprovider/defaults:go_default_library",
19+
"//pkg/scheduler/apis/config:go_default_library",
20+
"//pkg/scheduler/framework/plugins/defaultpodtopologyspread:go_default_library",
21+
"//pkg/scheduler/framework/plugins/imagelocality:go_default_library",
22+
"//pkg/scheduler/framework/plugins/interpodaffinity:go_default_library",
23+
"//pkg/scheduler/framework/plugins/nodeaffinity:go_default_library",
24+
"//pkg/scheduler/framework/plugins/nodename:go_default_library",
25+
"//pkg/scheduler/framework/plugins/nodeports:go_default_library",
26+
"//pkg/scheduler/framework/plugins/nodepreferavoidpods:go_default_library",
27+
"//pkg/scheduler/framework/plugins/noderesources:go_default_library",
28+
"//pkg/scheduler/framework/plugins/nodeunschedulable:go_default_library",
29+
"//pkg/scheduler/framework/plugins/nodevolumelimits:go_default_library",
30+
"//pkg/scheduler/framework/plugins/podtopologyspread:go_default_library",
31+
"//pkg/scheduler/framework/plugins/tainttoleration:go_default_library",
32+
"//pkg/scheduler/framework/plugins/volumebinding:go_default_library",
33+
"//pkg/scheduler/framework/plugins/volumerestrictions:go_default_library",
34+
"//pkg/scheduler/framework/plugins/volumezone:go_default_library",
35+
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
36+
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
37+
"//vendor/k8s.io/klog:go_default_library",
38+
],
1439
)
1540

1641
go_test(
1742
name = "go_default_test",
18-
srcs = ["plugins_test.go"],
43+
srcs = [
44+
"plugins_test.go",
45+
"registry_test.go",
46+
],
1947
embed = [":go_default_library"],
2048
deps = [
2149
"//pkg/scheduler:go_default_library",
2250
"//pkg/scheduler/apis/config:go_default_library",
51+
"//pkg/scheduler/framework/plugins:go_default_library",
52+
"//pkg/scheduler/framework/v1alpha1:go_default_library",
53+
"//pkg/scheduler/nodeinfo/snapshot:go_default_library",
54+
"//pkg/scheduler/volumebinder:go_default_library",
55+
"//staging/src/k8s.io/client-go/informers:go_default_library",
56+
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
57+
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
2358
],
2459
)
2560

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/*
2+
Copyright 2014 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package algorithmprovider
18+
19+
import (
20+
"fmt"
21+
22+
"k8s.io/apimachinery/pkg/runtime"
23+
utilfeature "k8s.io/apiserver/pkg/util/feature"
24+
"k8s.io/klog"
25+
"k8s.io/kubernetes/pkg/features"
26+
schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config"
27+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpodtopologyspread"
28+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality"
29+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity"
30+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity"
31+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename"
32+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports"
33+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodepreferavoidpods"
34+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources"
35+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable"
36+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits"
37+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread"
38+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration"
39+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding"
40+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions"
41+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone"
42+
)
43+
44+
// ClusterAutoscalerProvider defines the default autoscaler provider
45+
const ClusterAutoscalerProvider = "ClusterAutoscalerProvider"
46+
47+
// Config the configuration of an algorithm provider.
48+
type Config struct {
49+
FrameworkPlugins *schedulerapi.Plugins
50+
FrameworkPluginConfig []schedulerapi.PluginConfig
51+
}
52+
53+
// Registry is a collection of all available algorithm providers.
54+
type Registry map[string]*Config
55+
56+
// NewRegistry returns an algorithm provider registry instance.
57+
func NewRegistry(hardPodAffinityWeight int64) Registry {
58+
defaultConfig := getDefaultConfig(hardPodAffinityWeight)
59+
applyFeatureGates(defaultConfig)
60+
61+
caConfig := getClusterAutoscalerConfig(hardPodAffinityWeight)
62+
applyFeatureGates(caConfig)
63+
64+
return Registry{
65+
schedulerapi.SchedulerDefaultProviderName: defaultConfig,
66+
ClusterAutoscalerProvider: caConfig,
67+
}
68+
}
69+
70+
func getDefaultConfig(hardPodAffinityWeight int64) *Config {
71+
return &Config{
72+
FrameworkPlugins: &schedulerapi.Plugins{
73+
PreFilter: &schedulerapi.PluginSet{
74+
Enabled: []schedulerapi.Plugin{
75+
{Name: noderesources.FitName},
76+
{Name: nodeports.Name},
77+
{Name: interpodaffinity.Name},
78+
},
79+
},
80+
Filter: &schedulerapi.PluginSet{
81+
Enabled: []schedulerapi.Plugin{
82+
{Name: nodeunschedulable.Name},
83+
{Name: noderesources.FitName},
84+
{Name: nodename.Name},
85+
{Name: nodeports.Name},
86+
{Name: nodeaffinity.Name},
87+
{Name: volumerestrictions.Name},
88+
{Name: tainttoleration.Name},
89+
{Name: nodevolumelimits.EBSName},
90+
{Name: nodevolumelimits.GCEPDName},
91+
{Name: nodevolumelimits.CSIName},
92+
{Name: nodevolumelimits.AzureDiskName},
93+
{Name: volumebinding.Name},
94+
{Name: volumezone.Name},
95+
{Name: interpodaffinity.Name},
96+
},
97+
},
98+
PostFilter: &schedulerapi.PluginSet{
99+
Enabled: []schedulerapi.Plugin{
100+
{Name: interpodaffinity.Name},
101+
{Name: tainttoleration.Name},
102+
},
103+
},
104+
Score: &schedulerapi.PluginSet{
105+
Enabled: []schedulerapi.Plugin{
106+
{Name: noderesources.BalancedAllocationName, Weight: 1},
107+
{Name: imagelocality.Name, Weight: 1},
108+
{Name: interpodaffinity.Name, Weight: 1},
109+
{Name: noderesources.LeastAllocatedName, Weight: 1},
110+
{Name: nodeaffinity.Name, Weight: 1},
111+
{Name: nodepreferavoidpods.Name, Weight: 10000},
112+
{Name: defaultpodtopologyspread.Name, Weight: 1},
113+
{Name: tainttoleration.Name, Weight: 1},
114+
},
115+
},
116+
},
117+
FrameworkPluginConfig: []schedulerapi.PluginConfig{
118+
{
119+
Name: interpodaffinity.Name,
120+
Args: runtime.Unknown{Raw: []byte(fmt.Sprintf(`{"hardPodAffinityWeight":%d}`, hardPodAffinityWeight))},
121+
},
122+
},
123+
}
124+
}
125+
126+
func getClusterAutoscalerConfig(hardPodAffinityWeight int64) *Config {
127+
defaultConfig := getDefaultConfig(hardPodAffinityWeight)
128+
caConfig := Config{
129+
FrameworkPlugins: &schedulerapi.Plugins{},
130+
}
131+
defaultConfig.FrameworkPlugins.DeepCopyInto(caConfig.FrameworkPlugins)
132+
caConfig.FrameworkPluginConfig = append([]schedulerapi.PluginConfig(nil), defaultConfig.FrameworkPluginConfig...)
133+
134+
// Replace least with most requested.
135+
for i := range caConfig.FrameworkPlugins.Score.Enabled {
136+
if caConfig.FrameworkPlugins.Score.Enabled[i].Name == noderesources.LeastAllocatedName {
137+
caConfig.FrameworkPlugins.Score.Enabled[i].Name = noderesources.MostAllocatedName
138+
}
139+
}
140+
141+
return &caConfig
142+
}
143+
144+
func applyFeatureGates(config *Config) {
145+
// Only add EvenPodsSpread if the feature is enabled.
146+
if utilfeature.DefaultFeatureGate.Enabled(features.EvenPodsSpread) {
147+
klog.Infof("Registering EvenPodsSpread predicate and priority function")
148+
f := schedulerapi.Plugin{Name: podtopologyspread.Name}
149+
config.FrameworkPlugins.PreFilter.Enabled = append(config.FrameworkPlugins.PreFilter.Enabled, f)
150+
config.FrameworkPlugins.Filter.Enabled = append(config.FrameworkPlugins.Filter.Enabled, f)
151+
s := schedulerapi.Plugin{Name: podtopologyspread.Name, Weight: 1}
152+
config.FrameworkPlugins.Score.Enabled = append(config.FrameworkPlugins.Score.Enabled, s)
153+
}
154+
155+
// Prioritizes nodes that satisfy pod's resource limits
156+
if utilfeature.DefaultFeatureGate.Enabled(features.ResourceLimitsPriorityFunction) {
157+
klog.Infof("Registering resourcelimits priority function")
158+
// TODO(ahg-g): append to config.FrameworkPlugins.Score.Enabled when available.
159+
}
160+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package algorithmprovider
18+
19+
import (
20+
"testing"
21+
"time"
22+
23+
"github.com/google/go-cmp/cmp"
24+
"k8s.io/client-go/informers"
25+
"k8s.io/client-go/kubernetes/fake"
26+
"k8s.io/kubernetes/pkg/scheduler"
27+
"k8s.io/kubernetes/pkg/scheduler/apis/config"
28+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins"
29+
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
30+
nodeinfosnapshot "k8s.io/kubernetes/pkg/scheduler/nodeinfo/snapshot"
31+
"k8s.io/kubernetes/pkg/scheduler/volumebinder"
32+
)
33+
34+
func TestCompatibility(t *testing.T) {
35+
testcases := []struct {
36+
name string
37+
provider string
38+
wantPlugins map[string][]config.Plugin
39+
}{
40+
{
41+
name: "DefaultProvider",
42+
provider: config.SchedulerDefaultProviderName,
43+
},
44+
{
45+
name: "ClusterAutoscalerProvider",
46+
provider: ClusterAutoscalerProvider,
47+
},
48+
}
49+
for _, tc := range testcases {
50+
t.Run(tc.name, func(t *testing.T) {
51+
client := fake.NewSimpleClientset()
52+
informerFactory := informers.NewSharedInformerFactory(client, 0)
53+
54+
sched, err := scheduler.New(
55+
client,
56+
informerFactory,
57+
informerFactory.Core().V1().Pods(),
58+
nil,
59+
make(chan struct{}),
60+
scheduler.WithAlgorithmSource(config.SchedulerAlgorithmSource{
61+
Provider: &tc.provider,
62+
}))
63+
if err != nil {
64+
t.Fatalf("Error constructing: %v", err)
65+
}
66+
gotPlugins := sched.Framework.ListPlugins()
67+
68+
volumeBinder := volumebinder.NewVolumeBinder(
69+
client,
70+
informerFactory.Core().V1().Nodes(),
71+
informerFactory.Storage().V1().CSINodes(),
72+
informerFactory.Core().V1().PersistentVolumeClaims(),
73+
informerFactory.Core().V1().PersistentVolumes(),
74+
informerFactory.Storage().V1().StorageClasses(),
75+
time.Second,
76+
)
77+
providerRegistry := NewRegistry(1)
78+
config := providerRegistry[tc.provider]
79+
fwk, err := framework.NewFramework(
80+
plugins.NewInTreeRegistry(&plugins.RegistryArgs{
81+
VolumeBinder: volumeBinder,
82+
}),
83+
config.FrameworkPlugins,
84+
config.FrameworkPluginConfig,
85+
framework.WithClientSet(client),
86+
framework.WithInformerFactory(informerFactory),
87+
framework.WithSnapshotSharedLister(nodeinfosnapshot.NewEmptySnapshot()),
88+
)
89+
if err != nil {
90+
t.Fatalf("error initializing the scheduling framework: %v", err)
91+
}
92+
wantPlugins := fwk.ListPlugins()
93+
94+
if diff := cmp.Diff(wantPlugins, gotPlugins); diff != "" {
95+
t.Errorf("unexpected plugins diff (-want, +got): %s", diff)
96+
}
97+
})
98+
}
99+
}

0 commit comments

Comments
 (0)