mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 08:17:26 +00:00
kube-scheduler: Use default predicates/prioritizers if policy config does not specify them
This commit is contained in:
parent
1105751cc7
commit
f69eaa3b18
@ -37,9 +37,14 @@ const (
|
|||||||
|
|
||||||
type Policy struct {
|
type Policy struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta
|
||||||
// Holds the information to configure the fit predicate functions
|
// Holds the information to configure the fit predicate functions.
|
||||||
|
// If unspecified, the default predicate functions will be applied.
|
||||||
|
// If empty list, all predicates (except the mandatory ones) will be
|
||||||
|
// bypassed.
|
||||||
Predicates []PredicatePolicy
|
Predicates []PredicatePolicy
|
||||||
// Holds the information to configure the priority functions
|
// Holds the information to configure the priority functions.
|
||||||
|
// If unspecified, the default priority functions will be applied.
|
||||||
|
// If empty list, all priority functions will be bypassed.
|
||||||
Priorities []PriorityPolicy
|
Priorities []PriorityPolicy
|
||||||
// Holds the information to communicate with the extender(s)
|
// Holds the information to communicate with the extender(s)
|
||||||
ExtenderConfigs []ExtenderConfig
|
ExtenderConfigs []ExtenderConfig
|
||||||
|
@ -67,6 +67,7 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/api/legacyscheme:go_default_library",
|
"//pkg/api/legacyscheme:go_default_library",
|
||||||
"//pkg/api/testing:go_default_library",
|
"//pkg/api/testing:go_default_library",
|
||||||
|
"//pkg/scheduler:go_default_library",
|
||||||
"//pkg/scheduler/algorithm:go_default_library",
|
"//pkg/scheduler/algorithm:go_default_library",
|
||||||
"//pkg/scheduler/api:go_default_library",
|
"//pkg/scheduler/api:go_default_library",
|
||||||
"//pkg/scheduler/api/latest:go_default_library",
|
"//pkg/scheduler/api/latest:go_default_library",
|
||||||
@ -77,6 +78,7 @@ go_test(
|
|||||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/informers:go_default_library",
|
"//vendor/k8s.io/client-go/informers:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
|
@ -892,15 +892,33 @@ func (f *configFactory) CreateFromConfig(policy schedulerapi.Policy) (*scheduler
|
|||||||
}
|
}
|
||||||
|
|
||||||
predicateKeys := sets.NewString()
|
predicateKeys := sets.NewString()
|
||||||
for _, predicate := range policy.Predicates {
|
if policy.Predicates == nil {
|
||||||
glog.V(2).Infof("Registering predicate: %s", predicate.Name)
|
glog.V(2).Infof("Using predicates from algorithm provider '%v'", DefaultProvider)
|
||||||
predicateKeys.Insert(RegisterCustomFitPredicate(predicate))
|
provider, err := GetAlgorithmProvider(DefaultProvider)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
predicateKeys = provider.FitPredicateKeys
|
||||||
|
} else {
|
||||||
|
for _, predicate := range policy.Predicates {
|
||||||
|
glog.V(2).Infof("Registering predicate: %s", predicate.Name)
|
||||||
|
predicateKeys.Insert(RegisterCustomFitPredicate(predicate))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
priorityKeys := sets.NewString()
|
priorityKeys := sets.NewString()
|
||||||
for _, priority := range policy.Priorities {
|
if policy.Priorities == nil {
|
||||||
glog.V(2).Infof("Registering priority: %s", priority.Name)
|
glog.V(2).Infof("Using priorities from algorithm provider '%v'", DefaultProvider)
|
||||||
priorityKeys.Insert(RegisterCustomPriorityFunction(priority))
|
provider, err := GetAlgorithmProvider(DefaultProvider)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
priorityKeys = provider.PriorityFunctionKeys
|
||||||
|
} else {
|
||||||
|
for _, priority := range policy.Priorities {
|
||||||
|
glog.V(2).Infof("Registering priority: %s", priority.Name)
|
||||||
|
priorityKeys.Insert(RegisterCustomPriorityFunction(priority))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extenders := make([]algorithm.SchedulerExtender, 0)
|
extenders := make([]algorithm.SchedulerExtender, 0)
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
@ -33,6 +34,7 @@ import (
|
|||||||
utiltesting "k8s.io/client-go/util/testing"
|
utiltesting "k8s.io/client-go/util/testing"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/scheduler"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/algorithm"
|
"k8s.io/kubernetes/pkg/scheduler/algorithm"
|
||||||
schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
|
schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
|
||||||
latestschedulerapi "k8s.io/kubernetes/pkg/scheduler/api/latest"
|
latestschedulerapi "k8s.io/kubernetes/pkg/scheduler/api/latest"
|
||||||
@ -53,23 +55,7 @@ func TestCreate(t *testing.T) {
|
|||||||
server := httptest.NewServer(&handler)
|
server := httptest.NewServer(&handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
||||||
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(),
|
|
||||||
informerFactory.Policy().V1beta1().PodDisruptionBudgets(),
|
|
||||||
informerFactory.Storage().V1().StorageClasses(),
|
|
||||||
v1.DefaultHardPodAffinitySymmetricWeight,
|
|
||||||
enableEquivalenceCache,
|
|
||||||
)
|
|
||||||
factory.Create()
|
factory.Create()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,23 +73,7 @@ func TestCreateFromConfig(t *testing.T) {
|
|||||||
server := httptest.NewServer(&handler)
|
server := httptest.NewServer(&handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
||||||
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(),
|
|
||||||
informerFactory.Policy().V1beta1().PodDisruptionBudgets(),
|
|
||||||
informerFactory.Storage().V1().StorageClasses(),
|
|
||||||
v1.DefaultHardPodAffinitySymmetricWeight,
|
|
||||||
enableEquivalenceCache,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Pre-register some predicate and priority functions
|
// Pre-register some predicate and priority functions
|
||||||
RegisterFitPredicate("PredicateOne", PredicateOne)
|
RegisterFitPredicate("PredicateOne", PredicateOne)
|
||||||
@ -148,23 +118,7 @@ func TestCreateFromConfigWithHardPodAffinitySymmetricWeight(t *testing.T) {
|
|||||||
server := httptest.NewServer(&handler)
|
server := httptest.NewServer(&handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
||||||
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(),
|
|
||||||
informerFactory.Policy().V1beta1().PodDisruptionBudgets(),
|
|
||||||
informerFactory.Storage().V1().StorageClasses(),
|
|
||||||
v1.DefaultHardPodAffinitySymmetricWeight,
|
|
||||||
enableEquivalenceCache,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Pre-register some predicate and priority functions
|
// Pre-register some predicate and priority functions
|
||||||
RegisterFitPredicate("PredicateOne", PredicateOne)
|
RegisterFitPredicate("PredicateOne", PredicateOne)
|
||||||
@ -210,23 +164,7 @@ func TestCreateFromEmptyConfig(t *testing.T) {
|
|||||||
server := httptest.NewServer(&handler)
|
server := httptest.NewServer(&handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
||||||
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(),
|
|
||||||
informerFactory.Policy().V1beta1().PodDisruptionBudgets(),
|
|
||||||
informerFactory.Storage().V1().StorageClasses(),
|
|
||||||
v1.DefaultHardPodAffinitySymmetricWeight,
|
|
||||||
enableEquivalenceCache,
|
|
||||||
)
|
|
||||||
|
|
||||||
configData = []byte(`{}`)
|
configData = []byte(`{}`)
|
||||||
if err := runtime.DecodeInto(latestschedulerapi.Codec, configData, &policy); err != nil {
|
if err := runtime.DecodeInto(latestschedulerapi.Codec, configData, &policy); err != nil {
|
||||||
@ -236,6 +174,88 @@ func TestCreateFromEmptyConfig(t *testing.T) {
|
|||||||
factory.CreateFromConfig(policy)
|
factory.CreateFromConfig(policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test configures a scheduler from a policy that does not specify any
|
||||||
|
// predicate/priority.
|
||||||
|
// The predicate/priority from DefaultProvider will be used.
|
||||||
|
func TestCreateFromConfigWithUnspecifiedPredicatesOrPriorities(t *testing.T) {
|
||||||
|
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: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
||||||
|
|
||||||
|
RegisterFitPredicate("PredicateOne", PredicateOne)
|
||||||
|
RegisterPriorityFunction("PriorityOne", PriorityOne, 1)
|
||||||
|
|
||||||
|
RegisterAlgorithmProvider(DefaultProvider, sets.NewString("PredicateOne"), sets.NewString("PriorityOne"))
|
||||||
|
|
||||||
|
configData := []byte(`{
|
||||||
|
"kind" : "Policy",
|
||||||
|
"apiVersion" : "v1"
|
||||||
|
}`)
|
||||||
|
var policy schedulerapi.Policy
|
||||||
|
if err := runtime.DecodeInto(latestschedulerapi.Codec, configData, &policy); err != nil {
|
||||||
|
t.Fatalf("Invalid configuration: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := factory.CreateFromConfig(policy)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create scheduler from configuration: %v", err)
|
||||||
|
}
|
||||||
|
if _, found := config.Algorithm.Predicates()["PredicateOne"]; !found {
|
||||||
|
t.Errorf("Expected predicate PredicateOne from %q", DefaultProvider)
|
||||||
|
}
|
||||||
|
if len(config.Algorithm.Prioritizers()) != 1 || config.Algorithm.Prioritizers()[0].Name != "PriorityOne" {
|
||||||
|
t.Errorf("Expected priority PriorityOne from %q", DefaultProvider)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test configures a scheduler from a policy that contains empty
|
||||||
|
// predicate/priority.
|
||||||
|
// Empty predicate/priority sets will be used.
|
||||||
|
func TestCreateFromConfigWithEmptyPredicatesOrPriorities(t *testing.T) {
|
||||||
|
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: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
||||||
|
|
||||||
|
RegisterFitPredicate("PredicateOne", PredicateOne)
|
||||||
|
RegisterPriorityFunction("PriorityOne", PriorityOne, 1)
|
||||||
|
|
||||||
|
RegisterAlgorithmProvider(DefaultProvider, sets.NewString("PredicateOne"), sets.NewString("PriorityOne"))
|
||||||
|
|
||||||
|
configData := []byte(`{
|
||||||
|
"kind" : "Policy",
|
||||||
|
"apiVersion" : "v1",
|
||||||
|
"predicates" : [],
|
||||||
|
"priorities" : []
|
||||||
|
}`)
|
||||||
|
var policy schedulerapi.Policy
|
||||||
|
if err := runtime.DecodeInto(latestschedulerapi.Codec, configData, &policy); err != nil {
|
||||||
|
t.Fatalf("Invalid configuration: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := factory.CreateFromConfig(policy)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create scheduler from configuration: %v", err)
|
||||||
|
}
|
||||||
|
if len(config.Algorithm.Predicates()) != 0 {
|
||||||
|
t.Error("Expected empty predicate sets")
|
||||||
|
}
|
||||||
|
if len(config.Algorithm.Prioritizers()) != 0 {
|
||||||
|
t.Error("Expected empty priority sets")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func PredicateOne(pod *v1.Pod, meta algorithm.PredicateMetadata, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) {
|
func PredicateOne(pod *v1.Pod, meta algorithm.PredicateMetadata, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) {
|
||||||
return true, nil, nil
|
return true, nil, nil
|
||||||
}
|
}
|
||||||
@ -269,23 +289,7 @@ func TestDefaultErrorFunc(t *testing.T) {
|
|||||||
server := httptest.NewServer(mux)
|
server := httptest.NewServer(mux)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
||||||
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(),
|
|
||||||
informerFactory.Policy().V1beta1().PodDisruptionBudgets(),
|
|
||||||
informerFactory.Storage().V1().StorageClasses(),
|
|
||||||
v1.DefaultHardPodAffinitySymmetricWeight,
|
|
||||||
enableEquivalenceCache,
|
|
||||||
)
|
|
||||||
queue := &core.FIFO{FIFO: cache.NewFIFO(cache.MetaNamespaceKeyFunc)}
|
queue := &core.FIFO{FIFO: cache.NewFIFO(cache.MetaNamespaceKeyFunc)}
|
||||||
podBackoff := util.CreatePodBackoff(1*time.Millisecond, 1*time.Second)
|
podBackoff := util.CreatePodBackoff(1*time.Millisecond, 1*time.Second)
|
||||||
errFunc := factory.MakeDefaultErrorFunc(podBackoff, queue)
|
errFunc := factory.MakeDefaultErrorFunc(podBackoff, queue)
|
||||||
@ -379,23 +383,7 @@ func TestInvalidHardPodAffinitySymmetricWeight(t *testing.T) {
|
|||||||
defer server.Close()
|
defer server.Close()
|
||||||
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
// factory of "default-scheduler"
|
// factory of "default-scheduler"
|
||||||
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
factory := newConfigFactory(client, -1)
|
||||||
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(),
|
|
||||||
informerFactory.Policy().V1beta1().PodDisruptionBudgets(),
|
|
||||||
informerFactory.Storage().V1().StorageClasses(),
|
|
||||||
-1,
|
|
||||||
enableEquivalenceCache,
|
|
||||||
)
|
|
||||||
_, err := factory.Create()
|
_, err := factory.Create()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("expected err: invalid hardPodAffinitySymmetricWeight, got nothing")
|
t.Errorf("expected err: invalid hardPodAffinitySymmetricWeight, got nothing")
|
||||||
@ -427,23 +415,7 @@ func TestInvalidFactoryArgs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
factory := newConfigFactory(client, test.hardPodAffinitySymmetricWeight)
|
||||||
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(),
|
|
||||||
informerFactory.Policy().V1beta1().PodDisruptionBudgets(),
|
|
||||||
informerFactory.Storage().V1().StorageClasses(),
|
|
||||||
test.hardPodAffinitySymmetricWeight,
|
|
||||||
enableEquivalenceCache,
|
|
||||||
)
|
|
||||||
_, err := factory.Create()
|
_, err := factory.Create()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("expected err: %s, got nothing", test.expectErr)
|
t.Errorf("expected err: %s, got nothing", test.expectErr)
|
||||||
@ -541,3 +513,23 @@ func TestSkipPodUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newConfigFactory(client *clientset.Clientset, hardPodAffinitySymmetricWeight int32) scheduler.Configurator {
|
||||||
|
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
||||||
|
return 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(),
|
||||||
|
informerFactory.Policy().V1beta1().PodDisruptionBudgets(),
|
||||||
|
informerFactory.Storage().V1().StorageClasses(),
|
||||||
|
hardPodAffinitySymmetricWeight,
|
||||||
|
enableEquivalenceCache,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -57,6 +57,7 @@ go_test(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/informers:go_default_library",
|
"//vendor/k8s.io/client-go/informers:go_default_library",
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/util/diff"
|
"k8s.io/apimachinery/pkg/util/diff"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
@ -97,69 +98,128 @@ func TestSchedulerCreationFromConfigMap(t *testing.T) {
|
|||||||
factory.RegisterPriorityFunction("PriorityOne", PriorityOne, 1)
|
factory.RegisterPriorityFunction("PriorityOne", PriorityOne, 1)
|
||||||
factory.RegisterPriorityFunction("PriorityTwo", PriorityTwo, 1)
|
factory.RegisterPriorityFunction("PriorityTwo", PriorityTwo, 1)
|
||||||
|
|
||||||
// Add a ConfigMap object.
|
for i, test := range []struct {
|
||||||
configPolicyName := "scheduler-custom-policy-config"
|
policy string
|
||||||
policyConfigMap := v1.ConfigMap{
|
expectedPredicates sets.String
|
||||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: configPolicyName},
|
expectedPrioritizers sets.String
|
||||||
Data: map[string]string{
|
}{
|
||||||
componentconfig.SchedulerPolicyConfigMapKey: `{
|
{
|
||||||
"kind" : "Policy",
|
policy: `{
|
||||||
"apiVersion" : "v1",
|
"kind" : "Policy",
|
||||||
"predicates" : [
|
"apiVersion" : "v1",
|
||||||
{"name" : "PredicateOne"},
|
"predicates" : [
|
||||||
{"name" : "PredicateTwo"}
|
{"name" : "PredicateOne"},
|
||||||
],
|
{"name" : "PredicateTwo"}
|
||||||
"priorities" : [
|
],
|
||||||
{"name" : "PriorityOne", "weight" : 1},
|
"priorities" : [
|
||||||
{"name" : "PriorityTwo", "weight" : 5}
|
{"name" : "PriorityOne", "weight" : 1},
|
||||||
]
|
{"name" : "PriorityTwo", "weight" : 5}
|
||||||
|
]
|
||||||
}`,
|
}`,
|
||||||
|
expectedPredicates: sets.NewString(
|
||||||
|
"CheckNodeCondition", // mandatory predicate
|
||||||
|
"PredicateOne",
|
||||||
|
"PredicateTwo",
|
||||||
|
),
|
||||||
|
expectedPrioritizers: sets.NewString(
|
||||||
|
"PriorityOne",
|
||||||
|
"PriorityTwo",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
}
|
{
|
||||||
|
policy: `{
|
||||||
|
"kind" : "Policy",
|
||||||
|
"apiVersion" : "v1"
|
||||||
|
}`,
|
||||||
|
expectedPredicates: sets.NewString(
|
||||||
|
"CheckNodeCondition", // mandatory predicate
|
||||||
|
"CheckNodeDiskPressure",
|
||||||
|
"CheckNodeMemoryPressure",
|
||||||
|
"CheckVolumeBinding",
|
||||||
|
"GeneralPredicates",
|
||||||
|
"MatchInterPodAffinity",
|
||||||
|
"MaxAzureDiskVolumeCount",
|
||||||
|
"MaxEBSVolumeCount",
|
||||||
|
"MaxGCEPDVolumeCount",
|
||||||
|
"NoDiskConflict",
|
||||||
|
"NoVolumeZoneConflict",
|
||||||
|
"PodToleratesNodeTaints",
|
||||||
|
),
|
||||||
|
expectedPrioritizers: sets.NewString(
|
||||||
|
"BalancedResourceAllocation",
|
||||||
|
"InterPodAffinityPriority",
|
||||||
|
"LeastRequestedPriority",
|
||||||
|
"NodeAffinityPriority",
|
||||||
|
"NodePreferAvoidPodsPriority",
|
||||||
|
"SelectorSpreadPriority",
|
||||||
|
"TaintTolerationPriority",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
policy: `{
|
||||||
|
"kind" : "Policy",
|
||||||
|
"apiVersion" : "v1",
|
||||||
|
"predicates" : [],
|
||||||
|
"priorities" : []
|
||||||
|
}`,
|
||||||
|
expectedPredicates: sets.NewString(
|
||||||
|
"CheckNodeCondition", // mandatory predicate
|
||||||
|
),
|
||||||
|
expectedPrioritizers: sets.NewString(),
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
// Add a ConfigMap object.
|
||||||
|
configPolicyName := fmt.Sprintf("scheduler-custom-policy-config-%d", i)
|
||||||
|
policyConfigMap := v1.ConfigMap{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: configPolicyName},
|
||||||
|
Data: map[string]string{componentconfig.SchedulerPolicyConfigMapKey: test.policy},
|
||||||
|
}
|
||||||
|
|
||||||
policyConfigMap.APIVersion = testapi.Groups[v1.GroupName].GroupVersion().String()
|
policyConfigMap.APIVersion = testapi.Groups[v1.GroupName].GroupVersion().String()
|
||||||
clientSet.CoreV1().ConfigMaps(metav1.NamespaceSystem).Create(&policyConfigMap)
|
clientSet.CoreV1().ConfigMaps(metav1.NamespaceSystem).Create(&policyConfigMap)
|
||||||
|
|
||||||
eventBroadcaster := record.NewBroadcaster()
|
eventBroadcaster := record.NewBroadcaster()
|
||||||
eventBroadcaster.StartRecordingToSink(&clientv1core.EventSinkImpl{Interface: clientv1core.New(clientSet.CoreV1().RESTClient()).Events("")})
|
eventBroadcaster.StartRecordingToSink(&clientv1core.EventSinkImpl{Interface: clientv1core.New(clientSet.CoreV1().RESTClient()).Events("")})
|
||||||
|
|
||||||
ss := &schedulerapp.SchedulerServer{
|
ss := &schedulerapp.SchedulerServer{
|
||||||
SchedulerName: v1.DefaultSchedulerName,
|
SchedulerName: v1.DefaultSchedulerName,
|
||||||
AlgorithmSource: componentconfig.SchedulerAlgorithmSource{
|
AlgorithmSource: componentconfig.SchedulerAlgorithmSource{
|
||||||
Policy: &componentconfig.SchedulerPolicySource{
|
Policy: &componentconfig.SchedulerPolicySource{
|
||||||
ConfigMap: &componentconfig.SchedulerPolicyConfigMapSource{
|
ConfigMap: &componentconfig.SchedulerPolicyConfigMapSource{
|
||||||
Namespace: policyConfigMap.Namespace,
|
Namespace: policyConfigMap.Namespace,
|
||||||
Name: policyConfigMap.Name,
|
Name: policyConfigMap.Name,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
HardPodAffinitySymmetricWeight: v1.DefaultHardPodAffinitySymmetricWeight,
|
||||||
HardPodAffinitySymmetricWeight: v1.DefaultHardPodAffinitySymmetricWeight,
|
Client: clientSet,
|
||||||
Client: clientSet,
|
InformerFactory: informerFactory,
|
||||||
InformerFactory: informerFactory,
|
PodInformer: factory.NewPodInformer(clientSet, 0, v1.DefaultSchedulerName),
|
||||||
PodInformer: factory.NewPodInformer(clientSet, 0, v1.DefaultSchedulerName),
|
EventClient: clientSet.CoreV1(),
|
||||||
EventClient: clientSet.CoreV1(),
|
Recorder: eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: v1.DefaultSchedulerName}),
|
||||||
Recorder: eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: v1.DefaultSchedulerName}),
|
Broadcaster: eventBroadcaster,
|
||||||
Broadcaster: eventBroadcaster,
|
}
|
||||||
}
|
|
||||||
|
|
||||||
config, err := ss.SchedulerConfig()
|
config, err := ss.SchedulerConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("couldn't make scheduler config: %v", err)
|
t.Fatalf("couldn't make scheduler config: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that the config is applied correctly.
|
// Verify that the config is applied correctly.
|
||||||
schedPredicates := config.Algorithm.Predicates()
|
schedPredicates := sets.NewString()
|
||||||
schedPrioritizers := config.Algorithm.Prioritizers()
|
for k := range config.Algorithm.Predicates() {
|
||||||
// Includes one mandatory predicates.
|
schedPredicates.Insert(k)
|
||||||
if len(schedPredicates) != 3 || len(schedPrioritizers) != 2 {
|
}
|
||||||
t.Errorf("Unexpected number of predicates or priority functions. Number of predicates: %v, number of prioritizers: %v", len(schedPredicates), len(schedPrioritizers))
|
schedPrioritizers := sets.NewString()
|
||||||
}
|
for _, p := range config.Algorithm.Prioritizers() {
|
||||||
// Check a predicate and a priority function.
|
schedPrioritizers.Insert(p.Name)
|
||||||
if schedPredicates["PredicateTwo"] == nil {
|
}
|
||||||
t.Errorf("Expected to have a PodFitsHostPorts predicate.")
|
if !schedPredicates.Equal(test.expectedPredicates) {
|
||||||
}
|
t.Errorf("Expected predicates %v, got %v", test.expectedPredicates, schedPredicates)
|
||||||
if schedPrioritizers[1].Function == nil || schedPrioritizers[1].Weight != 5 {
|
}
|
||||||
t.Errorf("Unexpected prioritizer: func: %v, weight: %v", schedPrioritizers[1].Function, schedPrioritizers[1].Weight)
|
if !schedPrioritizers.Equal(test.expectedPrioritizers) {
|
||||||
|
t.Errorf("Expected priority functions %v, got %v", test.expectedPrioritizers, schedPrioritizers)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user