-
Notifications
You must be signed in to change notification settings - Fork 38.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[migration] Mapping Layer - 2. Convert predicates/priorities configurations to a framework plugin one. #83099
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ahg-g The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/assign @Huang-Wei @alculquicondor |
I still need to add tests for this, but just to give an idea how this whole mapping layer will look like. |
pkg/scheduler/factory/factory.go
Outdated
@@ -395,7 +395,17 @@ func (c *Configurator) CreateFromKeys(predicateKeys, priorityKeys sets.String, e | |||
return nil, err | |||
} | |||
|
|||
framework, err := framework.NewFramework(c.registry, c.plugins, c.pluginConfig) | |||
// Combine all framework configurations. | |||
// TODO(ahg-g): handle duplicate and disabled plugins. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the consequence of not handling these for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate will be handled by the framework instantiation logic, disabled plugins does not apply yet since we don't have default plugins yet.
27ccba3
to
c8c669c
Compare
d266c3d
to
98b9abb
Compare
3bd65b3
to
2e75dea
Compare
pkg/scheduler/factory/factory.go
Outdated
@@ -516,7 +598,7 @@ func (c *Configurator) getPluginArgs() (*PluginFactoryArgs, error) { | |||
StorageClassInfo: &predicates.CachedStorageClassInfo{StorageClassLister: c.storageClassLister}, | |||
VolumeBinder: c.volumeBinder, | |||
HardPodAffinitySymmetricWeight: c.hardPodAffinitySymmetricWeight, | |||
}, nil | |||
}, &plugins.ConfigProducerArgs{}, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe let's add this once we figure that it is needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is fine, we will add HardPodAffinitySymmetricWeight pretty soon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. However, they can be separate methods. Also, there seems to be no need to return an error :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They can, but I don't think they should because both will be configuring very similar parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed the err, didn't see it before!
// NewConfigProducerRegistry creates a new producer registry. | ||
func NewConfigProducerRegistry() *ConfigProducerRegistry { | ||
// NewDefaultConfigProducerRegistry creates a new producer registry. | ||
func NewDefaultConfigProducerRegistry() *ConfigProducerRegistry { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look like a Default so far
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will add the registration of the various plugins in this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, that's what I figured. However, our tests are expecting a clean Registry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modified factory_test.go to start from an empty registry
@@ -49,6 +49,8 @@ type framework struct { | |||
postBindPlugins []PostBindPlugin | |||
unreservePlugins []UnreservePlugin | |||
permitPlugins []PermitPlugin | |||
plugins *config.Plugins |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of adding these here (and never GC the config), they should go in factory.Config
. They are only useful for factory_test.go
anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't we planning to remove factory.Config in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that scenario, we shouldn't be testing the Config, but rather that the proper plugins were instantiated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that practically means we need to write a function for the framework to re-create the config from the plugin arrays, I don't want to do that :)
I feel factory.Config already has too many arguments, adding more just makes it more cluttered and confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel factory.Config already has too many arguments, adding more just makes it more cluttered and confusing.
I agree. My only point is that configuration should only exist at startup and be collected after that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think naming is less of a problem than having living objects that we do not care about at runtime.
For now, this is my suggestion:
In Config
we have a struct named Framework
that stores the parameters to NewFramework
. That is implicitly a configuration because it lives inside the Config
struct. The instantiation of the framework itself is moved to scheduler.NewFromConfig
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think having the Config here is a big problem, they are implementations details of the framework anyways. However, I feel a bit hesitant on adding the GetConfiguration
to the Framework interface, which could open the door for changing the config after framework initialization. Having said that, I don't think it's too big an issue.
One way to get rid of this is to test the unexported factory
method of getPriorityConfigs
and getPredicateConfigs
, but I prefer to test exported methods.
Ideally we can avoid the new GetConfiguration
interface method but I don't hold strongly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can't do the instantiation there because the framework is needed when making generic scheduler. I will move those to Config though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sg. FYI @ahmad-diaa for when you work on this refactoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
/test pull-kubernetes-integration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
PriorityToConfigProducer: make(map[string]frameworkplugins.ConfigProducer), | ||
} | ||
configProducerRegistry.RegisterPredicate(predicateOneName, | ||
func(_ frameworkplugins.ConfigProducerArgs) (config.Plugins, []config.PluginConfig) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: it seems that the you can define a generic producer func and reuse it for predicate one, two, etc.
@@ -49,6 +49,8 @@ type framework struct { | |||
postBindPlugins []PostBindPlugin | |||
unreservePlugins []UnreservePlugin | |||
permitPlugins []PermitPlugin | |||
plugins *config.Plugins |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think having the Config here is a big problem, they are implementations details of the framework anyways. However, I feel a bit hesitant on adding the GetConfiguration
to the Framework interface, which could open the door for changing the config after framework initialization. Having said that, I don't think it's too big an issue.
One way to get rid of this is to test the unexported factory
method of getPriorityConfigs
and getPredicateConfigs
, but I prefer to test exported methods.
Ideally we can avoid the new GetConfiguration
interface method but I don't hold strongly.
// It is used by the scheduler and other components, such as k8s.io/autoscaler/cluster-autoscaler. | ||
func (c *Configurator) GetPredicates(predicateKeys sets.String) (map[string]predicates.FitPredicate, error) { | ||
pluginArgs, err := c.getPluginArgs() | ||
func (c *Configurator) getPredicateConfigs(predicateKeys sets.String) (map[string]predicates.FitPredicate, *config.Plugins, []config.PluginConfig, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic to produce the eventual algorithm vs. framework plugin output has some subtleties. It depends on a few things - algorithm keys in policy, algorithm to plugin config producer registry, ordered list of predicates, etc. I suggest that we add some high level comments here to explain this. Same for the getPriorityConfig
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
/hold for squash and remaining comments. @liu-cong, careful with LGTMing an approver. The PR could get merged accidentally before we actually intend to. Update: Oops, it looks like Abdullah had already hold this :) |
True, I already put a hold when the PR was created. |
An approver doesn't need an |
no, but need an lgtm from a reviewer I believe. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
Feel free to squash now.
@@ -771,9 +771,9 @@ func TestCreateWithFrameworkPlugins(t *testing.T) { | |||
t.Errorf("unexpected priorities diff (-want, +got): %s", diff) | |||
} | |||
|
|||
gotPlugins, _ := c.Framework.GetConfiguration() | |||
gotPlugins := c.Plugins |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: variable not needed
c6ae0a9
to
87ad919
Compare
done. |
@@ -167,6 +168,10 @@ func (*fakeFramework) NodeInfoSnapshot() *schedulernodeinfo.Snapshot { | |||
return nil | |||
} | |||
|
|||
func (*fakeFramework) GetConfiguration() (*config.Plugins, []config.PluginConfig) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leftover
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
87ad919
to
6120fe9
Compare
/lgtm |
/hold cancel |
What type of PR is this?
/sig scheduling
/kind feature
/priority important-soon
/hold
What this PR does / why we need it:
To facilitate predicates/priorities migration to the framework. This PR converts configured predicates/priorities into their equivalent framework plugins for the one that actually have a mapping.
This PR is based on the changes in #83080
Which issue(s) this PR fixes:
Part of #82708
Special notes for your reviewer:
Does this PR introduce a user-facing change?: