diff --git a/examples/scheduler-policy-config-with-extender.json b/examples/scheduler-policy-config-with-extender.json index eea38f5c40..071b08d2bf 100644 --- a/examples/scheduler-policy-config-with-extender.json +++ b/examples/scheduler-policy-config-with-extender.json @@ -14,7 +14,7 @@ {"name" : "ServiceSpreadingPriority", "weight" : 1}, {"name" : "EqualPriority", "weight" : 1} ], -"extenders":[ +"extenders" : [ { "urlPrefix": "http://127.0.0.1:12346/scheduler", "apiVersion": "v1beta1", @@ -24,5 +24,6 @@ "enableHttps": false, "nodeCacheCapable": false } - ] + ], +"hardPodAffinitySymmetricWeight" : 10 } diff --git a/examples/scheduler-policy-config.json b/examples/scheduler-policy-config.json index f93c39d133..b0fecffab2 100644 --- a/examples/scheduler-policy-config.json +++ b/examples/scheduler-policy-config.json @@ -14,5 +14,6 @@ {"name" : "BalancedResourceAllocation", "weight" : 1}, {"name" : "ServiceSpreadingPriority", "weight" : 1}, {"name" : "EqualPriority", "weight" : 1} - ] + ], +"hardPodAffinitySymmetricWeight" : 10 } diff --git a/plugin/cmd/kube-scheduler/app/options/options.go b/plugin/cmd/kube-scheduler/app/options/options.go index 6db57db802..1fe236fbc9 100644 --- a/plugin/cmd/kube-scheduler/app/options/options.go +++ b/plugin/cmd/kube-scheduler/app/options/options.go @@ -87,6 +87,7 @@ func (s *SchedulerServer) AddFlags(fs *pflag.FlagSet) { fs.IntVar(&s.HardPodAffinitySymmetricWeight, "hard-pod-affinity-symmetric-weight", api.DefaultHardPodAffinitySymmetricWeight, "RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule corresponding "+ "to every RequiredDuringScheduling affinity rule. --hard-pod-affinity-symmetric-weight represents the weight of implicit PreferredDuringScheduling affinity rule.") + fs.MarkDeprecated("hard-pod-affinity-symmetric-weight", "This option was moved to the policy configuration file") fs.StringVar(&s.FailureDomains, "failure-domains", api.DefaultFailureDomains, "Indicate the \"all topologies\" set for an empty topologyKey when it's used for PreferredDuringScheduling pod anti-affinity.") fs.MarkDeprecated("failure-domains", "Doesn't have any effect. Will be removed in future version.") leaderelection.BindFlags(&s.LeaderElection, fs) diff --git a/plugin/pkg/scheduler/api/types.go b/plugin/pkg/scheduler/api/types.go index 2f89d7544c..6498088dd8 100644 --- a/plugin/pkg/scheduler/api/types.go +++ b/plugin/pkg/scheduler/api/types.go @@ -40,6 +40,10 @@ type Policy struct { Priorities []PriorityPolicy // Holds the information to communicate with the extender(s) ExtenderConfigs []ExtenderConfig + // RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule + // corresponding to every RequiredDuringScheduling affinity rule. + // HardPodAffinitySymmetricWeight represents the weight of implicit PreferredDuringScheduling affinity rule, in the range 1-100. + HardPodAffinitySymmetricWeight int } type PredicatePolicy struct { diff --git a/plugin/pkg/scheduler/api/v1/types.go b/plugin/pkg/scheduler/api/v1/types.go index 036b6c5025..d8c6f50748 100644 --- a/plugin/pkg/scheduler/api/v1/types.go +++ b/plugin/pkg/scheduler/api/v1/types.go @@ -32,6 +32,10 @@ type Policy struct { Priorities []PriorityPolicy `json:"priorities"` // Holds the information to communicate with the extender(s) ExtenderConfigs []ExtenderConfig `json:"extenders"` + // RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule + // corresponding to every RequiredDuringScheduling affinity rule. + // HardPodAffinitySymmetricWeight represents the weight of implicit PreferredDuringScheduling affinity rule, in the range 1-100. + HardPodAffinitySymmetricWeight int `json:"hardPodAffinitySymmetricWeight"` } type PredicatePolicy struct { diff --git a/plugin/pkg/scheduler/factory/factory.go b/plugin/pkg/scheduler/factory/factory.go index b8687b7496..5a540622d8 100644 --- a/plugin/pkg/scheduler/factory/factory.go +++ b/plugin/pkg/scheduler/factory/factory.go @@ -378,6 +378,11 @@ func (f *ConfigFactory) CreateFromConfig(policy schedulerapi.Policy) (*scheduler } } } + // Providing HardPodAffinitySymmetricWeight in the policy config is the new and preferred way of providing the value. + // Give it higher precedence than scheduler CLI configuration when it is provided. + if policy.HardPodAffinitySymmetricWeight != 0 { + f.hardPodAffinitySymmetricWeight = policy.HardPodAffinitySymmetricWeight + } return f.CreateFromKeys(predicateKeys, priorityKeys, extenders) } @@ -385,8 +390,8 @@ func (f *ConfigFactory) CreateFromConfig(policy schedulerapi.Policy) (*scheduler func (f *ConfigFactory) CreateFromKeys(predicateKeys, priorityKeys sets.String, extenders []algorithm.SchedulerExtender) (*scheduler.Config, error) { glog.V(2).Infof("Creating scheduler with fit predicates '%v' and priority functions '%v", predicateKeys, priorityKeys) - if f.GetHardPodAffinitySymmetricWeight() < 0 || f.GetHardPodAffinitySymmetricWeight() > 100 { - return nil, fmt.Errorf("invalid hardPodAffinitySymmetricWeight: %d, must be in the range 0-100", f.GetHardPodAffinitySymmetricWeight()) + if f.GetHardPodAffinitySymmetricWeight() < 1 || f.GetHardPodAffinitySymmetricWeight() > 100 { + return nil, fmt.Errorf("invalid hardPodAffinitySymmetricWeight: %d, must be in the range 1-100", f.GetHardPodAffinitySymmetricWeight()) } predicateFuncs, err := f.GetPredicates(predicateKeys) diff --git a/plugin/pkg/scheduler/factory/factory_test.go b/plugin/pkg/scheduler/factory/factory_test.go index d72e873a3c..72fbf4acf1 100644 --- a/plugin/pkg/scheduler/factory/factory_test.go +++ b/plugin/pkg/scheduler/factory/factory_test.go @@ -121,6 +121,69 @@ func TestCreateFromConfig(t *testing.T) { } factory.CreateFromConfig(policy) + hpa := factory.GetHardPodAffinitySymmetricWeight() + if hpa != v1.DefaultHardPodAffinitySymmetricWeight { + t.Errorf("Wrong hardPodAffinitySymmetricWeight, ecpected: %d, got: %d", v1.DefaultHardPodAffinitySymmetricWeight, hpa) + } +} + +func TestCreateFromConfigWithHardPodAffinitySymmetricWeight(t *testing.T) { + var configData []byte + var policy schedulerapi.Policy + + handler := utiltesting.FakeHandler{ + StatusCode: 500, + ResponseBody: "", + T: t, + } + server := httptest.NewServer(&handler) + defer server.Close() + client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}}) + informerFactory := informers.NewSharedInformerFactory(client, 0) + factory := NewConfigFactory( + v1.DefaultSchedulerName, + client, + informerFactory.Core().V1().Nodes(), + informerFactory.Core().V1().Pods(), + informerFactory.Core().V1().PersistentVolumes(), + informerFactory.Core().V1().PersistentVolumeClaims(), + informerFactory.Core().V1().ReplicationControllers(), + informerFactory.Extensions().V1beta1().ReplicaSets(), + informerFactory.Apps().V1beta1().StatefulSets(), + informerFactory.Core().V1().Services(), + v1.DefaultHardPodAffinitySymmetricWeight, + ) + + // Pre-register some predicate and priority functions + RegisterFitPredicate("PredicateOne", PredicateOne) + RegisterFitPredicate("PredicateTwo", PredicateTwo) + RegisterPriorityFunction("PriorityOne", PriorityOne, 1) + RegisterPriorityFunction("PriorityTwo", PriorityTwo, 1) + + configData = []byte(`{ + "kind" : "Policy", + "apiVersion" : "v1", + "predicates" : [ + {"name" : "TestZoneAffinity", "argument" : {"serviceAffinity" : {"labels" : ["zone"]}}}, + {"name" : "TestRequireZone", "argument" : {"labelsPresence" : {"labels" : ["zone"], "presence" : true}}}, + {"name" : "PredicateOne"}, + {"name" : "PredicateTwo"} + ], + "priorities" : [ + {"name" : "RackSpread", "weight" : 3, "argument" : {"serviceAntiAffinity" : {"label" : "rack"}}}, + {"name" : "PriorityOne", "weight" : 2}, + {"name" : "PriorityTwo", "weight" : 1} + ], + "hardPodAffinitySymmetricWeight" : 10 + }`) + if err := runtime.DecodeInto(latestschedulerapi.Codec, configData, &policy); err != nil { + t.Errorf("Invalid configuration: %v", err) + } + factory.CreateFromConfig(policy) + hpa := factory.GetHardPodAffinitySymmetricWeight() + if hpa != 10 { + t.Errorf("Wrong hardPodAffinitySymmetricWeight, ecpected: %d, got: %d", 10, hpa) + } } func TestCreateFromEmptyConfig(t *testing.T) {