diff --git a/pkg/controller/podautoscaler/replica_calculator.go b/pkg/controller/podautoscaler/replica_calculator.go index b065fce3743..049aa61f31c 100644 --- a/pkg/controller/podautoscaler/replica_calculator.go +++ b/pkg/controller/podautoscaler/replica_calculator.go @@ -105,9 +105,11 @@ func (c *ReplicaCalculator) GetResourceReplicas(ctx context.Context, currentRepl if len(missingPods) > 0 { if usageRatio < 1.0 { - // on a scale-down, treat missing pods as using 100% of the resource request + // on a scale-down, treat missing pods as using 100% (all) of the resource request + // or the utilization target for targets higher than 100% + fallbackUtilization := int64(max(100, targetUtilization)) for podName := range missingPods { - metrics[podName] = metricsclient.PodMetric{Value: requests[podName]} + metrics[podName] = metricsclient.PodMetric{Value: requests[podName] * fallbackUtilization / 100} } } else if usageRatio > 1.0 { // on a scale-up, treat missing pods as using 0% of the resource request @@ -208,7 +210,7 @@ func (c *ReplicaCalculator) calcPlainMetricReplicas(metrics metricsclient.PodMet if len(missingPods) > 0 { if usageRatio < 1.0 { - // on a scale-down, treat missing pods as using 100% of the resource request + // on a scale-down, treat missing pods as using exactly the target amount for podName := range missingPods { metrics[podName] = metricsclient.PodMetric{Value: targetUtilization} } diff --git a/pkg/controller/podautoscaler/replica_calculator_test.go b/pkg/controller/podautoscaler/replica_calculator_test.go index 2f401d8b7a6..5d915d1897d 100644 --- a/pkg/controller/podautoscaler/replica_calculator_test.go +++ b/pkg/controller/podautoscaler/replica_calculator_test.go @@ -1464,6 +1464,24 @@ func TestReplicaCalcMissingMetricsUnreadyScaleDown(t *testing.T) { tc.runTest(t) } +func TestReplicaCalcMissingMetricsScaleDownTargetOver100(t *testing.T) { + tc := replicaCalcTestCase{ + currentReplicas: 4, + expectedReplicas: 2, + podReadiness: []v1.ConditionStatus{v1.ConditionFalse, v1.ConditionTrue, v1.ConditionTrue, v1.ConditionTrue}, + resource: &resourceInfo{ + name: v1.ResourceCPU, + requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("2.0"), resource.MustParse("2.0")}, + levels: makePodMetricLevels(200, 100, 100), + + targetUtilization: 300, + expectedUtilization: 6, + expectedValue: numContainersPerPod * 100, + }, + } + tc.runTest(t) +} + func TestReplicaCalcDuringRollingUpdateWithMaxSurge(t *testing.T) { tc := replicaCalcTestCase{ currentReplicas: 2,