123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661 |
- /*
- Copyright 2019 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package plugins
- import (
- "encoding/json"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/util/sets"
- utilfeature "k8s.io/apiserver/pkg/util/feature"
- "k8s.io/klog"
- "k8s.io/kubernetes/pkg/features"
- "k8s.io/kubernetes/pkg/scheduler/apis/config"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpodtopologyspread"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodelabel"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodepreferavoidpods"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/serviceaffinity"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions"
- "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone"
- )
- const (
- // EqualPriority defines the name of prioritizer function that gives an equal weight of one to all nodes.
- EqualPriority = "EqualPriority"
- // MostRequestedPriority defines the name of prioritizer function that gives used nodes higher priority.
- MostRequestedPriority = "MostRequestedPriority"
- // RequestedToCapacityRatioPriority defines the name of RequestedToCapacityRatioPriority.
- RequestedToCapacityRatioPriority = "RequestedToCapacityRatioPriority"
- // SelectorSpreadPriority defines the name of prioritizer function that spreads pods by minimizing
- // the number of pods (belonging to the same service or replication controller) on the same node.
- SelectorSpreadPriority = "SelectorSpreadPriority"
- // ServiceSpreadingPriority is largely replaced by "SelectorSpreadPriority".
- ServiceSpreadingPriority = "ServiceSpreadingPriority"
- // InterPodAffinityPriority defines the name of prioritizer function that decides which pods should or
- // should not be placed in the same topological domain as some other pods.
- InterPodAffinityPriority = "InterPodAffinityPriority"
- // LeastRequestedPriority defines the name of prioritizer function that prioritize nodes by least
- // requested utilization.
- LeastRequestedPriority = "LeastRequestedPriority"
- // BalancedResourceAllocation defines the name of prioritizer function that prioritizes nodes
- // to help achieve balanced resource usage.
- BalancedResourceAllocation = "BalancedResourceAllocation"
- // NodePreferAvoidPodsPriority defines the name of prioritizer function that priorities nodes according to
- // the node annotation "scheduler.alpha.kubernetes.io/preferAvoidPods".
- NodePreferAvoidPodsPriority = "NodePreferAvoidPodsPriority"
- // NodeAffinityPriority defines the name of prioritizer function that prioritizes nodes which have labels
- // matching NodeAffinity.
- NodeAffinityPriority = "NodeAffinityPriority"
- // TaintTolerationPriority defines the name of prioritizer function that prioritizes nodes that marked
- // with taint which pod can tolerate.
- TaintTolerationPriority = "TaintTolerationPriority"
- // ImageLocalityPriority defines the name of prioritizer function that prioritizes nodes that have images
- // requested by the pod present.
- ImageLocalityPriority = "ImageLocalityPriority"
- // ResourceLimitsPriority defines the nodes of prioritizer function ResourceLimitsPriority.
- ResourceLimitsPriority = "ResourceLimitsPriority"
- // EvenPodsSpreadPriority defines the name of prioritizer function that prioritizes nodes
- // which have pods and labels matching the incoming pod's topologySpreadConstraints.
- EvenPodsSpreadPriority = "EvenPodsSpreadPriority"
- )
- const (
- // MatchInterPodAffinityPred defines the name of predicate MatchInterPodAffinity.
- MatchInterPodAffinityPred = "MatchInterPodAffinity"
- // CheckVolumeBindingPred defines the name of predicate CheckVolumeBinding.
- CheckVolumeBindingPred = "CheckVolumeBinding"
- // GeneralPred defines the name of predicate GeneralPredicates.
- GeneralPred = "GeneralPredicates"
- // HostNamePred defines the name of predicate HostName.
- HostNamePred = "HostName"
- // PodFitsHostPortsPred defines the name of predicate PodFitsHostPorts.
- PodFitsHostPortsPred = "PodFitsHostPorts"
- // MatchNodeSelectorPred defines the name of predicate MatchNodeSelector.
- MatchNodeSelectorPred = "MatchNodeSelector"
- // PodFitsResourcesPred defines the name of predicate PodFitsResources.
- PodFitsResourcesPred = "PodFitsResources"
- // NoDiskConflictPred defines the name of predicate NoDiskConflict.
- NoDiskConflictPred = "NoDiskConflict"
- // PodToleratesNodeTaintsPred defines the name of predicate PodToleratesNodeTaints.
- PodToleratesNodeTaintsPred = "PodToleratesNodeTaints"
- // CheckNodeUnschedulablePred defines the name of predicate CheckNodeUnschedulablePredicate.
- CheckNodeUnschedulablePred = "CheckNodeUnschedulable"
- // CheckNodeLabelPresencePred defines the name of predicate CheckNodeLabelPresence.
- CheckNodeLabelPresencePred = "CheckNodeLabelPresence"
- // CheckServiceAffinityPred defines the name of predicate checkServiceAffinity.
- CheckServiceAffinityPred = "CheckServiceAffinity"
- // MaxEBSVolumeCountPred defines the name of predicate MaxEBSVolumeCount.
- // DEPRECATED
- // All cloudprovider specific predicates are deprecated in favour of MaxCSIVolumeCountPred.
- MaxEBSVolumeCountPred = "MaxEBSVolumeCount"
- // MaxGCEPDVolumeCountPred defines the name of predicate MaxGCEPDVolumeCount.
- // DEPRECATED
- // All cloudprovider specific predicates are deprecated in favour of MaxCSIVolumeCountPred.
- MaxGCEPDVolumeCountPred = "MaxGCEPDVolumeCount"
- // MaxAzureDiskVolumeCountPred defines the name of predicate MaxAzureDiskVolumeCount.
- // DEPRECATED
- // All cloudprovider specific predicates are deprecated in favour of MaxCSIVolumeCountPred.
- MaxAzureDiskVolumeCountPred = "MaxAzureDiskVolumeCount"
- // MaxCinderVolumeCountPred defines the name of predicate MaxCinderDiskVolumeCount.
- // DEPRECATED
- // All cloudprovider specific predicates are deprecated in favour of MaxCSIVolumeCountPred.
- MaxCinderVolumeCountPred = "MaxCinderVolumeCount"
- // MaxCSIVolumeCountPred defines the predicate that decides how many CSI volumes should be attached.
- MaxCSIVolumeCountPred = "MaxCSIVolumeCountPred"
- // NoVolumeZoneConflictPred defines the name of predicate NoVolumeZoneConflict.
- NoVolumeZoneConflictPred = "NoVolumeZoneConflict"
- // EvenPodsSpreadPred defines the name of predicate EvenPodsSpread.
- EvenPodsSpreadPred = "EvenPodsSpread"
- )
- // PredicateOrdering returns the ordering of predicate execution.
- func PredicateOrdering() []string {
- return []string{CheckNodeUnschedulablePred,
- GeneralPred, HostNamePred, PodFitsHostPortsPred,
- MatchNodeSelectorPred, PodFitsResourcesPred, NoDiskConflictPred,
- PodToleratesNodeTaintsPred, CheckNodeLabelPresencePred,
- CheckServiceAffinityPred, MaxEBSVolumeCountPred, MaxGCEPDVolumeCountPred, MaxCSIVolumeCountPred,
- MaxAzureDiskVolumeCountPred, MaxCinderVolumeCountPred, CheckVolumeBindingPred, NoVolumeZoneConflictPred,
- EvenPodsSpreadPred, MatchInterPodAffinityPred}
- }
- // LegacyRegistry is used to store current state of registered predicates and priorities.
- type LegacyRegistry struct {
- // maps that associate predicates/priorities with framework plugin configurations.
- PredicateToConfigProducer map[string]ConfigProducer
- PriorityToConfigProducer map[string]ConfigProducer
- // predicates that will always be configured.
- MandatoryPredicates sets.String
- // predicates and priorities that will be used if either was set to nil in a
- // given v1.Policy configuration.
- DefaultPredicates sets.String
- DefaultPriorities map[string]int64
- }
- // ConfigProducerArgs contains arguments that are passed to the producer.
- // As we add more predicates/priorities to framework plugins mappings, more arguments
- // may be added here.
- type ConfigProducerArgs struct {
- // Weight used for priority functions.
- Weight int32
- // NodeLabelArgs is the args for the NodeLabel plugin.
- NodeLabelArgs *nodelabel.Args
- // RequestedToCapacityRatioArgs is the args for the RequestedToCapacityRatio plugin.
- RequestedToCapacityRatioArgs *noderesources.RequestedToCapacityRatioArgs
- // ServiceAffinityArgs is the args for the ServiceAffinity plugin.
- ServiceAffinityArgs *serviceaffinity.Args
- // NodeResourcesFitArgs is the args for the NodeResources fit filter.
- NodeResourcesFitArgs *noderesources.FitArgs
- // InterPodAffinityArgs is the args for InterPodAffinity plugin
- InterPodAffinityArgs *interpodaffinity.Args
- }
- // ConfigProducer returns the set of plugins and their configuration for a
- // predicate/priority given the args.
- type ConfigProducer func(args ConfigProducerArgs) (config.Plugins, []config.PluginConfig)
- // NewLegacyRegistry returns a legacy algorithm registry of predicates and priorities.
- func NewLegacyRegistry() *LegacyRegistry {
- registry := &LegacyRegistry{
- // MandatoryPredicates the set of keys for predicates that the scheduler will
- // be configured with all the time.
- MandatoryPredicates: sets.NewString(
- PodToleratesNodeTaintsPred,
- CheckNodeUnschedulablePred,
- ),
- // Used as the default set of predicates if Policy was specified, but predicates was nil.
- DefaultPredicates: sets.NewString(
- NoVolumeZoneConflictPred,
- MaxEBSVolumeCountPred,
- MaxGCEPDVolumeCountPred,
- MaxAzureDiskVolumeCountPred,
- MaxCSIVolumeCountPred,
- MatchInterPodAffinityPred,
- NoDiskConflictPred,
- GeneralPred,
- PodToleratesNodeTaintsPred,
- CheckVolumeBindingPred,
- CheckNodeUnschedulablePred,
- ),
- // Used as the default set of predicates if Policy was specified, but priorities was nil.
- DefaultPriorities: map[string]int64{
- SelectorSpreadPriority: 1,
- InterPodAffinityPriority: 1,
- LeastRequestedPriority: 1,
- BalancedResourceAllocation: 1,
- NodePreferAvoidPodsPriority: 10000,
- NodeAffinityPriority: 1,
- TaintTolerationPriority: 1,
- ImageLocalityPriority: 1,
- },
- PredicateToConfigProducer: make(map[string]ConfigProducer),
- PriorityToConfigProducer: make(map[string]ConfigProducer),
- }
- registry.registerPredicateConfigProducer(GeneralPred,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- // GeneralPredicate is a combination of predicates.
- plugins.Filter = appendToPluginSet(plugins.Filter, noderesources.FitName, nil)
- plugins.PreFilter = appendToPluginSet(plugins.PreFilter, noderesources.FitName, nil)
- if args.NodeResourcesFitArgs != nil {
- pluginConfig = append(pluginConfig, NewPluginConfig(noderesources.FitName, args.NodeResourcesFitArgs))
- }
- plugins.Filter = appendToPluginSet(plugins.Filter, nodename.Name, nil)
- plugins.Filter = appendToPluginSet(plugins.Filter, nodeports.Name, nil)
- plugins.PreFilter = appendToPluginSet(plugins.PreFilter, nodeports.Name, nil)
- plugins.Filter = appendToPluginSet(plugins.Filter, nodeaffinity.Name, nil)
- return
- })
- registry.registerPredicateConfigProducer(PodToleratesNodeTaintsPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, tainttoleration.Name, nil)
- return
- })
- registry.registerPredicateConfigProducer(PodFitsResourcesPred,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, noderesources.FitName, nil)
- plugins.PreFilter = appendToPluginSet(plugins.PreFilter, noderesources.FitName, nil)
- if args.NodeResourcesFitArgs != nil {
- pluginConfig = append(pluginConfig, NewPluginConfig(noderesources.FitName, args.NodeResourcesFitArgs))
- }
- return
- })
- registry.registerPredicateConfigProducer(HostNamePred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, nodename.Name, nil)
- return
- })
- registry.registerPredicateConfigProducer(PodFitsHostPortsPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, nodeports.Name, nil)
- plugins.PreFilter = appendToPluginSet(plugins.PreFilter, nodeports.Name, nil)
- return
- })
- registry.registerPredicateConfigProducer(MatchNodeSelectorPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, nodeaffinity.Name, nil)
- return
- })
- registry.registerPredicateConfigProducer(CheckNodeUnschedulablePred,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, nodeunschedulable.Name, nil)
- return
- })
- registry.registerPredicateConfigProducer(CheckVolumeBindingPred,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, volumebinding.Name, nil)
- return
- })
- registry.registerPredicateConfigProducer(NoDiskConflictPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, volumerestrictions.Name, nil)
- return
- })
- registry.registerPredicateConfigProducer(NoVolumeZoneConflictPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, volumezone.Name, nil)
- return
- })
- registry.registerPredicateConfigProducer(MaxCSIVolumeCountPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, nodevolumelimits.CSIName, nil)
- return
- })
- registry.registerPredicateConfigProducer(MaxEBSVolumeCountPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, nodevolumelimits.EBSName, nil)
- return
- })
- registry.registerPredicateConfigProducer(MaxGCEPDVolumeCountPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, nodevolumelimits.GCEPDName, nil)
- return
- })
- registry.registerPredicateConfigProducer(MaxAzureDiskVolumeCountPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, nodevolumelimits.AzureDiskName, nil)
- return
- })
- registry.registerPredicateConfigProducer(MaxCinderVolumeCountPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, nodevolumelimits.CinderName, nil)
- return
- })
- registry.registerPredicateConfigProducer(MatchInterPodAffinityPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, interpodaffinity.Name, nil)
- plugins.PreFilter = appendToPluginSet(plugins.PreFilter, interpodaffinity.Name, nil)
- return
- })
- registry.registerPredicateConfigProducer(CheckNodeLabelPresencePred,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, nodelabel.Name, nil)
- if args.NodeLabelArgs != nil {
- pluginConfig = append(pluginConfig, NewPluginConfig(nodelabel.Name, args.NodeLabelArgs))
- }
- return
- })
- registry.registerPredicateConfigProducer(CheckServiceAffinityPred,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Filter = appendToPluginSet(plugins.Filter, serviceaffinity.Name, nil)
- if args.ServiceAffinityArgs != nil {
- pluginConfig = append(pluginConfig, NewPluginConfig(serviceaffinity.Name, args.ServiceAffinityArgs))
- }
- plugins.PreFilter = appendToPluginSet(plugins.PreFilter, serviceaffinity.Name, nil)
- return
- })
- // Register Priorities.
- registry.registerPriorityConfigProducer(SelectorSpreadPriority,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Score = appendToPluginSet(plugins.Score, defaultpodtopologyspread.Name, &args.Weight)
- plugins.PreScore = appendToPluginSet(plugins.PreScore, defaultpodtopologyspread.Name, nil)
- return
- })
- registry.registerPriorityConfigProducer(TaintTolerationPriority,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.PreScore = appendToPluginSet(plugins.PreScore, tainttoleration.Name, nil)
- plugins.Score = appendToPluginSet(plugins.Score, tainttoleration.Name, &args.Weight)
- return
- })
- registry.registerPriorityConfigProducer(NodeAffinityPriority,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Score = appendToPluginSet(plugins.Score, nodeaffinity.Name, &args.Weight)
- return
- })
- registry.registerPriorityConfigProducer(ImageLocalityPriority,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Score = appendToPluginSet(plugins.Score, imagelocality.Name, &args.Weight)
- return
- })
- registry.registerPriorityConfigProducer(InterPodAffinityPriority,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.PreScore = appendToPluginSet(plugins.PreScore, interpodaffinity.Name, nil)
- plugins.Score = appendToPluginSet(plugins.Score, interpodaffinity.Name, &args.Weight)
- if args.InterPodAffinityArgs != nil {
- pluginConfig = append(pluginConfig, NewPluginConfig(interpodaffinity.Name, args.InterPodAffinityArgs))
- }
- return
- })
- registry.registerPriorityConfigProducer(NodePreferAvoidPodsPriority,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Score = appendToPluginSet(plugins.Score, nodepreferavoidpods.Name, &args.Weight)
- return
- })
- registry.registerPriorityConfigProducer(MostRequestedPriority,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Score = appendToPluginSet(plugins.Score, noderesources.MostAllocatedName, &args.Weight)
- return
- })
- registry.registerPriorityConfigProducer(BalancedResourceAllocation,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Score = appendToPluginSet(plugins.Score, noderesources.BalancedAllocationName, &args.Weight)
- return
- })
- registry.registerPriorityConfigProducer(LeastRequestedPriority,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Score = appendToPluginSet(plugins.Score, noderesources.LeastAllocatedName, &args.Weight)
- return
- })
- registry.registerPriorityConfigProducer(noderesources.RequestedToCapacityRatioName,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.Score = appendToPluginSet(plugins.Score, noderesources.RequestedToCapacityRatioName, &args.Weight)
- if args.RequestedToCapacityRatioArgs != nil {
- pluginConfig = append(pluginConfig, NewPluginConfig(noderesources.RequestedToCapacityRatioName, args.RequestedToCapacityRatioArgs))
- }
- return
- })
- registry.registerPriorityConfigProducer(nodelabel.Name,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- // If there are n LabelPreference priorities in the policy, the weight for the corresponding
- // score plugin is n*weight (note that the validation logic verifies that all LabelPreference
- // priorities specified in Policy have the same weight).
- weight := args.Weight * int32(len(args.NodeLabelArgs.PresentLabelsPreference)+len(args.NodeLabelArgs.AbsentLabelsPreference))
- plugins.Score = appendToPluginSet(plugins.Score, nodelabel.Name, &weight)
- if args.NodeLabelArgs != nil {
- pluginConfig = append(pluginConfig, NewPluginConfig(nodelabel.Name, args.NodeLabelArgs))
- }
- return
- })
- registry.registerPriorityConfigProducer(serviceaffinity.Name,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- // If there are n ServiceAffinity priorities in the policy, the weight for the corresponding
- // score plugin is n*weight (note that the validation logic verifies that all ServiceAffinity
- // priorities specified in Policy have the same weight).
- weight := args.Weight * int32(len(args.ServiceAffinityArgs.AntiAffinityLabelsPreference))
- plugins.Score = appendToPluginSet(plugins.Score, serviceaffinity.Name, &weight)
- if args.ServiceAffinityArgs != nil {
- pluginConfig = append(pluginConfig, NewPluginConfig(serviceaffinity.Name, args.ServiceAffinityArgs))
- }
- return
- })
- // The following two features are the last ones to be supported as predicate/priority.
- // Once they graduate to GA, there will be no more checking for featue gates here.
- // Only register EvenPodsSpread predicate & priority if the feature is enabled
- if utilfeature.DefaultFeatureGate.Enabled(features.EvenPodsSpread) {
- klog.Infof("Registering EvenPodsSpread predicate and priority function")
- registry.registerPredicateConfigProducer(EvenPodsSpreadPred,
- func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.PreFilter = appendToPluginSet(plugins.PreFilter, podtopologyspread.Name, nil)
- plugins.Filter = appendToPluginSet(plugins.Filter, podtopologyspread.Name, nil)
- return
- })
- registry.DefaultPredicates.Insert(EvenPodsSpreadPred)
- registry.registerPriorityConfigProducer(EvenPodsSpreadPriority,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.PreScore = appendToPluginSet(plugins.PreScore, podtopologyspread.Name, nil)
- plugins.Score = appendToPluginSet(plugins.Score, podtopologyspread.Name, &args.Weight)
- return
- })
- registry.DefaultPriorities[EvenPodsSpreadPriority] = 1
- }
- // Prioritizes nodes that satisfy pod's resource limits
- if utilfeature.DefaultFeatureGate.Enabled(features.ResourceLimitsPriorityFunction) {
- klog.Infof("Registering resourcelimits priority function")
- registry.registerPriorityConfigProducer(ResourceLimitsPriority,
- func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
- plugins.PreScore = appendToPluginSet(plugins.PreScore, noderesources.ResourceLimitsName, nil)
- plugins.Score = appendToPluginSet(plugins.Score, noderesources.ResourceLimitsName, &args.Weight)
- return
- })
- registry.DefaultPriorities[ResourceLimitsPriority] = 1
- }
- return registry
- }
- // registers a config producer for a predicate.
- func (lr *LegacyRegistry) registerPredicateConfigProducer(name string, producer ConfigProducer) {
- if _, exist := lr.PredicateToConfigProducer[name]; exist {
- klog.Fatalf("already registered %q", name)
- }
- lr.PredicateToConfigProducer[name] = producer
- }
- // registers a framework config producer for a priority.
- func (lr *LegacyRegistry) registerPriorityConfigProducer(name string, producer ConfigProducer) {
- if _, exist := lr.PriorityToConfigProducer[name]; exist {
- klog.Fatalf("already registered %q", name)
- }
- lr.PriorityToConfigProducer[name] = producer
- }
- func appendToPluginSet(set *config.PluginSet, name string, weight *int32) *config.PluginSet {
- if set == nil {
- set = &config.PluginSet{}
- }
- cfg := config.Plugin{Name: name}
- if weight != nil {
- cfg.Weight = *weight
- }
- set.Enabled = append(set.Enabled, cfg)
- return set
- }
- // NewPluginConfig builds a PluginConfig with the struct of args marshaled.
- // It panics if it fails to marshal.
- func NewPluginConfig(pluginName string, args interface{}) config.PluginConfig {
- encoding, err := json.Marshal(args)
- if err != nil {
- klog.Fatalf("failed to marshal %+v: %v", args, err)
- }
- return config.PluginConfig{
- Name: pluginName,
- Args: runtime.Unknown{Raw: encoding},
- }
- }
- // ProcessPredicatePolicy given a PredicatePolicy, return the plugin name implementing the predicate and update
- // the ConfigProducerArgs if necessary.
- func (lr *LegacyRegistry) ProcessPredicatePolicy(policy config.PredicatePolicy, pluginArgs *ConfigProducerArgs) string {
- validatePredicateOrDie(policy)
- predicateName := policy.Name
- if policy.Name == "PodFitsPorts" {
- // For compatibility reasons, "PodFitsPorts" as a key is still supported.
- predicateName = PodFitsHostPortsPred
- }
- if _, ok := lr.PredicateToConfigProducer[predicateName]; ok {
- // checking to see if a pre-defined predicate is requested
- klog.V(2).Infof("Predicate type %s already registered, reusing.", policy.Name)
- return predicateName
- }
- if policy.Argument == nil || (policy.Argument.ServiceAffinity == nil &&
- policy.Argument.LabelsPresence == nil) {
- klog.Fatalf("Invalid configuration: Predicate type not found for %q", policy.Name)
- }
- // generate the predicate function, if a custom type is requested
- if policy.Argument.ServiceAffinity != nil {
- // map LabelsPresence policy to ConfigProducerArgs that's used to configure the ServiceAffinity plugin.
- if pluginArgs.ServiceAffinityArgs == nil {
- pluginArgs.ServiceAffinityArgs = &serviceaffinity.Args{}
- }
- pluginArgs.ServiceAffinityArgs.AffinityLabels = append(pluginArgs.ServiceAffinityArgs.AffinityLabels, policy.Argument.ServiceAffinity.Labels...)
- // We use the ServiceAffinity predicate name for all ServiceAffinity custom predicates.
- // It may get called multiple times but we essentially only register one instance of ServiceAffinity predicate.
- // This name is then used to find the registered plugin and run the plugin instead of the predicate.
- predicateName = CheckServiceAffinityPred
- }
- if policy.Argument.LabelsPresence != nil {
- // Map LabelPresence policy to ConfigProducerArgs that's used to configure the NodeLabel plugin.
- if pluginArgs.NodeLabelArgs == nil {
- pluginArgs.NodeLabelArgs = &nodelabel.Args{}
- }
- if policy.Argument.LabelsPresence.Presence {
- pluginArgs.NodeLabelArgs.PresentLabels = append(pluginArgs.NodeLabelArgs.PresentLabels, policy.Argument.LabelsPresence.Labels...)
- } else {
- pluginArgs.NodeLabelArgs.AbsentLabels = append(pluginArgs.NodeLabelArgs.AbsentLabels, policy.Argument.LabelsPresence.Labels...)
- }
- // We use the CheckNodeLabelPresencePred predicate name for all kNodeLabel custom predicates.
- // It may get called multiple times but we essentially only register one instance of NodeLabel predicate.
- // This name is then used to find the registered plugin and run the plugin instead of the predicate.
- predicateName = CheckNodeLabelPresencePred
- }
- return predicateName
- }
- // ProcessPriorityPolicy given a PriorityPolicy, return the plugin name implementing the priority and update
- // the ConfigProducerArgs if necessary.
- func (lr *LegacyRegistry) ProcessPriorityPolicy(policy config.PriorityPolicy, configProducerArgs *ConfigProducerArgs) string {
- validatePriorityOrDie(policy)
- priorityName := policy.Name
- if policy.Name == ServiceSpreadingPriority {
- // For compatibility reasons, "ServiceSpreadingPriority" as a key is still supported.
- priorityName = SelectorSpreadPriority
- }
- if _, ok := lr.PriorityToConfigProducer[priorityName]; ok {
- klog.V(2).Infof("Priority type %s already registered, reusing.", priorityName)
- return priorityName
- }
- // generate the priority function, if a custom priority is requested
- if policy.Argument == nil ||
- (policy.Argument.ServiceAntiAffinity == nil &&
- policy.Argument.RequestedToCapacityRatioArguments == nil &&
- policy.Argument.LabelPreference == nil) {
- klog.Fatalf("Invalid configuration: Priority type not found for %q", priorityName)
- }
- if policy.Argument.ServiceAntiAffinity != nil {
- // We use the ServiceAffinity plugin name for all ServiceAffinity custom priorities.
- // It may get called multiple times but we essentially only register one instance of
- // ServiceAffinity priority.
- // This name is then used to find the registered plugin and run the plugin instead of the priority.
- priorityName = serviceaffinity.Name
- if configProducerArgs.ServiceAffinityArgs == nil {
- configProducerArgs.ServiceAffinityArgs = &serviceaffinity.Args{}
- }
- configProducerArgs.ServiceAffinityArgs.AntiAffinityLabelsPreference = append(
- configProducerArgs.ServiceAffinityArgs.AntiAffinityLabelsPreference,
- policy.Argument.ServiceAntiAffinity.Label,
- )
- }
- if policy.Argument.LabelPreference != nil {
- // We use the NodeLabel plugin name for all NodeLabel custom priorities.
- // It may get called multiple times but we essentially only register one instance of NodeLabel priority.
- // This name is then used to find the registered plugin and run the plugin instead of the priority.
- priorityName = nodelabel.Name
- if configProducerArgs.NodeLabelArgs == nil {
- configProducerArgs.NodeLabelArgs = &nodelabel.Args{}
- }
- if policy.Argument.LabelPreference.Presence {
- configProducerArgs.NodeLabelArgs.PresentLabelsPreference = append(
- configProducerArgs.NodeLabelArgs.PresentLabelsPreference,
- policy.Argument.LabelPreference.Label,
- )
- } else {
- configProducerArgs.NodeLabelArgs.AbsentLabelsPreference = append(
- configProducerArgs.NodeLabelArgs.AbsentLabelsPreference,
- policy.Argument.LabelPreference.Label,
- )
- }
- }
- if policy.Argument.RequestedToCapacityRatioArguments != nil {
- configProducerArgs.RequestedToCapacityRatioArgs = &noderesources.RequestedToCapacityRatioArgs{
- RequestedToCapacityRatioArguments: *policy.Argument.RequestedToCapacityRatioArguments,
- }
- // We do not allow specifying the name for custom plugins, see #83472
- priorityName = noderesources.RequestedToCapacityRatioName
- }
- return priorityName
- }
- func validatePredicateOrDie(predicate config.PredicatePolicy) {
- if predicate.Argument != nil {
- numArgs := 0
- if predicate.Argument.ServiceAffinity != nil {
- numArgs++
- }
- if predicate.Argument.LabelsPresence != nil {
- numArgs++
- }
- if numArgs != 1 {
- klog.Fatalf("Exactly 1 predicate argument is required, numArgs: %v, Predicate: %s", numArgs, predicate.Name)
- }
- }
- }
- func validatePriorityOrDie(priority config.PriorityPolicy) {
- if priority.Argument != nil {
- numArgs := 0
- if priority.Argument.ServiceAntiAffinity != nil {
- numArgs++
- }
- if priority.Argument.LabelPreference != nil {
- numArgs++
- }
- if priority.Argument.RequestedToCapacityRatioArguments != nil {
- numArgs++
- }
- if numArgs != 1 {
- klog.Fatalf("Exactly 1 priority argument is required, numArgs: %v, Priority: %s", numArgs, priority.Name)
- }
- }
- }
|