forked from kubernetes-retired/contrib
/
cluster_autoscaler.go
107 lines (89 loc) · 2.91 KB
/
cluster_autoscaler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
Copyright 2016 The Kubernetes Authors 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 main
import (
"flag"
"net/url"
"time"
"k8s.io/contrib/cluster-autoscaler/config"
kube_client "k8s.io/kubernetes/pkg/client/unversioned"
"github.com/golang/glog"
)
var (
migConfig config.MigConfigFlag
kubernetes = flag.String("kubernetes", "", "Kuberentes master location. Leave blank for default")
)
func main() {
flag.Var(&migConfig, "nodes", "sets min,max size and url of a MIG to be controlled by Cluster Autoscaler. "+
"Can be used multiple times. Format: <min>:<max>:<migurl>")
flag.Parse()
glog.Infof("MIG: %s\n", migConfig.String())
url, err := url.Parse(*kubernetes)
if err != nil {
glog.Fatalf("Failed to parse Kuberentes url: %v", err)
}
kubeConfig, err := config.GetKubeClientConfig(url)
if err != nil {
glog.Fatalf("Failed to build Kuberentes client configuration: %v", err)
}
kubeClient := kube_client.NewOrDie(kubeConfig)
unscheduledPodLister := NewUnscheduledPodLister(kubeClient)
nodeLister := NewNodeLister(kubeClient)
for {
select {
case <-time.After(time.Minute):
{
pods, err := unscheduledPodLister.List()
if err != nil {
glog.Errorf("Failed to list pods: %v", err)
continue
}
if len(pods) == 0 {
glog.V(1).Info("No unscheduled pods")
continue
}
for _, pod := range pods {
glog.V(1).Infof("Pod %s/%s is not scheduled", pod.Namespace, pod.Name)
}
nodes, err := nodeLister.List()
if err != nil {
glog.Errorf("Failed to list nodes: %v", err)
continue
}
if len(nodes) == 0 {
glog.Errorf("No nodes in the cluster")
continue
}
// TODO: Checking if all nodes are present.
// Checks if scheduler tried to schedule the pods after thew newest node was added.
newestNode := GetNewestNode(nodes)
if newestNode == nil {
glog.Errorf("No newest node")
continue
}
oldestSchedulingTrial := GetOldestFailedSchedulingTrail(pods)
if oldestSchedulingTrial == nil {
glog.Errorf("No oldest unschedueled trial: %v", err)
continue
}
// TODO: Find better way to check if all pods were checked after the newest node
// was added.
if newestNode.CreationTimestamp.After(oldestSchedulingTrial.Add(-1 * time.Minute)) {
// Lets give scheduler another chance.
glog.V(1).Infof("One of the pods have not been tried after adding %s", newestNode.Name)
continue
}
}
}
}
}