mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 10:20:51 +00:00
Add profile level percentageOfNodesToScore
Fix conversion errors Changed the order update update fix manaul coversions keep the global parameter for backward compatibility Address Wei's comments Fix an error Fix issues Add unit tests for validation Fix a comment Address comments Update comments fix verifiation errors Add tests for scheme_test.go Convert percentageOfNodesToScore to pointer Fix errors Resolve conflicts Fix testing errors Address Wei's comments Revert IntPtr to Int changes Address comments Not overrite percentageOfNodesToScore Fix a bug Fix a bug change errs to err Fix a nit Remove duplication Address comments Fix lint warning Fix an issue Update comments Clean up Address comments Revert changes to defaults fix unit test error Update Fix tests Use default PluginConfigs
This commit is contained in:
parent
215f236a6b
commit
7297f48f12
@ -42,6 +42,7 @@ import (
|
||||
configtesting "k8s.io/kubernetes/pkg/scheduler/apis/config/testing"
|
||||
"k8s.io/kubernetes/pkg/scheduler/apis/config/testing/defaults"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/names"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
func TestSchedulerOptions(t *testing.T) {
|
||||
@ -395,7 +396,7 @@ profiles:
|
||||
|
||||
defaultPodInitialBackoffSeconds := int64(1)
|
||||
defaultPodMaxBackoffSeconds := int64(10)
|
||||
defaultPercentageOfNodesToScore := int32(0)
|
||||
defaultPercentageOfNodesToScore := pointer.Int32(0)
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
|
9
pkg/generated/openapi/zz_generated.openapi.go
generated
9
pkg/generated/openapi/zz_generated.openapi.go
generated
@ -51793,7 +51793,7 @@ func schema_k8sio_kube_scheduler_config_v1_KubeSchedulerConfiguration(ref common
|
||||
},
|
||||
"percentageOfNodesToScore": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "PercentageOfNodesToScore is the percentage of all nodes that once found feasible for running a pod, the scheduler stops its search for more feasible nodes in the cluster. This helps improve scheduler's performance. Scheduler always tries to find at least \"minFeasibleNodesToFind\" feasible nodes no matter what the value of this flag is. Example: if the cluster size is 500 nodes and the value of this flag is 30, then scheduler stops finding further feasible nodes once it finds 150 feasible ones. When the value is 0, default percentage (5%--50% based on the size of the cluster) of the nodes will be scored.",
|
||||
Description: "PercentageOfNodesToScore is the percentage of all nodes that once found feasible for running a pod, the scheduler stops its search for more feasible nodes in the cluster. This helps improve scheduler's performance. Scheduler always tries to find at least \"minFeasibleNodesToFind\" feasible nodes no matter what the value of this flag is. Example: if the cluster size is 500 nodes and the value of this flag is 30, then scheduler stops finding further feasible nodes once it finds 150 feasible ones. When the value is 0, default percentage (5%--50% based on the size of the cluster) of the nodes will be scored. It is overridden by profile level PercentageofNodesToScore.",
|
||||
Type: []string{"integer"},
|
||||
Format: "int32",
|
||||
},
|
||||
@ -51876,6 +51876,13 @@ func schema_k8sio_kube_scheduler_config_v1_KubeSchedulerProfile(ref common.Refer
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"percentageOfNodesToScore": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "PercentageOfNodesToScore is the percentage of all nodes that once found feasible for running a pod, the scheduler stops its search for more feasible nodes in the cluster. This helps improve scheduler's performance. Scheduler always tries to find at least \"minFeasibleNodesToFind\" feasible nodes no matter what the value of this flag is. Example: if the cluster size is 500 nodes and the value of this flag is 30, then scheduler stops finding further feasible nodes once it finds 150 feasible ones. When the value is 0, default percentage (5%--50% based on the size of the cluster) of the nodes will be scored. It will override global PercentageOfNodesToScore. If it is empty, global PercentageOfNodesToScore will be used.",
|
||||
Type: []string{"integer"},
|
||||
Format: "int32",
|
||||
},
|
||||
},
|
||||
"plugins": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Plugins specify the set of plugins that should be enabled or disabled. Enabled plugins are the ones that should be enabled in addition to the default plugins. Disabled plugins are any of the default plugins that should be disabled. When no enabled or disabled plugin is specified for an extension point, default plugins for that extension point will be used if there is any. If a QueueSort plugin is specified, the same QueueSort Plugin and PluginConfig must be specified for all profiles.",
|
||||
|
@ -48,6 +48,7 @@ func TestCodecsDecodePluginConfig(t *testing.T) {
|
||||
data: []byte(`
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta2
|
||||
kind: KubeSchedulerConfiguration
|
||||
percentageOfNodesToScore: 0
|
||||
profiles:
|
||||
- pluginConfig:
|
||||
- name: DefaultPreemption
|
||||
@ -94,8 +95,9 @@ profiles:
|
||||
`),
|
||||
wantProfiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "default-scheduler",
|
||||
Plugins: defaults.PluginsV1beta2,
|
||||
SchedulerName: "default-scheduler",
|
||||
PercentageOfNodesToScore: nil,
|
||||
Plugins: defaults.PluginsV1beta2,
|
||||
PluginConfig: []config.PluginConfig{
|
||||
{
|
||||
Name: "DefaultPreemption",
|
||||
@ -169,6 +171,22 @@ profiles:
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "v1beta2 with non-default global percentageOfNodesToScore",
|
||||
data: []byte(`
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta2
|
||||
kind: KubeSchedulerConfiguration
|
||||
percentageOfNodesToScore: 10
|
||||
`),
|
||||
wantProfiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "default-scheduler",
|
||||
PercentageOfNodesToScore: nil,
|
||||
Plugins: defaults.PluginsV1beta2,
|
||||
PluginConfig: defaults.PluginConfigsV1beta2,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "v1beta2 plugins can include version and kind",
|
||||
data: []byte(`
|
||||
@ -510,6 +528,22 @@ profiles:
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "v1beta3 with non-default global percentageOfNodesToScore",
|
||||
data: []byte(`
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta3
|
||||
kind: KubeSchedulerConfiguration
|
||||
percentageOfNodesToScore: 10
|
||||
`),
|
||||
wantProfiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "default-scheduler",
|
||||
PercentageOfNodesToScore: nil,
|
||||
Plugins: defaults.PluginsV1beta3,
|
||||
PluginConfig: defaults.PluginConfigsV1beta3,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "v1beta3 plugins can include version and kind",
|
||||
data: []byte(`
|
||||
@ -776,8 +810,9 @@ profiles:
|
||||
`),
|
||||
wantProfiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "default-scheduler",
|
||||
Plugins: defaults.PluginsV1,
|
||||
SchedulerName: "default-scheduler",
|
||||
PercentageOfNodesToScore: nil,
|
||||
Plugins: defaults.PluginsV1,
|
||||
PluginConfig: []config.PluginConfig{
|
||||
{
|
||||
Name: "DefaultPreemption",
|
||||
@ -851,6 +886,40 @@ profiles:
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "v1 with non-default global percentageOfNodesToScore",
|
||||
data: []byte(`
|
||||
apiVersion: kubescheduler.config.k8s.io/v1
|
||||
kind: KubeSchedulerConfiguration
|
||||
percentageOfNodesToScore: 10
|
||||
`),
|
||||
wantProfiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "default-scheduler",
|
||||
PercentageOfNodesToScore: nil,
|
||||
Plugins: defaults.PluginsV1,
|
||||
PluginConfig: defaults.PluginConfigsV1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "v1 with non-default global and profile percentageOfNodesToScore",
|
||||
data: []byte(`
|
||||
apiVersion: kubescheduler.config.k8s.io/v1
|
||||
kind: KubeSchedulerConfiguration
|
||||
percentageOfNodesToScore: 10
|
||||
profiles:
|
||||
- percentageOfNodesToScore: 20
|
||||
`),
|
||||
wantProfiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "default-scheduler",
|
||||
PercentageOfNodesToScore: pointer.Int32(20),
|
||||
Plugins: defaults.PluginsV1,
|
||||
PluginConfig: defaults.PluginConfigsV1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "v1 plugins can include version and kind",
|
||||
data: []byte(`
|
||||
@ -1284,7 +1353,6 @@ leaderElection:
|
||||
retryPeriod: 0s
|
||||
metricsBindAddress: ""
|
||||
parallelism: 8
|
||||
percentageOfNodesToScore: 0
|
||||
podInitialBackoffSeconds: 0
|
||||
podMaxBackoffSeconds: 0
|
||||
profiles:
|
||||
@ -1503,7 +1571,6 @@ leaderElection:
|
||||
resourceNamespace: ""
|
||||
retryPeriod: 0s
|
||||
parallelism: 8
|
||||
percentageOfNodesToScore: 0
|
||||
podInitialBackoffSeconds: 0
|
||||
podMaxBackoffSeconds: 0
|
||||
profiles:
|
||||
@ -1722,7 +1789,6 @@ leaderElection:
|
||||
resourceNamespace: ""
|
||||
retryPeriod: 0s
|
||||
parallelism: 8
|
||||
percentageOfNodesToScore: 0
|
||||
podInitialBackoffSeconds: 0
|
||||
podMaxBackoffSeconds: 0
|
||||
profiles:
|
||||
|
@ -74,8 +74,8 @@ type KubeSchedulerConfiguration struct {
|
||||
// Example: if the cluster size is 500 nodes and the value of this flag is 30,
|
||||
// then scheduler stops finding further feasible nodes once it finds 150 feasible ones.
|
||||
// When the value is 0, default percentage (5%--50% based on the size of the cluster) of the
|
||||
// nodes will be scored.
|
||||
PercentageOfNodesToScore int32
|
||||
// nodes will be scored. It is overridden by profile level PercentageOfNodesToScore.
|
||||
PercentageOfNodesToScore *int32
|
||||
|
||||
// PodInitialBackoffSeconds is the initial backoff for unschedulable pods.
|
||||
// If specified, it must be greater than 0. If this value is null, the default value (1s)
|
||||
@ -105,6 +105,17 @@ type KubeSchedulerProfile struct {
|
||||
// is scheduled with this profile.
|
||||
SchedulerName string
|
||||
|
||||
// PercentageOfNodesToScore is the percentage of all nodes that once found feasible
|
||||
// for running a pod, the scheduler stops its search for more feasible nodes in
|
||||
// the cluster. This helps improve scheduler's performance. Scheduler always tries to find
|
||||
// at least "minFeasibleNodesToFind" feasible nodes no matter what the value of this flag is.
|
||||
// Example: if the cluster size is 500 nodes and the value of this flag is 30,
|
||||
// then scheduler stops finding further feasible nodes once it finds 150 feasible ones.
|
||||
// When the value is 0, default percentage (5%--50% based on the size of the cluster) of the
|
||||
// nodes will be scored. It will override global PercentageOfNodesToScore. If it is empty,
|
||||
// global PercentageOfNodesToScore will be used.
|
||||
PercentageOfNodesToScore *int32
|
||||
|
||||
// Plugins specify the set of plugins that should be enabled or disabled.
|
||||
// Enabled plugins are the ones that should be enabled in addition to the
|
||||
// default plugins. Disabled plugins are any of the default plugins that
|
||||
|
@ -121,8 +121,7 @@ func SetDefaults_KubeSchedulerConfiguration(obj *configv1.KubeSchedulerConfigura
|
||||
}
|
||||
|
||||
if obj.PercentageOfNodesToScore == nil {
|
||||
percentageOfNodesToScore := int32(config.DefaultPercentageOfNodesToScore)
|
||||
obj.PercentageOfNodesToScore = &percentageOfNodesToScore
|
||||
obj.PercentageOfNodesToScore = pointer.Int32(config.DefaultPercentageOfNodesToScore)
|
||||
}
|
||||
|
||||
if len(obj.LeaderElection.ResourceLock) == 0 {
|
||||
|
@ -32,6 +32,7 @@ import (
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
configv1 "k8s.io/kube-scheduler/config/v1"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/names"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
@ -144,7 +145,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
||||
Profiles: []configv1.KubeSchedulerProfile{
|
||||
@ -181,7 +182,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
||||
Profiles: []configv1.KubeSchedulerProfile{
|
||||
@ -237,7 +238,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
||||
Profiles: []configv1.KubeSchedulerProfile{
|
||||
@ -388,7 +389,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
||||
Profiles: []configv1.KubeSchedulerProfile{
|
||||
@ -425,7 +426,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
||||
Profiles: []configv1.KubeSchedulerProfile{
|
||||
@ -437,6 +438,128 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "set non default global percentageOfNodesToScore",
|
||||
config: &configv1.KubeSchedulerConfiguration{
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
||||
},
|
||||
expected: &configv1.KubeSchedulerConfiguration{
|
||||
Parallelism: pointer.Int32Ptr(16),
|
||||
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
||||
EnableProfiling: &enable,
|
||||
EnableContentionProfiling: &enable,
|
||||
},
|
||||
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
||||
LeaderElect: pointer.BoolPtr(true),
|
||||
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
||||
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
||||
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
||||
ResourceLock: "leases",
|
||||
ResourceNamespace: "kube-system",
|
||||
ResourceName: "kube-scheduler",
|
||||
},
|
||||
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
||||
QPS: 50,
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
||||
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
||||
Profiles: []configv1.KubeSchedulerProfile{
|
||||
{
|
||||
Plugins: getDefaultPlugins(),
|
||||
PluginConfig: pluginConfigs,
|
||||
SchedulerName: pointer.StringPtr("default-scheduler"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "set non default profile percentageOfNodesToScore",
|
||||
config: &configv1.KubeSchedulerConfiguration{
|
||||
Profiles: []configv1.KubeSchedulerProfile{
|
||||
{
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &configv1.KubeSchedulerConfiguration{
|
||||
Parallelism: pointer.Int32Ptr(16),
|
||||
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
||||
EnableProfiling: &enable,
|
||||
EnableContentionProfiling: &enable,
|
||||
},
|
||||
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
||||
LeaderElect: pointer.BoolPtr(true),
|
||||
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
||||
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
||||
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
||||
ResourceLock: "leases",
|
||||
ResourceNamespace: "kube-system",
|
||||
ResourceName: "kube-scheduler",
|
||||
},
|
||||
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
||||
QPS: 50,
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
||||
Profiles: []configv1.KubeSchedulerProfile{
|
||||
{
|
||||
Plugins: getDefaultPlugins(),
|
||||
PluginConfig: pluginConfigs,
|
||||
SchedulerName: pointer.StringPtr("default-scheduler"),
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "set non default global and profile percentageOfNodesToScore",
|
||||
config: &configv1.KubeSchedulerConfiguration{
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(10),
|
||||
Profiles: []configv1.KubeSchedulerProfile{
|
||||
{
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &configv1.KubeSchedulerConfiguration{
|
||||
Parallelism: pointer.Int32Ptr(16),
|
||||
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
||||
EnableProfiling: &enable,
|
||||
EnableContentionProfiling: &enable,
|
||||
},
|
||||
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
||||
LeaderElect: pointer.BoolPtr(true),
|
||||
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
||||
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
||||
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
||||
ResourceLock: "leases",
|
||||
ResourceNamespace: "kube-system",
|
||||
ResourceName: "kube-scheduler",
|
||||
},
|
||||
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
||||
QPS: 50,
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(10),
|
||||
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
||||
Profiles: []configv1.KubeSchedulerProfile{
|
||||
{
|
||||
Plugins: getDefaultPlugins(),
|
||||
PluginConfig: pluginConfigs,
|
||||
SchedulerName: pointer.StringPtr("default-scheduler"),
|
||||
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
@ -408,9 +408,7 @@ func autoConvert_v1_KubeSchedulerConfiguration_To_config_KubeSchedulerConfigurat
|
||||
if err := v1alpha1.Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := metav1.Convert_Pointer_int32_To_int32(&in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore))
|
||||
if err := metav1.Convert_Pointer_int64_To_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -447,9 +445,7 @@ func autoConvert_config_KubeSchedulerConfiguration_To_v1_KubeSchedulerConfigurat
|
||||
if err := v1alpha1.Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := metav1.Convert_int32_To_Pointer_int32(&in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore))
|
||||
if err := metav1.Convert_int64_To_Pointer_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -475,6 +471,7 @@ func autoConvert_v1_KubeSchedulerProfile_To_config_KubeSchedulerProfile(in *v1.K
|
||||
if err := metav1.Convert_Pointer_string_To_string(&in.SchedulerName, &out.SchedulerName, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore))
|
||||
if in.Plugins != nil {
|
||||
in, out := &in.Plugins, &out.Plugins
|
||||
*out = new(config.Plugins)
|
||||
@ -507,6 +504,7 @@ func autoConvert_config_KubeSchedulerProfile_To_v1_KubeSchedulerProfile(in *conf
|
||||
if err := metav1.Convert_string_To_Pointer_string(&in.SchedulerName, &out.SchedulerName, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore))
|
||||
if in.Plugins != nil {
|
||||
in, out := &in.Plugins, &out.Plugins
|
||||
*out = new(v1.Plugins)
|
||||
|
@ -105,3 +105,9 @@ func convertToExternalPluginConfigArgs(out *v1beta2.KubeSchedulerConfiguration)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_config_KubeSchedulerProfile_To_v1beta2_KubeSchedulerProfile uses auto coversion by
|
||||
// ignoring per profile PercentageOfNodesToScore.
|
||||
func Convert_config_KubeSchedulerProfile_To_v1beta2_KubeSchedulerProfile(in *config.KubeSchedulerProfile, out *v1beta2.KubeSchedulerProfile, s conversion.Scope) error {
|
||||
return autoConvert_config_KubeSchedulerProfile_To_v1beta2_KubeSchedulerProfile(in, out, s)
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import (
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kube-scheduler/config/v1beta2"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/names"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
@ -144,7 +145,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64(10),
|
||||
Profiles: []v1beta2.KubeSchedulerProfile{
|
||||
@ -181,7 +182,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64(10),
|
||||
Profiles: []v1beta2.KubeSchedulerProfile{
|
||||
@ -237,7 +238,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64(10),
|
||||
Profiles: []v1beta2.KubeSchedulerProfile{
|
||||
@ -430,7 +431,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64(10),
|
||||
Profiles: []v1beta2.KubeSchedulerProfile{
|
||||
|
@ -95,11 +95,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*config.KubeSchedulerProfile)(nil), (*v1beta2.KubeSchedulerProfile)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_KubeSchedulerProfile_To_v1beta2_KubeSchedulerProfile(a.(*config.KubeSchedulerProfile), b.(*v1beta2.KubeSchedulerProfile), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1beta2.NodeAffinityArgs)(nil), (*config.NodeAffinityArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta2_NodeAffinityArgs_To_config_NodeAffinityArgs(a.(*v1beta2.NodeAffinityArgs), b.(*config.NodeAffinityArgs), scope)
|
||||
}); err != nil {
|
||||
@ -235,6 +230,11 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*config.KubeSchedulerProfile)(nil), (*v1beta2.KubeSchedulerProfile)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_KubeSchedulerProfile_To_v1beta2_KubeSchedulerProfile(a.(*config.KubeSchedulerProfile), b.(*v1beta2.KubeSchedulerProfile), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*v1beta2.KubeSchedulerConfiguration)(nil), (*config.KubeSchedulerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta2_KubeSchedulerConfiguration_To_config_KubeSchedulerConfiguration(a.(*v1beta2.KubeSchedulerConfiguration), b.(*config.KubeSchedulerConfiguration), scope)
|
||||
}); err != nil {
|
||||
@ -414,9 +414,7 @@ func autoConvert_v1beta2_KubeSchedulerConfiguration_To_config_KubeSchedulerConfi
|
||||
if err := v1alpha1.Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := v1.Convert_Pointer_int32_To_int32(&in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore))
|
||||
if err := v1.Convert_Pointer_int64_To_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -457,9 +455,7 @@ func autoConvert_config_KubeSchedulerConfiguration_To_v1beta2_KubeSchedulerConfi
|
||||
if err := v1alpha1.Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := v1.Convert_int32_To_Pointer_int32(&in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore))
|
||||
if err := v1.Convert_int64_To_Pointer_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -517,6 +513,7 @@ func autoConvert_config_KubeSchedulerProfile_To_v1beta2_KubeSchedulerProfile(in
|
||||
if err := v1.Convert_string_To_Pointer_string(&in.SchedulerName, &out.SchedulerName, s); err != nil {
|
||||
return err
|
||||
}
|
||||
// WARNING: in.PercentageOfNodesToScore requires manual conversion: does not exist in peer-type
|
||||
if in.Plugins != nil {
|
||||
in, out := &in.Plugins, &out.Plugins
|
||||
*out = new(v1beta2.Plugins)
|
||||
@ -540,11 +537,6 @@ func autoConvert_config_KubeSchedulerProfile_To_v1beta2_KubeSchedulerProfile(in
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_config_KubeSchedulerProfile_To_v1beta2_KubeSchedulerProfile is an autogenerated conversion function.
|
||||
func Convert_config_KubeSchedulerProfile_To_v1beta2_KubeSchedulerProfile(in *config.KubeSchedulerProfile, out *v1beta2.KubeSchedulerProfile, s conversion.Scope) error {
|
||||
return autoConvert_config_KubeSchedulerProfile_To_v1beta2_KubeSchedulerProfile(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta2_NodeAffinityArgs_To_config_NodeAffinityArgs(in *v1beta2.NodeAffinityArgs, out *config.NodeAffinityArgs, s conversion.Scope) error {
|
||||
out.AddedAffinity = (*corev1.NodeAffinity)(unsafe.Pointer(in.AddedAffinity))
|
||||
return nil
|
||||
|
@ -105,3 +105,9 @@ func convertToExternalPluginConfigArgs(out *v1beta3.KubeSchedulerConfiguration)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_config_KubeSchedulerProfile_To_v1beta3_KubeSchedulerProfile called auto coversion by
|
||||
// ignoring per profile PercentageOfNodesToScore.
|
||||
func Convert_config_KubeSchedulerProfile_To_v1beta3_KubeSchedulerProfile(in *config.KubeSchedulerProfile, out *v1beta3.KubeSchedulerProfile, s conversion.Scope) error {
|
||||
return autoConvert_config_KubeSchedulerProfile_To_v1beta3_KubeSchedulerProfile(in, out, s)
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import (
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kube-scheduler/config/v1beta3"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/names"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
@ -144,7 +145,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64(10),
|
||||
Profiles: []v1beta3.KubeSchedulerProfile{
|
||||
@ -181,7 +182,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64(10),
|
||||
Profiles: []v1beta3.KubeSchedulerProfile{
|
||||
@ -237,7 +238,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64(10),
|
||||
Profiles: []v1beta3.KubeSchedulerProfile{
|
||||
@ -388,7 +389,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64(10),
|
||||
Profiles: []v1beta3.KubeSchedulerProfile{
|
||||
@ -425,7 +426,7 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: pointer.Int32(0),
|
||||
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
||||
PodInitialBackoffSeconds: pointer.Int64(1),
|
||||
PodMaxBackoffSeconds: pointer.Int64(10),
|
||||
Profiles: []v1beta3.KubeSchedulerProfile{
|
||||
|
@ -95,11 +95,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*config.KubeSchedulerProfile)(nil), (*v1beta3.KubeSchedulerProfile)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_KubeSchedulerProfile_To_v1beta3_KubeSchedulerProfile(a.(*config.KubeSchedulerProfile), b.(*v1beta3.KubeSchedulerProfile), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1beta3.NodeAffinityArgs)(nil), (*config.NodeAffinityArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta3_NodeAffinityArgs_To_config_NodeAffinityArgs(a.(*v1beta3.NodeAffinityArgs), b.(*config.NodeAffinityArgs), scope)
|
||||
}); err != nil {
|
||||
@ -235,6 +230,11 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*config.KubeSchedulerProfile)(nil), (*v1beta3.KubeSchedulerProfile)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_KubeSchedulerProfile_To_v1beta3_KubeSchedulerProfile(a.(*config.KubeSchedulerProfile), b.(*v1beta3.KubeSchedulerProfile), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*v1beta3.KubeSchedulerConfiguration)(nil), (*config.KubeSchedulerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta3_KubeSchedulerConfiguration_To_config_KubeSchedulerConfiguration(a.(*v1beta3.KubeSchedulerConfiguration), b.(*config.KubeSchedulerConfiguration), scope)
|
||||
}); err != nil {
|
||||
@ -408,9 +408,7 @@ func autoConvert_v1beta3_KubeSchedulerConfiguration_To_config_KubeSchedulerConfi
|
||||
if err := v1alpha1.Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := v1.Convert_Pointer_int32_To_int32(&in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore))
|
||||
if err := v1.Convert_Pointer_int64_To_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -447,9 +445,7 @@ func autoConvert_config_KubeSchedulerConfiguration_To_v1beta3_KubeSchedulerConfi
|
||||
if err := v1alpha1.Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := v1.Convert_int32_To_Pointer_int32(&in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore))
|
||||
if err := v1.Convert_int64_To_Pointer_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -507,6 +503,7 @@ func autoConvert_config_KubeSchedulerProfile_To_v1beta3_KubeSchedulerProfile(in
|
||||
if err := v1.Convert_string_To_Pointer_string(&in.SchedulerName, &out.SchedulerName, s); err != nil {
|
||||
return err
|
||||
}
|
||||
// WARNING: in.PercentageOfNodesToScore requires manual conversion: does not exist in peer-type
|
||||
if in.Plugins != nil {
|
||||
in, out := &in.Plugins, &out.Plugins
|
||||
*out = new(v1beta3.Plugins)
|
||||
@ -530,11 +527,6 @@ func autoConvert_config_KubeSchedulerProfile_To_v1beta3_KubeSchedulerProfile(in
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_config_KubeSchedulerProfile_To_v1beta3_KubeSchedulerProfile is an autogenerated conversion function.
|
||||
func Convert_config_KubeSchedulerProfile_To_v1beta3_KubeSchedulerProfile(in *config.KubeSchedulerProfile, out *v1beta3.KubeSchedulerProfile, s conversion.Scope) error {
|
||||
return autoConvert_config_KubeSchedulerProfile_To_v1beta3_KubeSchedulerProfile(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta3_NodeAffinityArgs_To_config_NodeAffinityArgs(in *v1beta3.NodeAffinityArgs, out *config.NodeAffinityArgs, s conversion.Scope) error {
|
||||
out.AddedAffinity = (*corev1.NodeAffinity)(unsafe.Pointer(in.AddedAffinity))
|
||||
return nil
|
||||
|
@ -88,10 +88,9 @@ func ValidateKubeSchedulerConfiguration(cc *config.KubeSchedulerConfiguration) u
|
||||
}
|
||||
}
|
||||
}
|
||||
if cc.PercentageOfNodesToScore < 0 || cc.PercentageOfNodesToScore > 100 {
|
||||
errs = append(errs, field.Invalid(field.NewPath("percentageOfNodesToScore"),
|
||||
cc.PercentageOfNodesToScore, "not in valid range [0-100]"))
|
||||
}
|
||||
|
||||
errs = append(errs, validatePercentageOfNodesToScore(field.NewPath("percentageOfNodesToScore"), cc.PercentageOfNodesToScore))
|
||||
|
||||
if cc.PodInitialBackoffSeconds <= 0 {
|
||||
errs = append(errs, field.Invalid(field.NewPath("podInitialBackoffSeconds"),
|
||||
cc.PodInitialBackoffSeconds, "must be greater than 0"))
|
||||
@ -117,6 +116,15 @@ func splitHostIntPort(s string) (string, int, error) {
|
||||
return host, portInt, err
|
||||
}
|
||||
|
||||
func validatePercentageOfNodesToScore(path *field.Path, percentageOfNodesToScore *int32) error {
|
||||
if percentageOfNodesToScore != nil {
|
||||
if *percentageOfNodesToScore < 0 || *percentageOfNodesToScore > 100 {
|
||||
return field.Invalid(path, *percentageOfNodesToScore, "not in valid range [0-100]")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type invalidPlugins struct {
|
||||
schemeGroupVersion string
|
||||
plugins []string
|
||||
@ -171,6 +179,7 @@ func validateKubeSchedulerProfile(path *field.Path, apiVersion string, profile *
|
||||
if len(profile.SchedulerName) == 0 {
|
||||
errs = append(errs, field.Required(path.Child("schedulerName"), ""))
|
||||
}
|
||||
errs = append(errs, validatePercentageOfNodesToScore(path.Child("percentageOfNodesToScore"), profile.PercentageOfNodesToScore))
|
||||
errs = append(errs, validatePluginConfig(path, apiVersion, profile)...)
|
||||
return errs
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
configv1 "k8s.io/kubernetes/pkg/scheduler/apis/config/v1"
|
||||
"k8s.io/kubernetes/pkg/scheduler/apis/config/v1beta2"
|
||||
"k8s.io/kubernetes/pkg/scheduler/apis/config/v1beta3"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
|
||||
@ -54,7 +55,7 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
|
||||
},
|
||||
PodInitialBackoffSeconds: podInitialBackoffSeconds,
|
||||
PodMaxBackoffSeconds: podMaxBackoffSeconds,
|
||||
PercentageOfNodesToScore: 35,
|
||||
PercentageOfNodesToScore: pointer.Int32(35),
|
||||
Profiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "me",
|
||||
@ -113,7 +114,10 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
|
||||
healthzBindAddrInvalid.HealthzBindAddress = "0.0.0.0:9090"
|
||||
|
||||
percentageOfNodesToScore101 := validConfig.DeepCopy()
|
||||
percentageOfNodesToScore101.PercentageOfNodesToScore = int32(101)
|
||||
percentageOfNodesToScore101.PercentageOfNodesToScore = pointer.Int32(101)
|
||||
|
||||
percentageOfNodesToScoreNegative := validConfig.DeepCopy()
|
||||
percentageOfNodesToScoreNegative.PercentageOfNodesToScore = pointer.Int32(-1)
|
||||
|
||||
schedulerNameNotSet := validConfig.DeepCopy()
|
||||
schedulerNameNotSet.Profiles[1].SchedulerName = ""
|
||||
@ -121,6 +125,12 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
|
||||
repeatedSchedulerName := validConfig.DeepCopy()
|
||||
repeatedSchedulerName.Profiles[0].SchedulerName = "other"
|
||||
|
||||
profilePercentageOfNodesToScore101 := validConfig.DeepCopy()
|
||||
profilePercentageOfNodesToScore101.Profiles[1].PercentageOfNodesToScore = pointer.Int32(101)
|
||||
|
||||
profilePercentageOfNodesToScoreNegative := validConfig.DeepCopy()
|
||||
profilePercentageOfNodesToScoreNegative.Profiles[1].PercentageOfNodesToScore = pointer.Int32(-1)
|
||||
|
||||
differentQueueSort := validConfig.DeepCopy()
|
||||
differentQueueSort.Profiles[1].Plugins.QueueSort.Enabled[0].Name = "AnotherSort"
|
||||
|
||||
@ -237,11 +247,16 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
|
||||
config: healthzBindAddrInvalid,
|
||||
errorString: "must be empty or with an explicit 0 port",
|
||||
},
|
||||
"bad-percentage-of-nodes-to-score": {
|
||||
"greater-than-100-percentage-of-nodes-to-score": {
|
||||
expectedToFail: true,
|
||||
config: percentageOfNodesToScore101,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"negative-percentage-of-nodes-to-score": {
|
||||
expectedToFail: true,
|
||||
config: percentageOfNodesToScoreNegative,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"scheduler-name-not-set": {
|
||||
expectedToFail: true,
|
||||
config: schedulerNameNotSet,
|
||||
@ -252,6 +267,16 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
|
||||
config: repeatedSchedulerName,
|
||||
errorString: "Duplicate value",
|
||||
},
|
||||
"greater-than-100-profile-percentage-of-nodes-to-score": {
|
||||
expectedToFail: true,
|
||||
config: profilePercentageOfNodesToScore101,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"negative-100-profile-percentage-of-nodes-to-score": {
|
||||
expectedToFail: true,
|
||||
config: profilePercentageOfNodesToScoreNegative,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"different-queue-sort": {
|
||||
expectedToFail: true,
|
||||
config: differentQueueSort,
|
||||
@ -345,7 +370,7 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
|
||||
},
|
||||
PodInitialBackoffSeconds: podInitialBackoffSeconds,
|
||||
PodMaxBackoffSeconds: podMaxBackoffSeconds,
|
||||
PercentageOfNodesToScore: 35,
|
||||
PercentageOfNodesToScore: pointer.Int32(35),
|
||||
Profiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "me",
|
||||
@ -404,7 +429,10 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
|
||||
healthzBindAddrInvalid.HealthzBindAddress = "0.0.0.0:9090"
|
||||
|
||||
percentageOfNodesToScore101 := validConfig.DeepCopy()
|
||||
percentageOfNodesToScore101.PercentageOfNodesToScore = int32(101)
|
||||
percentageOfNodesToScore101.PercentageOfNodesToScore = pointer.Int32(101)
|
||||
|
||||
percentageOfNodesToScoreNegative := validConfig.DeepCopy()
|
||||
percentageOfNodesToScoreNegative.Profiles[1].PercentageOfNodesToScore = pointer.Int32(-1)
|
||||
|
||||
schedulerNameNotSet := validConfig.DeepCopy()
|
||||
schedulerNameNotSet.Profiles[1].SchedulerName = ""
|
||||
@ -412,6 +440,12 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
|
||||
repeatedSchedulerName := validConfig.DeepCopy()
|
||||
repeatedSchedulerName.Profiles[0].SchedulerName = "other"
|
||||
|
||||
profilePercentageOfNodesToScore101 := validConfig.DeepCopy()
|
||||
profilePercentageOfNodesToScore101.Profiles[1].PercentageOfNodesToScore = pointer.Int32(101)
|
||||
|
||||
profilePercentageOfNodesToScoreNegative := validConfig.DeepCopy()
|
||||
profilePercentageOfNodesToScoreNegative.Profiles[1].PercentageOfNodesToScore = pointer.Int32(-1)
|
||||
|
||||
differentQueueSort := validConfig.DeepCopy()
|
||||
differentQueueSort.Profiles[1].Plugins.QueueSort.Enabled[0].Name = "AnotherSort"
|
||||
|
||||
@ -533,6 +567,11 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
|
||||
config: percentageOfNodesToScore101,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"negative-percentage-of-nodes-to-score": {
|
||||
expectedToFail: true,
|
||||
config: percentageOfNodesToScoreNegative,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"scheduler-name-not-set": {
|
||||
expectedToFail: true,
|
||||
config: schedulerNameNotSet,
|
||||
@ -543,6 +582,16 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
|
||||
config: repeatedSchedulerName,
|
||||
errorString: "Duplicate value",
|
||||
},
|
||||
"greater-than-100-profile-percentage-of-nodes-to-score": {
|
||||
expectedToFail: true,
|
||||
config: profilePercentageOfNodesToScore101,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"negative-100-profile-percentage-of-nodes-to-score": {
|
||||
expectedToFail: true,
|
||||
config: profilePercentageOfNodesToScoreNegative,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"different-queue-sort": {
|
||||
expectedToFail: true,
|
||||
config: differentQueueSort,
|
||||
@ -636,10 +685,10 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
|
||||
},
|
||||
PodInitialBackoffSeconds: podInitialBackoffSeconds,
|
||||
PodMaxBackoffSeconds: podMaxBackoffSeconds,
|
||||
PercentageOfNodesToScore: 35,
|
||||
Profiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "me",
|
||||
SchedulerName: "me",
|
||||
PercentageOfNodesToScore: pointer.Int32(35),
|
||||
Plugins: &config.Plugins{
|
||||
QueueSort: config.PluginSet{
|
||||
Enabled: []config.Plugin{{Name: "CustomSort"}},
|
||||
@ -656,7 +705,8 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
SchedulerName: "other",
|
||||
SchedulerName: "other",
|
||||
PercentageOfNodesToScore: pointer.Int32(35),
|
||||
Plugins: &config.Plugins{
|
||||
QueueSort: config.PluginSet{
|
||||
Enabled: []config.Plugin{{Name: "CustomSort"}},
|
||||
@ -695,7 +745,10 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
|
||||
healthzBindAddrInvalid.HealthzBindAddress = "0.0.0.0:9090"
|
||||
|
||||
percentageOfNodesToScore101 := validConfig.DeepCopy()
|
||||
percentageOfNodesToScore101.PercentageOfNodesToScore = int32(101)
|
||||
percentageOfNodesToScore101.PercentageOfNodesToScore = pointer.Int32(101)
|
||||
|
||||
percentageOfNodesToScoreNegative := validConfig.DeepCopy()
|
||||
percentageOfNodesToScoreNegative.PercentageOfNodesToScore = pointer.Int32(-1)
|
||||
|
||||
schedulerNameNotSet := validConfig.DeepCopy()
|
||||
schedulerNameNotSet.Profiles[1].SchedulerName = ""
|
||||
@ -703,6 +756,12 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
|
||||
repeatedSchedulerName := validConfig.DeepCopy()
|
||||
repeatedSchedulerName.Profiles[0].SchedulerName = "other"
|
||||
|
||||
profilePercentageOfNodesToScore101 := validConfig.DeepCopy()
|
||||
profilePercentageOfNodesToScore101.Profiles[1].PercentageOfNodesToScore = pointer.Int32(101)
|
||||
|
||||
profilePercentageOfNodesToScoreNegative := validConfig.DeepCopy()
|
||||
profilePercentageOfNodesToScoreNegative.Profiles[1].PercentageOfNodesToScore = pointer.Int32(-1)
|
||||
|
||||
differentQueueSort := validConfig.DeepCopy()
|
||||
differentQueueSort.Profiles[1].Plugins.QueueSort.Enabled[0].Name = "AnotherSort"
|
||||
|
||||
@ -827,6 +886,11 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
|
||||
config: percentageOfNodesToScore101,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"negative-percentage-of-nodes-to-score": {
|
||||
expectedToFail: true,
|
||||
config: percentageOfNodesToScoreNegative,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"scheduler-name-not-set": {
|
||||
expectedToFail: true,
|
||||
config: schedulerNameNotSet,
|
||||
@ -837,6 +901,16 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
|
||||
config: repeatedSchedulerName,
|
||||
errorString: "Duplicate value",
|
||||
},
|
||||
"greater-than-100-profile-percentage-of-nodes-to-score": {
|
||||
expectedToFail: true,
|
||||
config: profilePercentageOfNodesToScore101,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"negative-profile-percentage-of-nodes-to-score": {
|
||||
expectedToFail: true,
|
||||
config: profilePercentageOfNodesToScoreNegative,
|
||||
errorString: "not in valid range [0-100]",
|
||||
},
|
||||
"different-queue-sort": {
|
||||
expectedToFail: true,
|
||||
config: differentQueueSort,
|
||||
|
10
pkg/scheduler/apis/config/zz_generated.deepcopy.go
generated
10
pkg/scheduler/apis/config/zz_generated.deepcopy.go
generated
@ -157,6 +157,11 @@ func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfigurati
|
||||
out.LeaderElection = in.LeaderElection
|
||||
out.ClientConnection = in.ClientConnection
|
||||
out.DebuggingConfiguration = in.DebuggingConfiguration
|
||||
if in.PercentageOfNodesToScore != nil {
|
||||
in, out := &in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Profiles != nil {
|
||||
in, out := &in.Profiles, &out.Profiles
|
||||
*out = make([]KubeSchedulerProfile, len(*in))
|
||||
@ -195,6 +200,11 @@ func (in *KubeSchedulerConfiguration) DeepCopyObject() runtime.Object {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeSchedulerProfile) DeepCopyInto(out *KubeSchedulerProfile) {
|
||||
*out = *in
|
||||
if in.PercentageOfNodesToScore != nil {
|
||||
in, out := &in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Plugins != nil {
|
||||
in, out := &in.Plugins, &out.Plugins
|
||||
*out = new(Plugins)
|
||||
|
@ -574,8 +574,11 @@ type Framework interface {
|
||||
// ListPlugins returns a map of extension point name to list of configured Plugins.
|
||||
ListPlugins() *config.Plugins
|
||||
|
||||
// ProfileName returns the profile name associated to this framework.
|
||||
// ProfileName returns the profile name associated to a profile.
|
||||
ProfileName() string
|
||||
|
||||
// PercentageOfNodesToScore returns percentageOfNodesToScore associated to a profile.
|
||||
PercentageOfNodesToScore() *int32
|
||||
}
|
||||
|
||||
// Handle provides data and some tools that plugins can use. It is
|
||||
|
@ -92,8 +92,9 @@ type frameworkImpl struct {
|
||||
eventRecorder events.EventRecorder
|
||||
informerFactory informers.SharedInformerFactory
|
||||
|
||||
metricsRecorder *metricsRecorder
|
||||
profileName string
|
||||
metricsRecorder *metricsRecorder
|
||||
profileName string
|
||||
percentageOfNodesToScore *int32
|
||||
|
||||
extenders []framework.Extender
|
||||
framework.PodNominator
|
||||
@ -271,6 +272,7 @@ func NewFramework(r Registry, profile *config.KubeSchedulerProfile, stopCh <-cha
|
||||
}
|
||||
|
||||
f.profileName = profile.SchedulerName
|
||||
f.percentageOfNodesToScore = profile.PercentageOfNodesToScore
|
||||
if profile.Plugins == nil {
|
||||
return f, nil
|
||||
}
|
||||
@ -287,9 +289,10 @@ func NewFramework(r Registry, profile *config.KubeSchedulerProfile, stopCh <-cha
|
||||
pluginConfig[name] = profile.PluginConfig[i].Args
|
||||
}
|
||||
outputProfile := config.KubeSchedulerProfile{
|
||||
SchedulerName: f.profileName,
|
||||
Plugins: profile.Plugins,
|
||||
PluginConfig: make([]config.PluginConfig, 0, len(pg)),
|
||||
SchedulerName: f.profileName,
|
||||
PercentageOfNodesToScore: f.percentageOfNodesToScore,
|
||||
Plugins: profile.Plugins,
|
||||
PluginConfig: make([]config.PluginConfig, 0, len(pg)),
|
||||
}
|
||||
|
||||
pluginsMap := make(map[string]framework.Plugin)
|
||||
@ -1340,6 +1343,11 @@ func (f *frameworkImpl) ProfileName() string {
|
||||
return f.profileName
|
||||
}
|
||||
|
||||
// PercentageOfNodesToScore returns percentageOfNodesToScore associated to a profile.
|
||||
func (f *frameworkImpl) PercentageOfNodesToScore() *int32 {
|
||||
return f.percentageOfNodesToScore
|
||||
}
|
||||
|
||||
// Parallelizer returns a parallelizer holding parallelism for scheduler.
|
||||
func (f *frameworkImpl) Parallelizer() parallelize.Parallelizer {
|
||||
return f.parallelizer
|
||||
|
@ -37,6 +37,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||
internalqueue "k8s.io/kubernetes/pkg/scheduler/internal/queue"
|
||||
"k8s.io/kubernetes/pkg/scheduler/metrics"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -52,8 +53,9 @@ const (
|
||||
permitPlugin = "permit-plugin"
|
||||
bindPlugin = "bind-plugin"
|
||||
|
||||
testProfileName = "test-profile"
|
||||
nodeName = "testNode"
|
||||
testProfileName = "test-profile"
|
||||
testPercentageOfNodesToScore = 35
|
||||
nodeName = "testNode"
|
||||
|
||||
injectReason = "injected status"
|
||||
injectFilterReason = "injected filter status"
|
||||
@ -2287,8 +2289,9 @@ func TestRecordingMetrics(t *testing.T) {
|
||||
stopCh := make(chan struct{})
|
||||
recorder := newMetricsRecorder(100, time.Nanosecond, stopCh)
|
||||
profile := config.KubeSchedulerProfile{
|
||||
SchedulerName: testProfileName,
|
||||
Plugins: plugins,
|
||||
PercentageOfNodesToScore: pointer.Int32(testPercentageOfNodesToScore),
|
||||
SchedulerName: testProfileName,
|
||||
Plugins: plugins,
|
||||
}
|
||||
f, err := newFrameworkWithQueueSortAndBind(r, profile, stopCh, withMetricsRecorder(recorder))
|
||||
if err != nil {
|
||||
@ -2398,8 +2401,9 @@ func TestRunBindPlugins(t *testing.T) {
|
||||
stopCh := make(chan struct{})
|
||||
recorder := newMetricsRecorder(100, time.Nanosecond, stopCh)
|
||||
profile := config.KubeSchedulerProfile{
|
||||
SchedulerName: testProfileName,
|
||||
Plugins: plugins,
|
||||
SchedulerName: testProfileName,
|
||||
PercentageOfNodesToScore: pointer.Int32(testPercentageOfNodesToScore),
|
||||
Plugins: plugins,
|
||||
}
|
||||
fwk, err := newFrameworkWithQueueSortAndBind(r, profile, stopCh, withMetricsRecorder(recorder))
|
||||
if err != nil {
|
||||
|
@ -511,7 +511,7 @@ func (sched *Scheduler) findNodesThatPassFilters(
|
||||
diagnosis framework.Diagnosis,
|
||||
nodes []*framework.NodeInfo) ([]*v1.Node, error) {
|
||||
numAllNodes := len(nodes)
|
||||
numNodesToFind := sched.numFeasibleNodesToFind(int32(numAllNodes))
|
||||
numNodesToFind := sched.numFeasibleNodesToFind(fwk.PercentageOfNodesToScore(), int32(numAllNodes))
|
||||
|
||||
// Create feasible list with enough space to avoid growing it
|
||||
// and allow assigning.
|
||||
@ -576,21 +576,27 @@ func (sched *Scheduler) findNodesThatPassFilters(
|
||||
|
||||
// numFeasibleNodesToFind returns the number of feasible nodes that once found, the scheduler stops
|
||||
// its search for more feasible nodes.
|
||||
func (sched *Scheduler) numFeasibleNodesToFind(numAllNodes int32) (numNodes int32) {
|
||||
if numAllNodes < minFeasibleNodesToFind || sched.percentageOfNodesToScore >= 100 {
|
||||
func (sched *Scheduler) numFeasibleNodesToFind(percentageOfNodesToScore *int32, numAllNodes int32) (numNodes int32) {
|
||||
if numAllNodes < minFeasibleNodesToFind {
|
||||
return numAllNodes
|
||||
}
|
||||
|
||||
adaptivePercentage := sched.percentageOfNodesToScore
|
||||
if adaptivePercentage <= 0 {
|
||||
basePercentageOfNodesToScore := int32(50)
|
||||
adaptivePercentage = basePercentageOfNodesToScore - numAllNodes/125
|
||||
if adaptivePercentage < minFeasibleNodesPercentageToFind {
|
||||
adaptivePercentage = minFeasibleNodesPercentageToFind
|
||||
// Use profile percentageOfNodesToScore if it's set. Otherwise, use global percentageOfNodesToScore.
|
||||
var percentage int32
|
||||
if percentageOfNodesToScore != nil {
|
||||
percentage = *percentageOfNodesToScore
|
||||
} else {
|
||||
percentage = sched.percentageOfNodesToScore
|
||||
}
|
||||
|
||||
if percentage == 0 {
|
||||
percentage = int32(50) - numAllNodes/125
|
||||
if percentage < minFeasibleNodesPercentageToFind {
|
||||
percentage = minFeasibleNodesPercentageToFind
|
||||
}
|
||||
}
|
||||
|
||||
numNodes = numAllNodes * adaptivePercentage / 100
|
||||
numNodes = numAllNodes * percentage / 100
|
||||
if numNodes < minFeasibleNodesToFind {
|
||||
return minFeasibleNodesToFind
|
||||
}
|
||||
|
@ -2346,10 +2346,11 @@ var lowPriority, midPriority, highPriority = int32(0), int32(100), int32(1000)
|
||||
|
||||
func TestNumFeasibleNodesToFind(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
percentageOfNodesToScore int32
|
||||
numAllNodes int32
|
||||
wantNumNodes int32
|
||||
name string
|
||||
globalPercentage int32
|
||||
profilePercentage *int32
|
||||
numAllNodes int32
|
||||
wantNumNodes int32
|
||||
}{
|
||||
{
|
||||
name: "not set percentageOfNodesToScore and nodes number not more than 50",
|
||||
@ -2357,10 +2358,10 @@ func TestNumFeasibleNodesToFind(t *testing.T) {
|
||||
wantNumNodes: 10,
|
||||
},
|
||||
{
|
||||
name: "set percentageOfNodesToScore and nodes number not more than 50",
|
||||
percentageOfNodesToScore: 40,
|
||||
numAllNodes: 10,
|
||||
wantNumNodes: 10,
|
||||
name: "set profile percentageOfNodesToScore and nodes number not more than 50",
|
||||
profilePercentage: pointer.Int32(40),
|
||||
numAllNodes: 10,
|
||||
wantNumNodes: 10,
|
||||
},
|
||||
{
|
||||
name: "not set percentageOfNodesToScore and nodes number more than 50",
|
||||
@ -2368,29 +2369,43 @@ func TestNumFeasibleNodesToFind(t *testing.T) {
|
||||
wantNumNodes: 420,
|
||||
},
|
||||
{
|
||||
name: "set percentageOfNodesToScore and nodes number more than 50",
|
||||
percentageOfNodesToScore: 40,
|
||||
numAllNodes: 1000,
|
||||
wantNumNodes: 400,
|
||||
name: "set profile percentageOfNodesToScore and nodes number more than 50",
|
||||
profilePercentage: pointer.Int32(40),
|
||||
numAllNodes: 1000,
|
||||
wantNumNodes: 400,
|
||||
},
|
||||
{
|
||||
name: "not set percentageOfNodesToScore and nodes number more than 50*125",
|
||||
name: "set global and profile percentageOfNodesToScore and nodes number more than 50",
|
||||
globalPercentage: 100,
|
||||
profilePercentage: pointer.Int32(40),
|
||||
numAllNodes: 1000,
|
||||
wantNumNodes: 400,
|
||||
},
|
||||
{
|
||||
name: "set global percentageOfNodesToScore and nodes number more than 50",
|
||||
globalPercentage: 40,
|
||||
numAllNodes: 1000,
|
||||
wantNumNodes: 400,
|
||||
},
|
||||
{
|
||||
name: "not set profile percentageOfNodesToScore and nodes number more than 50*125",
|
||||
numAllNodes: 6000,
|
||||
wantNumNodes: 300,
|
||||
},
|
||||
{
|
||||
name: "set percentageOfNodesToScore and nodes number more than 50*125",
|
||||
percentageOfNodesToScore: 40,
|
||||
numAllNodes: 6000,
|
||||
wantNumNodes: 2400,
|
||||
name: "set profile percentageOfNodesToScore and nodes number more than 50*125",
|
||||
profilePercentage: pointer.Int32(40),
|
||||
numAllNodes: 6000,
|
||||
wantNumNodes: 2400,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
sched := &Scheduler{
|
||||
percentageOfNodesToScore: tt.percentageOfNodesToScore,
|
||||
percentageOfNodesToScore: tt.globalPercentage,
|
||||
}
|
||||
if gotNumNodes := sched.numFeasibleNodesToFind(tt.numAllNodes); gotNumNodes != tt.wantNumNodes {
|
||||
if gotNumNodes := sched.numFeasibleNodesToFind(tt.profilePercentage, tt.numAllNodes); gotNumNodes != tt.wantNumNodes {
|
||||
t.Errorf("Scheduler.numFeasibleNodesToFind() = %v, want %v", gotNumNodes, tt.wantNumNodes)
|
||||
}
|
||||
})
|
||||
@ -2423,7 +2438,7 @@ func TestFairEvaluationForNodes(t *testing.T) {
|
||||
|
||||
// To make numAllNodes % nodesToFind != 0
|
||||
sched.percentageOfNodesToScore = 30
|
||||
nodesToFind := int(sched.numFeasibleNodesToFind(int32(numAllNodes)))
|
||||
nodesToFind := int(sched.numFeasibleNodesToFind(fwk.PercentageOfNodesToScore(), int32(numAllNodes)))
|
||||
|
||||
// Iterating over all nodes more than twice
|
||||
for i := 0; i < 2*(numAllNodes/nodesToFind+1); i++ {
|
||||
|
@ -104,8 +104,9 @@ func (s *Scheduler) applyDefaultHandlers() {
|
||||
}
|
||||
|
||||
type schedulerOptions struct {
|
||||
componentConfigVersion string
|
||||
kubeConfig *restclient.Config
|
||||
componentConfigVersion string
|
||||
kubeConfig *restclient.Config
|
||||
// Overridden by profile level percentageOfNodesToScore if set in v1.
|
||||
percentageOfNodesToScore int32
|
||||
podInitialBackoffSeconds int64
|
||||
podMaxBackoffSeconds int64
|
||||
@ -166,10 +167,13 @@ func WithParallelism(threads int32) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithPercentageOfNodesToScore sets percentageOfNodesToScore for Scheduler, the default value is 50
|
||||
func WithPercentageOfNodesToScore(percentageOfNodesToScore int32) Option {
|
||||
// WithPercentageOfNodesToScore sets percentageOfNodesToScore for Scheduler.
|
||||
// The default value of 0 will use an adaptive percentage: 50 - (num of nodes)/125.
|
||||
func WithPercentageOfNodesToScore(percentageOfNodesToScore *int32) Option {
|
||||
return func(o *schedulerOptions) {
|
||||
o.percentageOfNodesToScore = percentageOfNodesToScore
|
||||
if percentageOfNodesToScore != nil {
|
||||
o.percentageOfNodesToScore = *percentageOfNodesToScore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/scheduler/profile"
|
||||
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||
testingclock "k8s.io/utils/clock/testing"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
func TestSchedulerCreation(t *testing.T) {
|
||||
@ -415,6 +416,50 @@ func TestFailureHandler_PodAlreadyBound(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestWithPercentageOfNodesToScore tests scheduler's PercentageOfNodesToScore is set correctly.
|
||||
func TestWithPercentageOfNodesToScore(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
percentageOfNodesToScoreConfig *int32
|
||||
wantedPercentageOfNodesToScore int32
|
||||
}{
|
||||
{
|
||||
name: "percentageOfNodesScore is nil",
|
||||
percentageOfNodesToScoreConfig: nil,
|
||||
wantedPercentageOfNodesToScore: schedulerapi.DefaultPercentageOfNodesToScore,
|
||||
},
|
||||
{
|
||||
name: "percentageOfNodesScore is not nil",
|
||||
percentageOfNodesToScoreConfig: pointer.Int32(10),
|
||||
wantedPercentageOfNodesToScore: 10,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
client := fake.NewSimpleClientset()
|
||||
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
||||
eventBroadcaster := events.NewBroadcaster(&events.EventSinkImpl{Interface: client.EventsV1()})
|
||||
stopCh := make(chan struct{})
|
||||
defer close(stopCh)
|
||||
sched, err := New(
|
||||
client,
|
||||
informerFactory,
|
||||
nil,
|
||||
profile.NewRecorderFactory(eventBroadcaster),
|
||||
stopCh,
|
||||
WithPercentageOfNodesToScore(tt.percentageOfNodesToScoreConfig),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create scheduler: %v", err)
|
||||
}
|
||||
if sched.percentageOfNodesToScore != tt.wantedPercentageOfNodesToScore {
|
||||
t.Errorf("scheduler.percercentageOfNodesToScore = %v, want %v", sched.percentageOfNodesToScore, tt.wantedPercentageOfNodesToScore)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// getPodFromPriorityQueue is the function used in the TestDefaultErrorFunc test to get
|
||||
// the specific pod from the given priority queue. It returns the found pod in the priority queue.
|
||||
func getPodFromPriorityQueue(queue *internalqueue.PriorityQueue, pod *v1.Pod) *v1.Pod {
|
||||
|
@ -64,7 +64,7 @@ type KubeSchedulerConfiguration struct {
|
||||
// Example: if the cluster size is 500 nodes and the value of this flag is 30,
|
||||
// then scheduler stops finding further feasible nodes once it finds 150 feasible ones.
|
||||
// When the value is 0, default percentage (5%--50% based on the size of the cluster) of the
|
||||
// nodes will be scored.
|
||||
// nodes will be scored. It is overridden by profile level PercentageofNodesToScore.
|
||||
PercentageOfNodesToScore *int32 `json:"percentageOfNodesToScore,omitempty"`
|
||||
|
||||
// PodInitialBackoffSeconds is the initial backoff for unschedulable pods.
|
||||
@ -135,6 +135,17 @@ type KubeSchedulerProfile struct {
|
||||
// is scheduled with this profile.
|
||||
SchedulerName *string `json:"schedulerName,omitempty"`
|
||||
|
||||
// PercentageOfNodesToScore is the percentage of all nodes that once found feasible
|
||||
// for running a pod, the scheduler stops its search for more feasible nodes in
|
||||
// the cluster. This helps improve scheduler's performance. Scheduler always tries to find
|
||||
// at least "minFeasibleNodesToFind" feasible nodes no matter what the value of this flag is.
|
||||
// Example: if the cluster size is 500 nodes and the value of this flag is 30,
|
||||
// then scheduler stops finding further feasible nodes once it finds 150 feasible ones.
|
||||
// When the value is 0, default percentage (5%--50% based on the size of the cluster) of the
|
||||
// nodes will be scored. It will override global PercentageOfNodesToScore. If it is empty,
|
||||
// global PercentageOfNodesToScore will be used.
|
||||
PercentageOfNodesToScore *int32 `json:"percentageOfNodesToScore,omitempty"`
|
||||
|
||||
// Plugins specify the set of plugins that should be enabled or disabled.
|
||||
// Enabled plugins are the ones that should be enabled in addition to the
|
||||
// default plugins. Disabled plugins are any of the default plugins that
|
||||
|
@ -235,6 +235,11 @@ func (in *KubeSchedulerProfile) DeepCopyInto(out *KubeSchedulerProfile) {
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.PercentageOfNodesToScore != nil {
|
||||
in, out := &in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Plugins != nil {
|
||||
in, out := &in.Plugins, &out.Plugins
|
||||
*out = new(Plugins)
|
||||
|
Loading…
Reference in New Issue
Block a user