Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
32523f8a
Commit
32523f8a
authored
Mar 02, 2015
by
David Oppenheimer
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4674 from abhgupta/abhgupta-dev
Configuring scheduler via json configuration file
parents
f278fbab
5e096fed
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
548 additions
and
73 deletions
+548
-73
generic_scheduler.go
pkg/scheduler/generic_scheduler.go
+7
-0
server.go
plugin/cmd/kube-scheduler/app/server.go
+26
-0
affinity.go
plugin/pkg/scheduler/algorithmprovider/affinity/affinity.go
+0
-55
plugins.go
plugin/pkg/scheduler/algorithmprovider/plugins.go
+0
-1
plugins_test.go
plugin/pkg/scheduler/algorithmprovider/plugins_test.go
+0
-2
latest.go
plugin/pkg/scheduler/api/latest/latest.go
+38
-0
register.go
plugin/pkg/scheduler/api/register.go
+32
-0
types.go
plugin/pkg/scheduler/api/types.go
+103
-0
register.go
plugin/pkg/scheduler/api/v1/register.go
+33
-0
types.go
plugin/pkg/scheduler/api/v1/types.go
+103
-0
factory.go
plugin/pkg/scheduler/factory/factory.go
+28
-8
factory_test.go
plugin/pkg/scheduler/factory/factory_test.go
+86
-0
plugins.go
plugin/pkg/scheduler/factory/plugins.go
+92
-7
No files found.
pkg/scheduler/generic_scheduler.go
View file @
32523f8a
...
...
@@ -135,6 +135,13 @@ func findNodesThatFit(pod api.Pod, podLister PodLister, predicates map[string]Fi
// All scores are finally combined (added) to get the total weighted scores of all minions
func
prioritizeNodes
(
pod
api
.
Pod
,
podLister
PodLister
,
priorityConfigs
[]
PriorityConfig
,
minionLister
MinionLister
)
(
HostPriorityList
,
error
)
{
result
:=
HostPriorityList
{}
// If no priority configs are provided, then the EqualPriority function is applied
// This is required to generate the priority list in the required format
if
len
(
priorityConfigs
)
==
0
{
return
EqualPriority
(
pod
,
podLister
,
minionLister
)
}
combinedScores
:=
map
[
string
]
int
{}
for
_
,
priorityConfig
:=
range
priorityConfigs
{
weight
:=
priorityConfig
.
Weight
...
...
plugin/cmd/kube-scheduler/app/server.go
View file @
32523f8a
...
...
@@ -18,8 +18,11 @@ limitations under the License.
package
app
import
(
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
"strconv"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
...
...
@@ -30,6 +33,8 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler"
_
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/algorithmprovider"
schedulerapi
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api"
latestschedulerapi
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory"
"github.com/golang/glog"
...
...
@@ -42,6 +47,7 @@ type SchedulerServer struct {
Address
util
.
IP
ClientConfig
client
.
Config
AlgorithmProvider
string
PolicyConfigFile
string
}
// NewSchedulerServer creates a new SchedulerServer with default parameters
...
...
@@ -60,6 +66,7 @@ func (s *SchedulerServer) AddFlags(fs *pflag.FlagSet) {
fs
.
Var
(
&
s
.
Address
,
"address"
,
"The IP address to serve on (set to 0.0.0.0 for all interfaces)"
)
client
.
BindClientConfigFlags
(
fs
,
&
s
.
ClientConfig
)
fs
.
StringVar
(
&
s
.
AlgorithmProvider
,
"algorithm_provider"
,
s
.
AlgorithmProvider
,
"The scheduling algorithm provider to use"
)
fs
.
StringVar
(
&
s
.
PolicyConfigFile
,
"policy_config_file"
,
s
.
PolicyConfigFile
,
"File with scheduler policy configuration"
)
}
// Run runs the specified SchedulerServer. This should never exit.
...
...
@@ -78,6 +85,7 @@ func (s *SchedulerServer) Run(_ []string) error {
if
err
!=
nil
{
glog
.
Fatalf
(
"Failed to create scheduler configuration: %v"
,
err
)
}
sched
:=
scheduler
.
New
(
config
)
sched
.
Run
()
...
...
@@ -85,10 +93,28 @@ func (s *SchedulerServer) Run(_ []string) error {
}
func
(
s
*
SchedulerServer
)
createConfig
(
configFactory
*
factory
.
ConfigFactory
)
(
*
scheduler
.
Config
,
error
)
{
var
policy
schedulerapi
.
Policy
var
configData
[]
byte
if
_
,
err
:=
os
.
Stat
(
s
.
PolicyConfigFile
);
err
==
nil
{
configData
,
err
=
ioutil
.
ReadFile
(
s
.
PolicyConfigFile
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Unable to read policy config: %v"
,
err
)
}
err
=
latestschedulerapi
.
Codec
.
DecodeInto
(
configData
,
&
policy
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Invalid configuration: %v"
,
err
)
}
return
configFactory
.
CreateFromConfig
(
policy
)
}
// if the config file isn't provided, use the specified (or default) provider
// check of algorithm provider is registered and fail fast
_
,
err
:=
factory
.
GetAlgorithmProvider
(
s
.
AlgorithmProvider
)
if
err
!=
nil
{
return
nil
,
err
}
return
configFactory
.
CreateFromProvider
(
s
.
AlgorithmProvider
)
}
plugin/pkg/scheduler/algorithmprovider/affinity/affinity.go
deleted
100644 → 0
View file @
f278fbab
/*
Copyright 2014 Google Inc. All rights reserved.
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.
*/
// This algorithm provider has predicates and priorities related to affinity/anti-affinity for the scheduler.
package
affinity
import
(
algorithm
"github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory"
)
const
AffinityProvider
string
=
"AffinityProvider"
func
init
()
{
factory
.
RegisterAlgorithmProvider
(
AffinityProvider
,
affinityPredicates
(),
affinityPriorities
())
}
func
affinityPredicates
()
util
.
StringSet
{
return
util
.
NewStringSet
(
"HostName"
,
"MatchNodeSelector"
,
"PodFitsPorts"
,
"PodFitsResources"
,
"NoDiskConflict"
,
// Ensures that all pods within the same service are hosted on minions within the same region as defined by the "region" label
factory
.
RegisterFitPredicate
(
"ServiceAffinity"
,
algorithm
.
NewServiceAffinityPredicate
(
factory
.
PodLister
,
factory
.
ServiceLister
,
factory
.
MinionLister
,
[]
string
{
"region"
})),
// Fit is defined based on the presence of the "region" label on a minion, regardless of value.
factory
.
RegisterFitPredicate
(
"NodeLabelPredicate"
,
algorithm
.
NewNodeLabelPredicate
(
factory
.
MinionLister
,
[]
string
{
"region"
},
true
)),
)
}
func
affinityPriorities
()
util
.
StringSet
{
return
util
.
NewStringSet
(
"LeastRequestedPriority"
,
"ServiceSpreadingPriority"
,
// spreads pods belonging to the same service across minions in different zones
factory
.
RegisterPriorityFunction
(
"ZoneSpreadingPriority"
,
algorithm
.
NewServiceAntiAffinityPriority
(
factory
.
ServiceLister
,
"zone"
),
2
),
// Prioritize nodes based on the presence of the "zone" label on a minion, regardless of value.
factory
.
RegisterPriorityFunction
(
"NodeLabelPriority"
,
algorithm
.
NewNodeLabelPriority
(
"zone"
,
true
),
1
),
)
}
plugin/pkg/scheduler/algorithmprovider/plugins.go
View file @
32523f8a
...
...
@@ -18,6 +18,5 @@ limitations under the License.
package
algorithmprovider
import
(
_
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/algorithmprovider/affinity"
_
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults"
)
plugin/pkg/scheduler/algorithmprovider/plugins_test.go
View file @
32523f8a
...
...
@@ -19,14 +19,12 @@ package algorithmprovider
import
(
"testing"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/algorithmprovider/affinity"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory"
)
var
(
algorithmProviderNames
=
[]
string
{
factory
.
DefaultProvider
,
affinity
.
AffinityProvider
,
}
)
...
...
plugin/pkg/scheduler/api/latest/latest.go
0 → 100644
View file @
32523f8a
/*
Copyright 2014 Google Inc. All rights reserved.
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
latest
import
(
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api/v1"
)
// Version is the string that represents the current external default version.
const
Version
=
"v1"
// OldestVersion is the string that represents the oldest server version supported.
const
OldestVersion
=
"v1"
// Versions is the list of versions that are recognized in code. The order provided
// may be assumed to be least feature rich to most feature rich, and clients may
// choose to prefer the latter items in the list over the former items when presented
// with a set of versions to choose.
var
Versions
=
[]
string
{
"v1"
}
// Codec is the default codec for serializing input that should use
// the latest supported version.
// This codec can decode any object that Kubernetes is aware of.
var
Codec
=
v1
.
Codec
plugin/pkg/scheduler/api/register.go
0 → 100644
View file @
32523f8a
/*
Copyright 2014 Google Inc. All rights reserved.
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
api
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
var
Scheme
=
runtime
.
NewScheme
()
func
init
()
{
Scheme
.
AddKnownTypes
(
""
,
&
Policy
{},
)
}
func
(
*
Policy
)
IsAnAPIObject
()
{}
plugin/pkg/scheduler/api/types.go
0 → 100644
View file @
32523f8a
/*
Copyright 2014 Google Inc. All rights reserved.
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
api
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
)
type
Policy
struct
{
api
.
TypeMeta
`json:",inline"`
// Holds the information to configure the fit predicate functions
Predicates
[]
PredicatePolicy
`json:"predicates"`
// Holds the information to configure the priority functions
Priorities
[]
PriorityPolicy
`json:"priorities"`
}
type
PredicatePolicy
struct
{
// Identifier of the predicate policy
// For a custom predicate, the name can be user-defined
// For the Kubernetes provided predicates, the name is the identifier of the pre-defined predicate
Name
string
`json:"name"`
// Holds the parameters to configure the given predicate
Argument
*
PredicateArgument
`json:"argument"`
}
type
PriorityPolicy
struct
{
// Identifier of the priority policy
// For a custom priority, the name can be user-defined
// For the Kubernetes provided priority functions, the name is the identifier of the pre-defined priority function
Name
string
`json:"name"`
// The numeric multiplier for the minion scores that the priority function generates
Weight
int
`json:"weight"`
// Holds the parameters to configure the given priority function
Argument
*
PriorityArgument
`json:"argument"`
}
// Represents the arguments that the different types of predicates take
// Only one of its members may be specified
type
PredicateArgument
struct
{
// The predicate that provides affinity for pods belonging to a service
// It uses a label to identify minions that belong to the same "group"
ServiceAffinity
*
ServiceAffinity
`json:"serviceAffinity"`
// The predicate that checks whether a particular minion has a certain label
// defined or not, regardless of value
LabelsPresence
*
LabelsPresence
`json:"labelsPresence"`
}
// Represents the arguments that the different types of priorities take.
// Only one of its members may be specified
type
PriorityArgument
struct
{
// The priority function that ensures a good spread (anti-affinity) for pods belonging to a service
// It uses a label to identify minions that belong to the same "group"
ServiceAntiAffinity
*
ServiceAntiAffinity
`json:"serviceAntiAffinity"`
// The priority function that checks whether a particular minion has a certain label
// defined or not, regardless of value
LabelPreference
*
LabelPreference
`json:"labelPreference"`
}
// Holds the parameters that are used to configure the corresponding predicate
type
ServiceAffinity
struct
{
// The list of labels that identify minion "groups"
// All of the labels should match for the minion to be considered a fit for hosting the pod
Labels
[]
string
`json:"labels"`
}
// Holds the parameters that are used to configure the corresponding predicate
type
LabelsPresence
struct
{
// The list of labels that identify minion "groups"
// All of the labels should be either present (or absent) for the minion to be considered a fit for hosting the pod
Labels
[]
string
`json:"labels"`
// The boolean flag that indicates whether the labels should be present or absent from the minion
Presence
bool
`json:"presence"`
}
// Holds the parameters that are used to configure the corresponding priority function
type
ServiceAntiAffinity
struct
{
// Used to identify minion "groups"
Label
string
`json:"label"`
}
// Holds the parameters that are used to configure the corresponding priority function
type
LabelPreference
struct
{
// Used to identify minion "groups"
Label
string
`json:"label"`
// This is a boolean flag
// If true, higher priority is given to minions that have the label
// If false, higher priority is given to minions that do not have the label
Presence
bool
`json:"presence"`
}
plugin/pkg/scheduler/api/v1/register.go
0 → 100644
View file @
32523f8a
/*
Copyright 2014 Google Inc. All rights reserved.
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
v1
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api"
)
// Codec encodes internal objects to the v1 scheme
var
Codec
=
runtime
.
CodecFor
(
api
.
Scheme
,
"v1"
)
func
init
()
{
api
.
Scheme
.
AddKnownTypes
(
"v1"
,
&
Policy
{},
)
}
func
(
*
Policy
)
IsAnAPIObject
()
{}
plugin/pkg/scheduler/api/v1/types.go
0 → 100644
View file @
32523f8a
/*
Copyright 2014 Google Inc. All rights reserved.
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
v1
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
)
type
Policy
struct
{
v1beta3
.
TypeMeta
`json:",inline"`
// Holds the information to configure the fit predicate functions
Predicates
[]
PredicatePolicy
`json:"predicates"`
// Holds the information to configure the priority functions
Priorities
[]
PriorityPolicy
`json:"priorities"`
}
type
PredicatePolicy
struct
{
// Identifier of the predicate policy
// For a custom predicate, the name can be user-defined
// For the Kubernetes provided predicates, the name is the identifier of the pre-defined predicate
Name
string
`json:"name"`
// Holds the parameters to configure the given predicate
Argument
*
PredicateArgument
`json:"argument"`
}
type
PriorityPolicy
struct
{
// Identifier of the priority policy
// For a custom priority, the name can be user-defined
// For the Kubernetes provided priority functions, the name is the identifier of the pre-defined priority function
Name
string
`json:"name"`
// The numeric multiplier for the minion scores that the priority function generates
Weight
int
`json:"weight"`
// Holds the parameters to configure the given priority function
Argument
*
PriorityArgument
`json:"argument"`
}
// Represents the arguments that the different types of predicates take
// Only one of its members may be specified
type
PredicateArgument
struct
{
// The predicate that provides affinity for pods belonging to a service
// It uses a label to identify minions that belong to the same "group"
ServiceAffinity
*
ServiceAffinity
`json:"serviceAffinity"`
// The predicate that checks whether a particular minion has a certain label
// defined or not, regardless of value
LabelsPresence
*
LabelsPresence
`json:"labelsPresence"`
}
// Represents the arguments that the different types of priorities take.
// Only one of its members may be specified
type
PriorityArgument
struct
{
// The priority function that ensures a good spread (anti-affinity) for pods belonging to a service
// It uses a label to identify minions that belong to the same "group"
ServiceAntiAffinity
*
ServiceAntiAffinity
`json:"serviceAntiAffinity"`
// The priority function that checks whether a particular minion has a certain label
// defined or not, regardless of value
LabelPreference
*
LabelPreference
`json:"labelPreference"`
}
// Holds the parameters that are used to configure the corresponding predicate
type
ServiceAffinity
struct
{
// The list of labels that identify minion "groups"
// All of the labels should match for the minion to be considered a fit for hosting the pod
Labels
[]
string
`json:"labels"`
}
// Holds the parameters that are used to configure the corresponding predicate
type
LabelsPresence
struct
{
// The list of labels that identify minion "groups"
// All of the labels should be either present (or absent) for the minion to be considered a fit for hosting the pod
Labels
[]
string
`json:"labels"`
// The boolean flag that indicates whether the labels should be present or absent from the minion
Presence
bool
`json:"presence"`
}
// Holds the parameters that are used to configure the corresponding priority function
type
ServiceAntiAffinity
struct
{
// Used to identify minion "groups"
Label
string
`json:"label"`
}
// Holds the parameters that are used to configure the corresponding priority function
type
LabelPreference
struct
{
// Used to identify minion "groups"
Label
string
`json:"label"`
// This is a boolean flag
// If true, higher priority is given to minions that have the label
// If false, higher priority is given to minions that do not have the label
Presence
bool
`json:"presence"`
}
plugin/pkg/scheduler/factory/factory.go
View file @
32523f8a
...
...
@@ -30,6 +30,7 @@ import (
algorithm
"github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler"
schedulerapi
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api"
"github.com/golang/glog"
)
...
...
@@ -53,7 +54,7 @@ type ConfigFactory struct {
ServiceLister
*
cache
.
StoreToServiceLister
}
//
NewConfigFactory i
nitializes the factory.
//
I
nitializes the factory.
func
NewConfigFactory
(
client
*
client
.
Client
)
*
ConfigFactory
{
return
&
ConfigFactory
{
Client
:
client
,
...
...
@@ -69,7 +70,7 @@ func (f *ConfigFactory) Create() (*scheduler.Config, error) {
return
f
.
CreateFromProvider
(
DefaultProvider
)
}
// Create
FromProvider create
s a scheduler from the name of a registered algorithm provider.
// Creates a scheduler from the name of a registered algorithm provider.
func
(
f
*
ConfigFactory
)
CreateFromProvider
(
providerName
string
)
(
*
scheduler
.
Config
,
error
)
{
glog
.
V
(
2
)
.
Infof
(
"creating scheduler from algorithm provider '%v'"
,
providerName
)
provider
,
err
:=
GetAlgorithmProvider
(
providerName
)
...
...
@@ -80,7 +81,26 @@ func (f *ConfigFactory) CreateFromProvider(providerName string) (*scheduler.Conf
return
f
.
CreateFromKeys
(
provider
.
FitPredicateKeys
,
provider
.
PriorityFunctionKeys
)
}
// CreateFromKeys creates a scheduler from a set of registered fit predicate keys and priority keys.
// Creates a scheduler from the configuration file
func
(
f
*
ConfigFactory
)
CreateFromConfig
(
policy
schedulerapi
.
Policy
)
(
*
scheduler
.
Config
,
error
)
{
glog
.
V
(
2
)
.
Infof
(
"creating scheduler from configuration: %v"
,
policy
)
predicateKeys
:=
util
.
NewStringSet
()
for
_
,
predicate
:=
range
policy
.
Predicates
{
glog
.
V
(
2
)
.
Infof
(
"Registering predicate: %s"
,
predicate
.
Name
)
predicateKeys
.
Insert
(
RegisterCustomFitPredicate
(
predicate
))
}
priorityKeys
:=
util
.
NewStringSet
()
for
_
,
priority
:=
range
policy
.
Priorities
{
glog
.
V
(
2
)
.
Infof
(
"Registering priority: %s"
,
priority
.
Name
)
priorityKeys
.
Insert
(
RegisterCustomPriorityFunction
(
priority
))
}
return
f
.
CreateFromKeys
(
predicateKeys
,
priorityKeys
)
}
// Creates a scheduler from a set of registered fit predicate keys and priority keys.
func
(
f
*
ConfigFactory
)
CreateFromKeys
(
predicateKeys
,
priorityKeys
util
.
StringSet
)
(
*
scheduler
.
Config
,
error
)
{
glog
.
V
(
2
)
.
Infof
(
"creating scheduler with fit predicates '%v' and priority functions '%v"
,
predicateKeys
,
priorityKeys
)
predicateFuncs
,
err
:=
getFitPredicateFunctions
(
predicateKeys
)
...
...
@@ -140,7 +160,7 @@ func (f *ConfigFactory) CreateFromKeys(predicateKeys, priorityKeys util.StringSe
},
nil
}
//
createUnassignedPodLW r
eturns a cache.ListWatch that finds all pods that need to be
//
R
eturns a cache.ListWatch that finds all pods that need to be
// scheduled.
func
(
factory
*
ConfigFactory
)
createUnassignedPodLW
()
*
cache
.
ListWatch
{
return
cache
.
NewListWatchFromClient
(
factory
.
Client
,
"pods"
,
api
.
NamespaceAll
,
labels
.
Set
{
"DesiredState.Host"
:
""
}
.
AsSelector
())
...
...
@@ -154,7 +174,7 @@ func parseSelectorOrDie(s string) labels.Selector {
return
selector
}
//
createAssignedPodLW r
eturns a cache.ListWatch that finds all pods that are
//
R
eturns a cache.ListWatch that finds all pods that are
// already scheduled.
// TODO: return a ListerWatcher interface instead?
func
(
factory
*
ConfigFactory
)
createAssignedPodLW
()
*
cache
.
ListWatch
{
...
...
@@ -166,7 +186,7 @@ func (factory *ConfigFactory) createMinionLW() *cache.ListWatch {
return
cache
.
NewListWatchFromClient
(
factory
.
Client
,
"minions"
,
api
.
NamespaceAll
,
parseSelectorOrDie
(
""
))
}
//
pollMinions l
ists all minions and filter out unhealthy ones, then returns
//
L
ists all minions and filter out unhealthy ones, then returns
// an enumerator for cache.Poller.
func
(
factory
*
ConfigFactory
)
pollMinions
()
(
cache
.
Enumerator
,
error
)
{
allNodes
:=
&
api
.
NodeList
{}
...
...
@@ -201,7 +221,7 @@ func (factory *ConfigFactory) pollMinions() (cache.Enumerator, error) {
return
&
nodeEnumerator
{
nodes
},
nil
}
//
createServiceLW r
eturns a cache.ListWatch that gets all changes to services.
//
R
eturns a cache.ListWatch that gets all changes to services.
func
(
factory
*
ConfigFactory
)
createServiceLW
()
*
cache
.
ListWatch
{
return
cache
.
NewListWatchFromClient
(
factory
.
Client
,
"services"
,
api
.
NamespaceAll
,
parseSelectorOrDie
(
""
))
}
...
...
@@ -231,7 +251,7 @@ func (factory *ConfigFactory) makeDefaultErrorFunc(backoff *podBackoff, podQueue
}
}
//
nodeEnumerator a
llows a cache.Poller to enumerate items in an api.NodeList
//
A
llows a cache.Poller to enumerate items in an api.NodeList
type
nodeEnumerator
struct
{
*
api
.
NodeList
}
...
...
plugin/pkg/scheduler/factory/factory_test.go
View file @
32523f8a
...
...
@@ -30,7 +30,10 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
algorithm
"github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
schedulerapi
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api"
latestschedulerapi
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api/latest"
)
func
TestCreate
(
t
*
testing
.
T
)
{
...
...
@@ -46,6 +49,89 @@ func TestCreate(t *testing.T) {
factory
.
Create
()
}
// Test configures a scheduler from a policies defined in a file
// It combines some configurable predicate/priorities with some pre-defined ones
func
TestCreateFromConfig
(
t
*
testing
.
T
)
{
var
configData
[]
byte
var
policy
schedulerapi
.
Policy
handler
:=
util
.
FakeHandler
{
StatusCode
:
500
,
ResponseBody
:
""
,
T
:
t
,
}
server
:=
httptest
.
NewServer
(
&
handler
)
defer
server
.
Close
()
client
:=
client
.
NewOrDie
(
&
client
.
Config
{
Host
:
server
.
URL
,
Version
:
testapi
.
Version
()})
factory
:=
NewConfigFactory
(
client
)
// Pre-register some predicate and priority functions
RegisterFitPredicate
(
"PredicateOne"
,
PredicateOne
)
RegisterFitPredicate
(
"PredicateTwo"
,
PredicateTwo
)
RegisterPriorityFunction
(
"PriorityOne"
,
PriorityOne
,
1
)
RegisterPriorityFunction
(
"PriorityTwo"
,
PriorityTwo
,
1
)
configData
=
[]
byte
(
`{
"kind" : "Policy",
"apiVersion" : "v1",
"predicates" : [
{"name" : "TestZoneAffinity", "argument" : {"serviceAffinity" : {"labels" : ["zone"]}}},
{"name" : "TestRequireZone", "argument" : {"labelsPresence" : {"labels" : ["zone"], "presence" : true}}},
{"name" : "PredicateOne"},
{"name" : "PredicateTwo"}
],
"priorities" : [
{"name" : "RackSpread", "weight" : 3, "argument" : {"serviceAntiAffinity" : {"label" : "rack"}}},
{"name" : "PriorityOne", "weight" : 2},
{"name" : "PriorityTwo", "weight" : 1} ]
}`
)
err
:=
latestschedulerapi
.
Codec
.
DecodeInto
(
configData
,
&
policy
)
if
err
!=
nil
{
t
.
Errorf
(
"Invalid configuration: %v"
,
err
)
}
factory
.
CreateFromConfig
(
policy
)
}
func
TestCreateFromEmptyConfig
(
t
*
testing
.
T
)
{
var
configData
[]
byte
var
policy
schedulerapi
.
Policy
handler
:=
util
.
FakeHandler
{
StatusCode
:
500
,
ResponseBody
:
""
,
T
:
t
,
}
server
:=
httptest
.
NewServer
(
&
handler
)
defer
server
.
Close
()
client
:=
client
.
NewOrDie
(
&
client
.
Config
{
Host
:
server
.
URL
,
Version
:
testapi
.
Version
()})
factory
:=
NewConfigFactory
(
client
)
configData
=
[]
byte
(
`{}`
)
err
:=
latestschedulerapi
.
Codec
.
DecodeInto
(
configData
,
&
policy
)
if
err
!=
nil
{
t
.
Errorf
(
"Invalid configuration: %v"
,
err
)
}
factory
.
CreateFromConfig
(
policy
)
}
func
PredicateOne
(
pod
api
.
Pod
,
existingPods
[]
api
.
Pod
,
node
string
)
(
bool
,
error
)
{
return
true
,
nil
}
func
PredicateTwo
(
pod
api
.
Pod
,
existingPods
[]
api
.
Pod
,
node
string
)
(
bool
,
error
)
{
return
true
,
nil
}
func
PriorityOne
(
pod
api
.
Pod
,
podLister
algorithm
.
PodLister
,
minionLister
algorithm
.
MinionLister
)
(
algorithm
.
HostPriorityList
,
error
)
{
return
[]
algorithm
.
HostPriority
{},
nil
}
func
PriorityTwo
(
pod
api
.
Pod
,
podLister
algorithm
.
PodLister
,
minionLister
algorithm
.
MinionLister
)
(
algorithm
.
HostPriorityList
,
error
)
{
return
[]
algorithm
.
HostPriority
{},
nil
}
func
TestPollMinions
(
t
*
testing
.
T
)
{
table
:=
[]
struct
{
minions
[]
api
.
Node
...
...
plugin/pkg/scheduler/factory/plugins.go
View file @
32523f8a
...
...
@@ -23,6 +23,7 @@ import (
algorithm
"github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
schedulerapi
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api"
"github.com/golang/glog"
)
...
...
@@ -45,7 +46,7 @@ type AlgorithmProviderConfig struct {
PriorityFunctionKeys
util
.
StringSet
}
// Register
FitPredicate register
s a fit predicate with the algorithm registry. Returns the name,
// Registers a fit predicate with the algorithm registry. Returns the name,
// with which the predicate was registered.
func
RegisterFitPredicate
(
name
string
,
predicate
algorithm
.
FitPredicate
)
string
{
schedulerFactoryMutex
.
Lock
()
...
...
@@ -55,7 +56,34 @@ func RegisterFitPredicate(name string, predicate algorithm.FitPredicate) string
return
name
}
// IsFitPredicateRegistered check is useful for testing providers.
// Registers a custom fit predicate with the algorithm registry.
// Returns the name, with which the predicate was registered.
func
RegisterCustomFitPredicate
(
policy
schedulerapi
.
PredicatePolicy
)
string
{
var
predicate
algorithm
.
FitPredicate
var
ok
bool
validatePredicateOrDie
(
policy
)
// generate the predicate function, if a custom type is requested
if
policy
.
Argument
!=
nil
{
if
policy
.
Argument
.
ServiceAffinity
!=
nil
{
predicate
=
algorithm
.
NewServiceAffinityPredicate
(
PodLister
,
ServiceLister
,
MinionLister
,
policy
.
Argument
.
ServiceAffinity
.
Labels
)
}
else
if
policy
.
Argument
.
LabelsPresence
!=
nil
{
predicate
=
algorithm
.
NewNodeLabelPredicate
(
MinionLister
,
policy
.
Argument
.
LabelsPresence
.
Labels
,
policy
.
Argument
.
LabelsPresence
.
Presence
)
}
}
else
if
predicate
,
ok
=
fitPredicateMap
[
policy
.
Name
];
ok
{
// checking to see if a pre-defined predicate is requested
glog
.
V
(
2
)
.
Infof
(
"Predicate type %s already registered, reusing."
,
policy
.
Name
)
}
if
predicate
==
nil
{
glog
.
Fatalf
(
"Invalid configuration: Predicate type not found for %s"
,
policy
.
Name
)
}
return
RegisterFitPredicate
(
policy
.
Name
,
predicate
)
}
// This check is useful for testing providers.
func
IsFitPredicateRegistered
(
name
string
)
bool
{
schedulerFactoryMutex
.
Lock
()
defer
schedulerFactoryMutex
.
Unlock
()
...
...
@@ -63,7 +91,7 @@ func IsFitPredicateRegistered(name string) bool {
return
ok
}
// Register
FitPredicate register
s a priority function with the algorithm registry. Returns the name,
// Registers a priority function with the algorithm registry. Returns the name,
// with which the function was registered.
func
RegisterPriorityFunction
(
name
string
,
function
algorithm
.
PriorityFunction
,
weight
int
)
string
{
schedulerFactoryMutex
.
Lock
()
...
...
@@ -73,7 +101,33 @@ func RegisterPriorityFunction(name string, function algorithm.PriorityFunction,
return
name
}
// IsPriorityFunctionRegistered check is useful for testing providers.
// Registers a custom priority function with the algorithm registry.
// Returns the name, with which the priority function was registered.
func
RegisterCustomPriorityFunction
(
policy
schedulerapi
.
PriorityPolicy
)
string
{
var
priority
algorithm
.
PriorityFunction
validatePriorityOrDie
(
policy
)
// generate the priority function, if a custom priority is requested
if
policy
.
Argument
!=
nil
{
if
policy
.
Argument
.
ServiceAntiAffinity
!=
nil
{
priority
=
algorithm
.
NewServiceAntiAffinityPriority
(
ServiceLister
,
policy
.
Argument
.
ServiceAntiAffinity
.
Label
)
}
else
if
policy
.
Argument
.
LabelPreference
!=
nil
{
priority
=
algorithm
.
NewNodeLabelPriority
(
policy
.
Argument
.
LabelPreference
.
Label
,
policy
.
Argument
.
LabelPreference
.
Presence
)
}
}
else
if
priorityConfig
,
ok
:=
priorityFunctionMap
[
policy
.
Name
];
ok
{
glog
.
V
(
2
)
.
Infof
(
"Priority type %s already registered, reusing."
,
policy
.
Name
)
priority
=
priorityConfig
.
Function
}
if
priority
==
nil
{
glog
.
Fatalf
(
"Invalid configuration: Priority type not found for %s"
,
policy
.
Name
)
}
return
RegisterPriorityFunction
(
policy
.
Name
,
priority
,
policy
.
Weight
)
}
// This check is useful for testing providers.
func
IsPriorityFunctionRegistered
(
name
string
)
bool
{
schedulerFactoryMutex
.
Lock
()
defer
schedulerFactoryMutex
.
Unlock
()
...
...
@@ -81,7 +135,7 @@ func IsPriorityFunctionRegistered(name string) bool {
return
ok
}
// Set
PriorityFunctionWeight set
s the weight of an already registered priority function.
// Sets the weight of an already registered priority function.
func
SetPriorityFunctionWeight
(
name
string
,
weight
int
)
{
schedulerFactoryMutex
.
Lock
()
defer
schedulerFactoryMutex
.
Unlock
()
...
...
@@ -91,9 +145,10 @@ func SetPriorityFunctionWeight(name string, weight int) {
return
}
config
.
Weight
=
weight
priorityFunctionMap
[
name
]
=
config
}
// Register
AlgorithmProvider register
s a new algorithm provider with the algorithm registry. This should
// Registers a new algorithm provider with the algorithm registry. This should
// be called from the init function in a provider plugin.
func
RegisterAlgorithmProvider
(
name
string
,
predicateKeys
,
priorityKeys
util
.
StringSet
)
string
{
schedulerFactoryMutex
.
Lock
()
...
...
@@ -106,7 +161,7 @@ func RegisterAlgorithmProvider(name string, predicateKeys, priorityKeys util.Str
return
name
}
//
GetAlgorithmProvider
should not be used to modify providers. It is publicly visible for testing.
//
This function
should not be used to modify providers. It is publicly visible for testing.
func
GetAlgorithmProvider
(
name
string
)
(
*
AlgorithmProviderConfig
,
error
)
{
schedulerFactoryMutex
.
Lock
()
defer
schedulerFactoryMutex
.
Unlock
()
...
...
@@ -157,3 +212,33 @@ func validateAlgorithmNameOrDie(name string) {
glog
.
Fatalf
(
"algorithm name %v does not match the name validation regexp
\"
%v
\"
."
,
name
,
validName
)
}
}
func
validatePredicateOrDie
(
predicate
schedulerapi
.
PredicatePolicy
)
{
if
predicate
.
Argument
!=
nil
{
numArgs
:=
0
if
predicate
.
Argument
.
ServiceAffinity
!=
nil
{
numArgs
++
}
if
predicate
.
Argument
.
LabelsPresence
!=
nil
{
numArgs
++
}
if
numArgs
!=
1
{
glog
.
Fatalf
(
"Exactly 1 predicate argument is required"
)
}
}
}
func
validatePriorityOrDie
(
priority
schedulerapi
.
PriorityPolicy
)
{
if
priority
.
Argument
!=
nil
{
numArgs
:=
0
if
priority
.
Argument
.
ServiceAntiAffinity
!=
nil
{
numArgs
++
}
if
priority
.
Argument
.
LabelPreference
!=
nil
{
numArgs
++
}
if
numArgs
!=
1
{
glog
.
Fatalf
(
"Exactly 1 priority argument is required"
)
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment