mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Add Extenders to scheduler v1alpha2 component config
This commit is contained in:
parent
06b798781a
commit
1d7006c38d
@ -187,6 +187,7 @@ func Run(ctx context.Context, cc schedulerserverconfig.CompletedConfig, outOfTre
|
|||||||
scheduler.WithFrameworkOutOfTreeRegistry(outOfTreeRegistry),
|
scheduler.WithFrameworkOutOfTreeRegistry(outOfTreeRegistry),
|
||||||
scheduler.WithPodMaxBackoffSeconds(cc.ComponentConfig.PodMaxBackoffSeconds),
|
scheduler.WithPodMaxBackoffSeconds(cc.ComponentConfig.PodMaxBackoffSeconds),
|
||||||
scheduler.WithPodInitialBackoffSeconds(cc.ComponentConfig.PodInitialBackoffSeconds),
|
scheduler.WithPodInitialBackoffSeconds(cc.ComponentConfig.PodInitialBackoffSeconds),
|
||||||
|
scheduler.WithExtenders(cc.ComponentConfig.Extenders...),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -101,6 +101,10 @@ type KubeSchedulerConfiguration struct {
|
|||||||
// scheduler name. Pods that don't specify any scheduler name are scheduled
|
// scheduler name. Pods that don't specify any scheduler name are scheduled
|
||||||
// with the "default-scheduler" profile, if present here.
|
// with the "default-scheduler" profile, if present here.
|
||||||
Profiles []KubeSchedulerProfile
|
Profiles []KubeSchedulerProfile
|
||||||
|
|
||||||
|
// Extenders are the list of scheduler extenders, each holding the values of how to communicate
|
||||||
|
// with the extender. These extenders are shared by all scheduler profiles.
|
||||||
|
Extenders []Extender
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubeSchedulerProfile is a scheduling profile.
|
// KubeSchedulerProfile is a scheduling profile.
|
||||||
|
@ -217,6 +217,7 @@ func autoConvert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConf
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// WARNING: in.Profiles requires manual conversion: does not exist in peer-type
|
// WARNING: in.Profiles requires manual conversion: does not exist in peer-type
|
||||||
|
// WARNING: in.Extenders requires manual conversion: does not exist in peer-type
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/component-base/config/v1alpha1:go_default_library",
|
"//staging/src/k8s.io/component-base/config/v1alpha1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/kube-scheduler/config/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/kube-scheduler/config/v1alpha2:go_default_library",
|
"//staging/src/k8s.io/kube-scheduler/config/v1alpha2:go_default_library",
|
||||||
"//vendor/k8s.io/utils/pointer:go_default_library",
|
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
v1alpha1 "k8s.io/component-base/config/v1alpha1"
|
v1alpha1 "k8s.io/component-base/config/v1alpha1"
|
||||||
|
configv1 "k8s.io/kube-scheduler/config/v1"
|
||||||
v1alpha2 "k8s.io/kube-scheduler/config/v1alpha2"
|
v1alpha2 "k8s.io/kube-scheduler/config/v1alpha2"
|
||||||
config "k8s.io/kubernetes/pkg/scheduler/apis/config"
|
config "k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||||
)
|
)
|
||||||
@ -153,6 +154,7 @@ func autoConvert_v1alpha2_KubeSchedulerConfiguration_To_config_KubeSchedulerConf
|
|||||||
} else {
|
} else {
|
||||||
out.Profiles = nil
|
out.Profiles = nil
|
||||||
}
|
}
|
||||||
|
out.Extenders = *(*[]config.Extender)(unsafe.Pointer(&in.Extenders))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +201,7 @@ func autoConvert_config_KubeSchedulerConfiguration_To_v1alpha2_KubeSchedulerConf
|
|||||||
} else {
|
} else {
|
||||||
out.Profiles = nil
|
out.Profiles = nil
|
||||||
}
|
}
|
||||||
|
out.Extenders = *(*[]configv1.Extender)(unsafe.Pointer(&in.Extenders))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +71,8 @@ func ValidateKubeSchedulerConfiguration(cc *config.KubeSchedulerConfiguration) f
|
|||||||
allErrs = append(allErrs, field.Invalid(field.NewPath("podMaxBackoffSeconds"),
|
allErrs = append(allErrs, field.Invalid(field.NewPath("podMaxBackoffSeconds"),
|
||||||
cc.PodMaxBackoffSeconds, "must be greater than or equal to PodInitialBackoffSeconds"))
|
cc.PodMaxBackoffSeconds, "must be greater than or equal to PodInitialBackoffSeconds"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allErrs = append(allErrs, validateExtenders(field.NewPath("extenders"), cc.Extenders)...)
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,28 +125,8 @@ func ValidatePolicy(policy config.Policy) error {
|
|||||||
validationErrors = append(validationErrors, validateCustomPriorities(priorities, priority))
|
validationErrors = append(validationErrors, validateCustomPriorities(priorities, priority))
|
||||||
}
|
}
|
||||||
|
|
||||||
binders := 0
|
if extenderErrs := validateExtenders(field.NewPath("extenders"), policy.Extenders); len(extenderErrs) > 0 {
|
||||||
extenderManagedResources := sets.NewString()
|
validationErrors = append(validationErrors, extenderErrs.ToAggregate().Errors()...)
|
||||||
for _, extender := range policy.Extenders {
|
|
||||||
if len(extender.PrioritizeVerb) > 0 && extender.Weight <= 0 {
|
|
||||||
validationErrors = append(validationErrors, fmt.Errorf("Priority for extender %s should have a positive weight applied to it", extender.URLPrefix))
|
|
||||||
}
|
|
||||||
if extender.BindVerb != "" {
|
|
||||||
binders++
|
|
||||||
}
|
|
||||||
for _, resource := range extender.ManagedResources {
|
|
||||||
errs := validateExtendedResourceName(v1.ResourceName(resource.Name))
|
|
||||||
if len(errs) != 0 {
|
|
||||||
validationErrors = append(validationErrors, errs...)
|
|
||||||
}
|
|
||||||
if extenderManagedResources.Has(resource.Name) {
|
|
||||||
validationErrors = append(validationErrors, fmt.Errorf("Duplicate extender managed resource name %s", string(resource.Name)))
|
|
||||||
}
|
|
||||||
extenderManagedResources.Insert(resource.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if binders > 1 {
|
|
||||||
validationErrors = append(validationErrors, fmt.Errorf("Only one extender can implement bind, found %v", binders))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if policy.HardPodAffinitySymmetricWeight < 0 || policy.HardPodAffinitySymmetricWeight > 100 {
|
if policy.HardPodAffinitySymmetricWeight < 0 || policy.HardPodAffinitySymmetricWeight > 100 {
|
||||||
@ -153,6 +135,40 @@ func ValidatePolicy(policy config.Policy) error {
|
|||||||
return utilerrors.NewAggregate(validationErrors)
|
return utilerrors.NewAggregate(validationErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validateExtenders validates the configured extenders for the Scheduler
|
||||||
|
func validateExtenders(fldPath *field.Path, extenders []config.Extender) field.ErrorList {
|
||||||
|
allErrs := field.ErrorList{}
|
||||||
|
binders := 0
|
||||||
|
extenderManagedResources := sets.NewString()
|
||||||
|
for i, extender := range extenders {
|
||||||
|
path := fldPath.Index(i)
|
||||||
|
if len(extender.PrioritizeVerb) > 0 && extender.Weight <= 0 {
|
||||||
|
allErrs = append(allErrs, field.Invalid(path.Child("weight"),
|
||||||
|
extender.Weight, "must have a positive weight applied to it"))
|
||||||
|
}
|
||||||
|
if extender.BindVerb != "" {
|
||||||
|
binders++
|
||||||
|
}
|
||||||
|
for j, resource := range extender.ManagedResources {
|
||||||
|
managedResourcesPath := path.Child("managedResources").Index(j)
|
||||||
|
errs := validateExtendedResourceName(v1.ResourceName(resource.Name))
|
||||||
|
for _, err := range errs {
|
||||||
|
allErrs = append(allErrs, field.Invalid(managedResourcesPath.Child("name"),
|
||||||
|
resource.Name, fmt.Sprintf("%+v", err)))
|
||||||
|
}
|
||||||
|
if extenderManagedResources.Has(resource.Name) {
|
||||||
|
allErrs = append(allErrs, field.Invalid(managedResourcesPath.Child("name"),
|
||||||
|
resource.Name, "duplicate extender managed resource name"))
|
||||||
|
}
|
||||||
|
extenderManagedResources.Insert(resource.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if binders > 1 {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath, fmt.Sprintf("found %d extenders implementing bind", binders), "only one extender can implement bind"))
|
||||||
|
}
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
|
||||||
// validateCustomPriorities validates that:
|
// validateCustomPriorities validates that:
|
||||||
// 1. RequestedToCapacityRatioRedeclared custom priority cannot be declared multiple times,
|
// 1. RequestedToCapacityRatioRedeclared custom priority cannot be declared multiple times,
|
||||||
// 2. LabelPreference/ServiceAntiAffinity custom priorities can be declared multiple times,
|
// 2. LabelPreference/ServiceAntiAffinity custom priorities can be declared multiple times,
|
||||||
|
@ -87,6 +87,12 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Extenders: []config.Extender{
|
||||||
|
{
|
||||||
|
PrioritizeVerb: "prioritize",
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceNameNotSet := validConfig.DeepCopy()
|
resourceNameNotSet := validConfig.DeepCopy()
|
||||||
@ -126,6 +132,22 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) {
|
|||||||
oneEmptyQueueSort := validConfig.DeepCopy()
|
oneEmptyQueueSort := validConfig.DeepCopy()
|
||||||
oneEmptyQueueSort.Profiles[0].Plugins = nil
|
oneEmptyQueueSort.Profiles[0].Plugins = nil
|
||||||
|
|
||||||
|
extenderNegativeWeight := validConfig.DeepCopy()
|
||||||
|
extenderNegativeWeight.Extenders[0].Weight = -1
|
||||||
|
|
||||||
|
extenderDuplicateManagedResource := validConfig.DeepCopy()
|
||||||
|
extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{
|
||||||
|
{Name: "foo", IgnoredByScheduler: false},
|
||||||
|
{Name: "foo", IgnoredByScheduler: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
extenderDuplicateBind := validConfig.DeepCopy()
|
||||||
|
extenderDuplicateBind.Extenders[0].BindVerb = "foo"
|
||||||
|
extenderDuplicateBind.Extenders = append(extenderDuplicateBind.Extenders, config.Extender{
|
||||||
|
PrioritizeVerb: "prioritize",
|
||||||
|
BindVerb: "bar",
|
||||||
|
})
|
||||||
|
|
||||||
scenarios := map[string]struct {
|
scenarios := map[string]struct {
|
||||||
expectedToFail bool
|
expectedToFail bool
|
||||||
config *config.KubeSchedulerConfiguration
|
config *config.KubeSchedulerConfiguration
|
||||||
@ -178,6 +200,18 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) {
|
|||||||
expectedToFail: true,
|
expectedToFail: true,
|
||||||
config: oneEmptyQueueSort,
|
config: oneEmptyQueueSort,
|
||||||
},
|
},
|
||||||
|
"extender-negative-weight": {
|
||||||
|
expectedToFail: true,
|
||||||
|
config: extenderNegativeWeight,
|
||||||
|
},
|
||||||
|
"extender-duplicate-managed-resources": {
|
||||||
|
expectedToFail: true,
|
||||||
|
config: extenderDuplicateManagedResource,
|
||||||
|
},
|
||||||
|
"extender-duplicate-bind": {
|
||||||
|
expectedToFail: true,
|
||||||
|
config: extenderDuplicateBind,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, scenario := range scenarios {
|
for name, scenario := range scenarios {
|
||||||
@ -232,7 +266,7 @@ func TestValidatePolicy(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "invalid negative weight in policy extender config",
|
name: "invalid negative weight in policy extender config",
|
||||||
policy: config.Policy{Extenders: []config.Extender{{URLPrefix: "http://127.0.0.1:8081/extender", PrioritizeVerb: "prioritize", Weight: -2}}},
|
policy: config.Policy{Extenders: []config.Extender{{URLPrefix: "http://127.0.0.1:8081/extender", PrioritizeVerb: "prioritize", Weight: -2}}},
|
||||||
expected: errors.New("Priority for extender http://127.0.0.1:8081/extender should have a positive weight applied to it"),
|
expected: errors.New("extenders[0].weight: Invalid value: -2: must have a positive weight applied to it"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid filter verb and url prefix",
|
name: "valid filter verb and url prefix",
|
||||||
@ -251,7 +285,7 @@ func TestValidatePolicy(t *testing.T) {
|
|||||||
{URLPrefix: "http://127.0.0.1:8081/extender", BindVerb: "bind"},
|
{URLPrefix: "http://127.0.0.1:8081/extender", BindVerb: "bind"},
|
||||||
{URLPrefix: "http://127.0.0.1:8082/extender", BindVerb: "bind"},
|
{URLPrefix: "http://127.0.0.1:8082/extender", BindVerb: "bind"},
|
||||||
}},
|
}},
|
||||||
expected: errors.New("Only one extender can implement bind, found 2"),
|
expected: errors.New("extenders: Invalid value: \"found 2 extenders implementing bind\": only one extender can implement bind"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid duplicate extender resource name",
|
name: "invalid duplicate extender resource name",
|
||||||
@ -260,7 +294,7 @@ func TestValidatePolicy(t *testing.T) {
|
|||||||
{URLPrefix: "http://127.0.0.1:8081/extender", ManagedResources: []config.ExtenderManagedResource{{Name: "foo.com/bar"}}},
|
{URLPrefix: "http://127.0.0.1:8081/extender", ManagedResources: []config.ExtenderManagedResource{{Name: "foo.com/bar"}}},
|
||||||
{URLPrefix: "http://127.0.0.1:8082/extender", BindVerb: "bind", ManagedResources: []config.ExtenderManagedResource{{Name: "foo.com/bar"}}},
|
{URLPrefix: "http://127.0.0.1:8082/extender", BindVerb: "bind", ManagedResources: []config.ExtenderManagedResource{{Name: "foo.com/bar"}}},
|
||||||
}},
|
}},
|
||||||
expected: errors.New("Duplicate extender managed resource name foo.com/bar"),
|
expected: errors.New("extenders[1].managedResources[0].name: Invalid value: \"foo.com/bar\": duplicate extender managed resource name"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid extended resource name",
|
name: "invalid extended resource name",
|
||||||
@ -268,7 +302,7 @@ func TestValidatePolicy(t *testing.T) {
|
|||||||
Extenders: []config.Extender{
|
Extenders: []config.Extender{
|
||||||
{URLPrefix: "http://127.0.0.1:8081/extender", ManagedResources: []config.ExtenderManagedResource{{Name: "kubernetes.io/foo"}}},
|
{URLPrefix: "http://127.0.0.1:8081/extender", ManagedResources: []config.ExtenderManagedResource{{Name: "kubernetes.io/foo"}}},
|
||||||
}},
|
}},
|
||||||
expected: errors.New("kubernetes.io/foo is an invalid extended resource name"),
|
expected: errors.New("extenders[0].managedResources[0].name: Invalid value: \"kubernetes.io/foo\": kubernetes.io/foo is an invalid extended resource name"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid redeclared RequestedToCapacityRatio custom priority",
|
name: "invalid redeclared RequestedToCapacityRatio custom priority",
|
||||||
|
@ -112,6 +112,13 @@ func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfigurati
|
|||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if in.Extenders != nil {
|
||||||
|
in, out := &in.Extenders, &out.Extenders
|
||||||
|
*out = make([]Extender, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ type Configurator struct {
|
|||||||
profiles []schedulerapi.KubeSchedulerProfile
|
profiles []schedulerapi.KubeSchedulerProfile
|
||||||
registry framework.Registry
|
registry framework.Registry
|
||||||
nodeInfoSnapshot *internalcache.Snapshot
|
nodeInfoSnapshot *internalcache.Snapshot
|
||||||
|
extenders []schedulerapi.Extender
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Configurator) buildFramework(p schedulerapi.KubeSchedulerProfile) (framework.Framework, error) {
|
func (c *Configurator) buildFramework(p schedulerapi.KubeSchedulerProfile) (framework.Framework, error) {
|
||||||
@ -121,7 +122,49 @@ func (c *Configurator) buildFramework(p schedulerapi.KubeSchedulerProfile) (fram
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create a scheduler from a set of registered plugins.
|
// create a scheduler from a set of registered plugins.
|
||||||
func (c *Configurator) create(extenders []core.SchedulerExtender) (*Scheduler, error) {
|
func (c *Configurator) create() (*Scheduler, error) {
|
||||||
|
var extenders []core.SchedulerExtender
|
||||||
|
var ignoredExtendedResources []string
|
||||||
|
if len(c.extenders) != 0 {
|
||||||
|
var ignorableExtenders []core.SchedulerExtender
|
||||||
|
for ii := range c.extenders {
|
||||||
|
klog.V(2).Infof("Creating extender with config %+v", c.extenders[ii])
|
||||||
|
extender, err := core.NewHTTPExtender(&c.extenders[ii])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !extender.IsIgnorable() {
|
||||||
|
extenders = append(extenders, extender)
|
||||||
|
} else {
|
||||||
|
ignorableExtenders = append(ignorableExtenders, extender)
|
||||||
|
}
|
||||||
|
for _, r := range c.extenders[ii].ManagedResources {
|
||||||
|
if r.IgnoredByScheduler {
|
||||||
|
ignoredExtendedResources = append(ignoredExtendedResources, r.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// place ignorable extenders to the tail of extenders
|
||||||
|
extenders = append(extenders, ignorableExtenders...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are any extended resources found from the Extenders, append them to the pluginConfig for each profile.
|
||||||
|
// This should only have an effect on ComponentConfig v1alpha2, where it is possible to configure Extenders and
|
||||||
|
// plugin args (and in which case the extender ignored resources take precedence).
|
||||||
|
// For earlier versions, using both policy and custom plugin config is disallowed, so this should be the only
|
||||||
|
// plugin config for this plugin.
|
||||||
|
if len(ignoredExtendedResources) > 0 {
|
||||||
|
for i := range c.profiles {
|
||||||
|
prof := &c.profiles[i]
|
||||||
|
prof.PluginConfig = append(prof.PluginConfig,
|
||||||
|
frameworkplugins.NewPluginConfig(
|
||||||
|
noderesources.FitName,
|
||||||
|
noderesources.FitArgs{IgnoredResources: ignoredExtendedResources},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
profiles, err := profile.NewMap(c.profiles, c.buildFramework, c.recorderFactory)
|
profiles, err := profile.NewMap(c.profiles, c.buildFramework, c.recorderFactory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("initializing profiles: %v", err)
|
return nil, fmt.Errorf("initializing profiles: %v", err)
|
||||||
@ -186,11 +229,11 @@ func (c *Configurator) createFromProvider(providerName string) (*Scheduler, erro
|
|||||||
plugins.Apply(prof.Plugins)
|
plugins.Apply(prof.Plugins)
|
||||||
prof.Plugins = plugins
|
prof.Plugins = plugins
|
||||||
}
|
}
|
||||||
|
return c.create()
|
||||||
return c.create([]core.SchedulerExtender{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// createFromConfig creates a scheduler from the configuration file
|
// createFromConfig creates a scheduler from the configuration file
|
||||||
|
// Only reachable when using v1alpha1 component config
|
||||||
func (c *Configurator) createFromConfig(policy schedulerapi.Policy) (*Scheduler, error) {
|
func (c *Configurator) createFromConfig(policy schedulerapi.Policy) (*Scheduler, error) {
|
||||||
lr := frameworkplugins.NewLegacyRegistry()
|
lr := frameworkplugins.NewLegacyRegistry()
|
||||||
args := &frameworkplugins.ConfigProducerArgs{}
|
args := &frameworkplugins.ConfigProducerArgs{}
|
||||||
@ -228,33 +271,6 @@ func (c *Configurator) createFromConfig(policy schedulerapi.Policy) (*Scheduler,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var extenders []core.SchedulerExtender
|
|
||||||
if len(policy.Extenders) != 0 {
|
|
||||||
var ignorableExtenders []core.SchedulerExtender
|
|
||||||
var ignoredExtendedResources []string
|
|
||||||
for ii := range policy.Extenders {
|
|
||||||
klog.V(2).Infof("Creating extender with config %+v", policy.Extenders[ii])
|
|
||||||
extender, err := core.NewHTTPExtender(&policy.Extenders[ii])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !extender.IsIgnorable() {
|
|
||||||
extenders = append(extenders, extender)
|
|
||||||
} else {
|
|
||||||
ignorableExtenders = append(ignorableExtenders, extender)
|
|
||||||
}
|
|
||||||
for _, r := range policy.Extenders[ii].ManagedResources {
|
|
||||||
if r.IgnoredByScheduler {
|
|
||||||
ignoredExtendedResources = append(ignoredExtendedResources, r.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args.NodeResourcesFitArgs = &noderesources.FitArgs{
|
|
||||||
IgnoredResources: ignoredExtendedResources,
|
|
||||||
}
|
|
||||||
// place ignorable extenders to the tail of extenders
|
|
||||||
extenders = append(extenders, ignorableExtenders...)
|
|
||||||
}
|
|
||||||
// HardPodAffinitySymmetricWeight in the policy config takes precedence over
|
// HardPodAffinitySymmetricWeight in the policy config takes precedence over
|
||||||
// CLI configuration.
|
// CLI configuration.
|
||||||
if policy.HardPodAffinitySymmetricWeight != 0 {
|
if policy.HardPodAffinitySymmetricWeight != 0 {
|
||||||
@ -312,7 +328,7 @@ func (c *Configurator) createFromConfig(policy schedulerapi.Policy) (*Scheduler,
|
|||||||
prof.PluginConfig = pluginConfig
|
prof.PluginConfig = pluginConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.create(extenders)
|
return c.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPriorityConfigs returns priorities configuration: ones that will run as priorities and ones that will run
|
// getPriorityConfigs returns priorities configuration: ones that will run as priorities and ones that will run
|
||||||
|
@ -133,6 +133,7 @@ type schedulerOptions struct {
|
|||||||
// Contains out-of-tree plugins to be merged with the in-tree registry.
|
// Contains out-of-tree plugins to be merged with the in-tree registry.
|
||||||
frameworkOutOfTreeRegistry framework.Registry
|
frameworkOutOfTreeRegistry framework.Registry
|
||||||
profiles []schedulerapi.KubeSchedulerProfile
|
profiles []schedulerapi.KubeSchedulerProfile
|
||||||
|
extenders []schedulerapi.Extender
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option configures a Scheduler
|
// Option configures a Scheduler
|
||||||
@ -196,6 +197,13 @@ func WithPodMaxBackoffSeconds(podMaxBackoffSeconds int64) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithExtenders sets extenders for the Scheduler
|
||||||
|
func WithExtenders(e ...schedulerapi.Extender) Option {
|
||||||
|
return func(o *schedulerOptions) {
|
||||||
|
o.extenders = e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var defaultSchedulerOptions = schedulerOptions{
|
var defaultSchedulerOptions = schedulerOptions{
|
||||||
profiles: []schedulerapi.KubeSchedulerProfile{
|
profiles: []schedulerapi.KubeSchedulerProfile{
|
||||||
// Profiles' default plugins are set from the algorithm provider.
|
// Profiles' default plugins are set from the algorithm provider.
|
||||||
@ -264,6 +272,7 @@ func New(client clientset.Interface,
|
|||||||
profiles: append([]schedulerapi.KubeSchedulerProfile(nil), options.profiles...),
|
profiles: append([]schedulerapi.KubeSchedulerProfile(nil), options.profiles...),
|
||||||
registry: registry,
|
registry: registry,
|
||||||
nodeInfoSnapshot: snapshot,
|
nodeInfoSnapshot: snapshot,
|
||||||
|
extenders: options.extenders,
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics.Register()
|
metrics.Register()
|
||||||
@ -291,6 +300,10 @@ func New(client clientset.Interface,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Set extenders on the configurator now that we've decoded the policy
|
||||||
|
// In this case, c.extenders should be nil since we're using a policy (and therefore not componentconfig,
|
||||||
|
// which would have set extenders in the above instantiation of Configurator from CC options)
|
||||||
|
configurator.extenders = policy.Extenders
|
||||||
sc, err := configurator.createFromConfig(*policy)
|
sc, err := configurator.createFromConfig(*policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't create scheduler from policy: %v", err)
|
return nil, fmt.Errorf("couldn't create scheduler from policy: %v", err)
|
||||||
|
@ -198,6 +198,7 @@
|
|||||||
- k8s.io/apimachinery
|
- k8s.io/apimachinery
|
||||||
- k8s.io/component-base
|
- k8s.io/component-base
|
||||||
- k8s.io/klog
|
- k8s.io/klog
|
||||||
|
- k8s.io/kube-scheduler
|
||||||
- k8s.io/utils
|
- k8s.io/utils
|
||||||
|
|
||||||
- baseImportPath: "./vendor/k8s.io/kubelet/"
|
- baseImportPath: "./vendor/k8s.io/kubelet/"
|
||||||
|
@ -16,6 +16,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/component-base/config/v1alpha1:go_default_library",
|
"//staging/src/k8s.io/component-base/config/v1alpha1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/kube-scheduler/config/v1:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
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"
|
||||||
componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1"
|
componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1"
|
||||||
|
v1 "k8s.io/kube-scheduler/config/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -91,6 +92,11 @@ type KubeSchedulerConfiguration struct {
|
|||||||
// +listType=map
|
// +listType=map
|
||||||
// +listMapKey=schedulerName
|
// +listMapKey=schedulerName
|
||||||
Profiles []KubeSchedulerProfile `json:"profiles"`
|
Profiles []KubeSchedulerProfile `json:"profiles"`
|
||||||
|
|
||||||
|
// Extenders are the list of scheduler extenders, each holding the values of how to communicate
|
||||||
|
// with the extender. These extenders are shared by all scheduler profiles.
|
||||||
|
// +listType=set
|
||||||
|
Extenders []v1.Extender `json:"extenders"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubeSchedulerProfile is a scheduling profile.
|
// KubeSchedulerProfile is a scheduling profile.
|
||||||
|
@ -22,6 +22,7 @@ package v1alpha2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
|
v1 "k8s.io/kube-scheduler/config/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
@ -73,6 +74,13 @@ func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfigurati
|
|||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if in.Extenders != nil {
|
||||||
|
in, out := &in.Extenders, &out.Extenders
|
||||||
|
*out = make([]v1.Extender, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user