Skip to content
This repository was archived by the owner on Apr 17, 2019. It is now read-only.

Commit a434839

Browse files
committed
Added support for ExponentialEstimator
1 parent 4865b21 commit a434839

File tree

3 files changed

+80
-3
lines changed

3 files changed

+80
-3
lines changed

addon-resizer/nanny/estimator.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ import (
2222
"k8s.io/kubernetes/pkg/api/resource"
2323
)
2424

25+
const (
26+
eps = float64(0.01)
27+
)
28+
2529
// Resource defines the name of a resource, the quantity, and the marginal value.
2630
type Resource struct {
2731
Base, ExtraPerNode resource.Quantity
@@ -34,9 +38,29 @@ type LinearEstimator struct {
3438
}
3539

3640
func (e LinearEstimator) scaleWithNodes(numNodes uint64) *api.ResourceRequirements {
41+
return calculateResources(numNodes, e.Resources)
42+
}
43+
44+
// ExponentialEstimator estimates the amount of resources in the way that
45+
// prevents from frequent updates but may end up with larger resource usage
46+
// than actually needed (though no more than ScaleFactor).
47+
type ExponentialEstimator struct {
48+
Resources []Resource
49+
ScaleFactor float64
50+
}
51+
52+
func (e ExponentialEstimator) scaleWithNodes(numNodes uint64) *api.ResourceRequirements {
53+
n := uint64(16)
54+
for n < numNodes {
55+
n = uint64(float64(n)*e.ScaleFactor + eps)
56+
}
57+
return calculateResources(n, e.Resources)
58+
}
59+
60+
func calculateResources(numNodes uint64, resources []Resource) *api.ResourceRequirements {
3761
limits := make(api.ResourceList)
3862
requests := make(api.ResourceList)
39-
for _, r := range e.Resources {
63+
for _, r := range resources {
4064
val := r.Base.MilliValue() + r.ExtraPerNode.MilliValue()*int64(numNodes)
4165
newRes := resource.NewMilliQuantity(val, r.Base.Format)
4266
limits[r.Name] = *newRes

addon-resizer/nanny/estimator_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,27 @@ var (
8989
Resources: []Resource{},
9090
}
9191

92+
exponentialEstimator = ExponentialEstimator{
93+
Resources: []Resource{
94+
{
95+
Base: resource.MustParse("0.3"),
96+
ExtraPerNode: resource.MustParse("1"),
97+
Name: "cpu",
98+
},
99+
{
100+
Base: resource.MustParse("30Mi"),
101+
ExtraPerNode: resource.MustParse("1Mi"),
102+
Name: "memory",
103+
},
104+
{
105+
Base: resource.MustParse("30Gi"),
106+
ExtraPerNode: resource.MustParse("1Gi"),
107+
Name: "storage",
108+
},
109+
},
110+
ScaleFactor: 1.5,
111+
}
112+
92113
baseResources = api.ResourceList{
93114
"cpu": resource.MustParse("0.3"),
94115
"memory": resource.MustParse("30Mi"),
@@ -125,6 +146,17 @@ var (
125146
"memory": resource.MustParse("33Mi"),
126147
}
127148
noResources = api.ResourceList{}
149+
150+
sixteenNodeResources = api.ResourceList{
151+
"cpu": resource.MustParse("16.3"),
152+
"memory": resource.MustParse("46Mi"),
153+
"storage": resource.MustParse("46Gi"),
154+
}
155+
twentyFourNodeResources = api.ResourceList{
156+
"cpu": resource.MustParse("24.3"),
157+
"memory": resource.MustParse("54Mi"),
158+
"storage": resource.MustParse("54Gi"),
159+
}
128160
)
129161

130162
func verifyResources(t *testing.T, kind string, got, want api.ResourceList) {
@@ -151,6 +183,8 @@ func TestEstimateResources(t *testing.T) {
151183
}{
152184
{fullEstimator, 0, baseResources, baseResources},
153185
{fullEstimator, 3, threeNodeResources, threeNodeResources},
186+
{fullEstimator, 16, sixteenNodeResources, sixteenNodeResources},
187+
{fullEstimator, 24, twentyFourNodeResources, twentyFourNodeResources},
154188
{noCPUEstimator, 0, noCPUBaseResources, noCPUBaseResources},
155189
{noCPUEstimator, 3, threeNodeNoCPUResources, threeNodeNoCPUResources},
156190
{noMemoryEstimator, 0, noMemoryBaseResources, noMemoryBaseResources},
@@ -159,6 +193,13 @@ func TestEstimateResources(t *testing.T) {
159193
{noStorageEstimator, 3, threeNodeNoStorageResources, threeNodeNoStorageResources},
160194
{emptyEstimator, 0, noResources, noResources},
161195
{emptyEstimator, 3, noResources, noResources},
196+
{exponentialEstimator, 0, sixteenNodeResources, sixteenNodeResources},
197+
{exponentialEstimator, 3, sixteenNodeResources, sixteenNodeResources},
198+
{exponentialEstimator, 10, sixteenNodeResources, sixteenNodeResources},
199+
{exponentialEstimator, 16, sixteenNodeResources, sixteenNodeResources},
200+
{exponentialEstimator, 17, twentyFourNodeResources, twentyFourNodeResources},
201+
{exponentialEstimator, 20, twentyFourNodeResources, twentyFourNodeResources},
202+
{exponentialEstimator, 24, twentyFourNodeResources, twentyFourNodeResources},
162203
}
163204

164205
for _, tc := range testCases {

addon-resizer/nanny/main/pod_nanny.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ var (
4848
containerName = flag.String("container", "pod-nanny", "The name of the container to watch. This defaults to the nanny itself.")
4949
// Flags to control runtime behavior.
5050
pollPeriod = time.Millisecond * time.Duration(*flag.Int("poll-period", 10000, "The time, in milliseconds, to poll the dependent container."))
51+
estimator = flag.String("estimator", "linear", "The estimator to use. Currently supported: linear, exponential")
5152
)
5253

5354
func main() {
@@ -107,8 +108,19 @@ func main() {
107108
}
108109

109110
log.Infof("Resources: %v", resources)
110-
est := nanny.LinearEstimator{
111-
Resources: resources,
111+
112+
var est nanny.ResourceEstimator
113+
if *estimator == "linear" {
114+
est = nanny.LinearEstimator{
115+
Resources: resources,
116+
}
117+
} else if *estimator == "exponential" {
118+
est = nanny.ExponentialEstimator{
119+
Resources: resources,
120+
ScaleFactor: 1.5,
121+
}
122+
} else {
123+
log.Fatalf("Estimator %s not supported", *estimator)
112124
}
113125

114126
// Begin nannying.

0 commit comments

Comments
 (0)