mirror of
https://github.com/zalando-incubator/kube-metrics-adapter.git
synced 2025-05-18 11:16:25 +00:00
Fix scaling adjustment edge case (#782)
* Update GH actions build Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de> * Fix scaling adjustment edge case Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de> --------- Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
This commit is contained in:

committed by
GitHub

parent
4204daa44f
commit
d416441688
6
.github/workflows/ci.yaml
vendored
6
.github/workflows/ci.yaml
vendored
@ -10,10 +10,10 @@ jobs:
|
|||||||
tests:
|
tests:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-go@v2
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '^1.19'
|
go-version: '^1.23'
|
||||||
- run: go version
|
- run: go version
|
||||||
- run: go install github.com/mattn/goveralls@latest
|
- run: go install github.com/mattn/goveralls@latest
|
||||||
- run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
- run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||||
|
@ -266,13 +266,13 @@ func (c *Controller) adjustHPAScaling(ctx context.Context, hpa *autoscalingv2.Ho
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
highestExpected, highestObject := highestActiveSchedule(hpa, activeSchedules)
|
highestExpected, usageRatio, highestObject := highestActiveSchedule(hpa, activeSchedules, current)
|
||||||
|
|
||||||
highestExpected = int64(math.Min(float64(highestExpected), float64(hpa.Spec.MaxReplicas)))
|
highestExpected = int64(math.Min(float64(highestExpected), float64(hpa.Spec.MaxReplicas)))
|
||||||
|
|
||||||
var change float64
|
var change float64
|
||||||
if highestExpected > current {
|
if highestExpected > current {
|
||||||
change = (float64(highestExpected) - float64(current)) / float64(current)
|
change = math.Abs(1.0 - usageRatio)
|
||||||
}
|
}
|
||||||
|
|
||||||
if change > 0 && change <= c.hpaTolerance {
|
if change > 0 && change <= c.hpaTolerance {
|
||||||
@ -304,8 +304,9 @@ func (c *Controller) adjustHPAScaling(ctx context.Context, hpa *autoscalingv2.Ho
|
|||||||
|
|
||||||
// highestActiveSchedule returns the highest active schedule value and
|
// highestActiveSchedule returns the highest active schedule value and
|
||||||
// corresponding object.
|
// corresponding object.
|
||||||
func highestActiveSchedule(hpa *autoscalingv2.HorizontalPodAutoscaler, activeSchedules map[string]int64) (int64, autoscalingv2.CrossVersionObjectReference) {
|
func highestActiveSchedule(hpa *autoscalingv2.HorizontalPodAutoscaler, activeSchedules map[string]int64, currentReplicas int64) (int64, float64, autoscalingv2.CrossVersionObjectReference) {
|
||||||
var highestExpected int64
|
var highestExpected int64
|
||||||
|
var usageRatio float64
|
||||||
var highestObject autoscalingv2.CrossVersionObjectReference
|
var highestObject autoscalingv2.CrossVersionObjectReference
|
||||||
for _, metric := range hpa.Spec.Metrics {
|
for _, metric := range hpa.Spec.Metrics {
|
||||||
if metric.Type != autoscalingv2.ObjectMetricSourceType {
|
if metric.Type != autoscalingv2.ObjectMetricSourceType {
|
||||||
@ -340,11 +341,12 @@ func highestActiveSchedule(hpa *autoscalingv2.HorizontalPodAutoscaler, activeSch
|
|||||||
expected := int64(math.Ceil(float64(value) / float64(target)))
|
expected := int64(math.Ceil(float64(value) / float64(target)))
|
||||||
if expected > highestExpected {
|
if expected > highestExpected {
|
||||||
highestExpected = expected
|
highestExpected = expected
|
||||||
|
usageRatio = float64(value) / (float64(target) * float64(currentReplicas))
|
||||||
highestObject = metric.Object.DescribedObject
|
highestObject = metric.Object.DescribedObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return highestExpected, highestObject
|
return highestExpected, usageRatio, highestObject
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) adjustScaling(ctx context.Context, schedules []v1.ScalingScheduler) error {
|
func (c *Controller) adjustScaling(ctx context.Context, schedules []v1.ScalingScheduler) error {
|
||||||
|
@ -337,24 +337,35 @@ func TestAdjustScaling(t *testing.T) {
|
|||||||
currentReplicas int32
|
currentReplicas int32
|
||||||
desiredReplicas int32
|
desiredReplicas int32
|
||||||
targetValue int64
|
targetValue int64
|
||||||
|
scheduleTarget int64
|
||||||
}{
|
}{
|
||||||
|
{
|
||||||
|
msg: "current less than 10%% below desired (target 10000)",
|
||||||
|
currentReplicas: 28, // 7.1% increase to desired
|
||||||
|
desiredReplicas: 31,
|
||||||
|
targetValue: 333, // 10000/333 ~= 31
|
||||||
|
scheduleTarget: 10000,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
msg: "current less than 10%% below desired",
|
msg: "current less than 10%% below desired",
|
||||||
currentReplicas: 95, // 5.3% increase to desired
|
currentReplicas: 95, // 5.3% increase to desired
|
||||||
desiredReplicas: 100,
|
desiredReplicas: 100,
|
||||||
targetValue: 10, // 1000/10 = 100
|
targetValue: 10, // 1000/10 = 100
|
||||||
|
scheduleTarget: 1000,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
msg: "current more than 10%% below desired, no adjustment",
|
msg: "current more than 10%% below desired, no adjustment",
|
||||||
currentReplicas: 90, // 11% increase to desired
|
currentReplicas: 90, // 11% increase to desired
|
||||||
desiredReplicas: 90,
|
desiredReplicas: 90,
|
||||||
targetValue: 10, // 1000/10 = 100
|
targetValue: 10, // 1000/10 = 100
|
||||||
|
scheduleTarget: 1000,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
msg: "invalid HPA should not do any adjustment",
|
msg: "invalid HPA should not do any adjustment",
|
||||||
currentReplicas: 95,
|
currentReplicas: 95,
|
||||||
desiredReplicas: 95,
|
desiredReplicas: 95,
|
||||||
targetValue: 0, // this is treated as invalid in the test, thus the HPA is ingored and no adjustment happens.
|
targetValue: 0, // this is treated as invalid in the test, thus the HPA is ingored and no adjustment happens.
|
||||||
|
scheduleTarget: 1000,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.msg, func(t *testing.T) {
|
t.Run(tc.msg, func(t *testing.T) {
|
||||||
@ -384,7 +395,7 @@ func TestAdjustScaling(t *testing.T) {
|
|||||||
Type: v1.OneTimeSchedule,
|
Type: v1.OneTimeSchedule,
|
||||||
Date: &scheduleDate,
|
Date: &scheduleDate,
|
||||||
DurationMinutes: 15,
|
DurationMinutes: 15,
|
||||||
Value: 1000,
|
Value: tc.scheduleTarget,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user