Skip to content

Commit

Permalink
Configuring scheduler via json configuration file
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhishek Gupta committed Mar 2, 2015
1 parent 445fd56 commit 548e0da
Show file tree
Hide file tree
Showing 9 changed files with 421 additions and 5 deletions.
27 changes: 27 additions & 0 deletions plugin/cmd/kube-scheduler/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -78,17 +85,37 @@ func (s *SchedulerServer) Run(_ []string) error {
if err != nil {
glog.Fatalf("Failed to create scheduler configuration: %v", err)
}

sched := scheduler.New(config)
sched.Run()

select {}
}

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 = json.Unmarshal(configData, &policy)
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)
}
8 changes: 4 additions & 4 deletions plugin/pkg/scheduler/algorithmprovider/affinity/affinity.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ func affinityPredicates() util.StringSet {
"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"})),
factory.RegisterFitPredicate("RegionAffinity", 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)),
factory.RegisterFitPredicate("RegionRequired", algorithm.NewNodeLabelPredicate(factory.MinionLister, []string{"region"}, true)),
)
}

Expand All @@ -48,8 +48,8 @@ func affinityPriorities() util.StringSet {
"LeastRequestedPriority",
"ServiceSpreadingPriority",
// spreads pods belonging to the same service across minions in different zones
factory.RegisterPriorityFunction("ZoneSpreadingPriority", algorithm.NewServiceAntiAffinityPriority(factory.ServiceLister, "zone"), 2),
factory.RegisterPriorityFunction("ZoneSpread", 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),
factory.RegisterPriorityFunction("ZonePreferred", algorithm.NewNodeLabelPriority("zone", true), 1),
)
}
40 changes: 40 additions & 0 deletions plugin/pkg/scheduler/api/latest/latest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
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,
// for client code that wants to hardcode the lowest common denominator.
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 output that should use
// the latest supported version. Use this Codec when writing to
// disk, a data store that is not dynamically versioned, or in tests.
// This codec can decode any object that Kubernetes is aware of.
var Codec = v1.Codec
32 changes: 32 additions & 0 deletions plugin/pkg/scheduler/api/register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
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() {}
73 changes: 73 additions & 0 deletions plugin/pkg/scheduler/api/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
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"
)

// Where possible, json tags match the cli argument names.
// Top level config objects and all values required for proper functioning are not "omitempty". Any truly optional piece of config is allowed to be omitted.

type Policy struct {
api.TypeMeta `json:",inline"`
Predicates []PredicatePolicy `json:"predicates"`
Priorities []PriorityPolicy `json:"priorities"`
}

type PredicatePolicy struct {
Name string `json:"name"`
Argument *PredicateArgument `json:"argument"`
}

type PriorityPolicy struct {
Name string `json:"name"`
Weight int `json:"weight"`
Argument *PriorityArgument `json:"argument"`
}

// PredicateArgument represents the arguments that the different types of predicates take.
// Only one of its members may be specified.
type PredicateArgument struct {
ServiceAffinity *ServiceAffinity `json:"serviceAffinity"`
LabelsPresence *LabelsPresence `json:"labelsPresence"`
}

// PriorityArgument represents the arguments that the different types of priorities take.
// Only one of its members may be specified.
type PriorityArgument struct {
ServiceAntiAffinity *ServiceAntiAffinity `json:"serviceAntiAffinity"`
LabelPreference *LabelPreference `json:"labelPreference"`
}

type ServiceAffinity struct {
Labels []string `json:"labels"`
}

type LabelsPresence struct {
Labels []string `json:"labels"`
Presence bool `json:"presence"`
}

type ServiceAntiAffinity struct {
Label string `json:"label"`
}

type LabelPreference struct {
Label string `json:"label"`
Presence bool `json:"presence"`
}
33 changes: 33 additions & 0 deletions plugin/pkg/scheduler/api/v1/register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
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() {}
106 changes: 106 additions & 0 deletions plugin/pkg/scheduler/api/v1/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
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"
)

// Where possible, json tags match the cli argument names.
// Top level config objects and all values required for proper functioning are not "omitempty". Any truly optional piece of config is allowed to be omitted.

type Policy struct {
v1beta3.TypeMeta `json:",inline"`
// Predicates holds the information to configure the fit predicate functions
Predicates []PredicatePolicy `json:"predicates"`
// Priorities holds the information to configure the priority functions
Priorities []PriorityPolicy `json:"priorities"`
}

type PredicatePolicy struct {
// Name is the 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"`
// Argument holds the parameters to configure the given predicate
Argument *PredicateArgument `json:"argument"`
}

type PriorityPolicy struct {
// Name is the 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"`
// Weight is the numeric multiplier for the minion scores that the priority function generates
Weight int `json:"weight"`
// Argument holds the parameters to configure the given priority function
Argument *PriorityArgument `json:"argument"`
}

// PredicateArgument represents the arguments that the different types of predicates take
// Only one of its members may be specified
type PredicateArgument struct {
// ServiceAffinity is 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"`
// LabelsPresence is the predicate that checks whether a particular minion has a certain label
// defined or not, regardless of value
LabelsPresence *LabelsPresence `json:"labelsPresence"`
}

// PriorityArgument represents the arguments that the different types of priorities take.
// Only one of its members may be specified
type PriorityArgument struct {
// ServiceAntiAffinity is 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"`
// LabelPreference is the priority function that checks whether a particular minion has a certain label
// defined or not, regardless of value
LabelPreference *LabelPreference `json:"labelPreference"`
}

// ServiceAffinity holds the parameters that are used to configure the corresponding predicate
type ServiceAffinity struct {
// Labels is 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"`
}

// LabelsPresence holds the parameters that are used to configure the corresponding predicate
type LabelsPresence struct {
// Labels is 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"`
// Presence is the boolean flag that indicates whether the labels should be present or absent from the minion
Presence bool `json:"presence"`
}

// ServiceAntiAffinity holds the parameters that are used to configure the corresponding priority function
type ServiceAntiAffinity struct {
// Label is used to identify minion "groups"
Label string `json:"label"`
}

// LabelPreference holds the parameters that are used to configure the corresponding priority function
type LabelPreference struct {
// Label is used to identify minion "groups"
Label string `json:"label"`
// Presence 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"`
}
Loading

0 comments on commit 548e0da

Please sign in to comment.