1
0
mirror of https://github.com/kubernetes-sigs/descheduler.git synced 2026-01-26 05:14:13 +01:00

Implement node selectors to retrieve node list based on provided query.

This commit is contained in:
Avesh Agarwal
2017-11-08 16:11:28 -05:00
parent 5d3f987dde
commit c29c9db41e
6 changed files with 36 additions and 4 deletions

View File

@@ -53,4 +53,6 @@ func (rs *DeschedulerServer) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&rs.KubeconfigFile, "kubeconfig-file", rs.KubeconfigFile, "File with kube configuration.")
fs.StringVar(&rs.PolicyConfigFile, "policy-config-file", rs.PolicyConfigFile, "File with descheduler policy configuration.")
fs.BoolVar(&rs.DryRun, "dry-run", rs.DryRun, "execute descheduler in dry run mode.")
// node-selector query causes descheduler to run only on nodes that matches the node labels in the query
fs.StringVar(&rs.NodeSelector, "node-selector", rs.NodeSelector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
}

View File

@@ -37,4 +37,7 @@ type DeschedulerConfiguration struct {
// Dry run
DryRun bool
// Node selectors
NodeSelector string
}

View File

@@ -37,4 +37,7 @@ type DeschedulerConfiguration struct {
// Dry run
DryRun bool `json:"dryRun,omitempty"`
// Node selectors
NodeSelector string `json:"nodeSelector,omitempty"`
}

View File

@@ -48,7 +48,7 @@ func Run(rs *options.DeschedulerServer) error {
}
stopChannel := make(chan struct{})
nodes, err := nodeutil.ReadyNodes(rs.Client, stopChannel)
nodes, err := nodeutil.ReadyNodes(rs.Client, rs.NodeSelector, stopChannel)
if err != nil {
return err
}

View File

@@ -31,16 +31,23 @@ import (
// ReadyNodes returns ready nodes irrespective of whether they are
// schedulable or not.
func ReadyNodes(client clientset.Interface, stopChannel <-chan struct{}) ([]*v1.Node, error) {
func ReadyNodes(client clientset.Interface, nodeSelector string, stopChannel <-chan struct{}) ([]*v1.Node, error) {
nl := GetNodeLister(client, stopChannel)
nodes, err := nl.List(labels.Everything())
ns, err := labels.Parse(nodeSelector)
if err != nil {
return []*v1.Node{}, err
}
nodes, err := nl.List(ns)
if err != nil {
return []*v1.Node{}, err
}
if len(nodes) == 0 {
var err error
nItems, err := client.Core().Nodes().List(metav1.ListOptions{})
nItems, err := client.Core().Nodes().List(metav1.ListOptions{LabelSelector: nodeSelector})
if err != nil {
return []*v1.Node{}, err
}

View File

@@ -80,3 +80,20 @@ func TestReadyNodes(t *testing.T) {
}
}
func TestReadyNodesWithNodeSelector(t *testing.T) {
node1 := test.BuildTestNode("node1", 1000, 2000, 9)
node1.Labels = map[string]string{"type": "compute"}
node2 := test.BuildTestNode("node2", 1000, 2000, 9)
node2.Labels = map[string]string{"type": "infra"}
fakeClient := fake.NewSimpleClientset(node1, node2)
nodeSelector := "type=compute"
stopChannel := make(chan struct{})
nodes, _ := ReadyNodes(fakeClient, nodeSelector, stopChannel)
if nodes[0].Name != "node1" {
t.Errorf("Expected node1, got %s", nodes[0].Name)
}
}