mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-18 04:54:54 +00:00
HPA: Fix int overflow in GetExternalPerPodMetricReplicas
Signed-off-by: Omer Aplatony <omerap12@gmail.com>
This commit is contained in:
@@ -375,15 +375,31 @@ func (c *ReplicaCalculator) GetExternalPerPodMetricReplicas(statusReplicas int32
|
||||
usage = 0
|
||||
for _, val := range metrics {
|
||||
usage = usage + val
|
||||
if usage < 0 {
|
||||
// the only way we would ever get here is because of an Int64 overflow
|
||||
usage = math.MaxInt64
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
replicaCount = statusReplicas
|
||||
usageRatio := float64(usage) / (float64(targetUsagePerPod) * float64(replicaCount))
|
||||
if !tolerances.isWithin(usageRatio) {
|
||||
// update number of replicas if the change is large enough
|
||||
replicaCount = int32(math.Ceil(float64(usage) / float64(targetUsagePerPod)))
|
||||
replicaCountResult := math.Ceil(float64(usage) / float64(targetUsagePerPod))
|
||||
// Ensure that the result exceeds the bounds of an int32
|
||||
if replicaCountResult > float64(math.MaxInt32) {
|
||||
replicaCount = math.MaxInt32
|
||||
} else {
|
||||
replicaCount = int32(replicaCountResult)
|
||||
}
|
||||
}
|
||||
// Handle usage overflow cases
|
||||
if float64(usage) >= float64(math.MaxInt64) {
|
||||
usage = math.MaxInt64
|
||||
} else {
|
||||
usage = int64(math.Ceil(float64(usage) / float64(statusReplicas)))
|
||||
}
|
||||
usage = int64(math.Ceil(float64(usage) / float64(statusReplicas)))
|
||||
return replicaCount, usage, timestamp, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -561,6 +561,38 @@ func TestReplicaCalcScaleUpUnreadyNoScale(t *testing.T) {
|
||||
tc.runTest(t)
|
||||
}
|
||||
|
||||
func TestExternalPerPodMetricReplicaOverflow(t *testing.T) {
|
||||
tc := replicaCalcTestCase{
|
||||
currentReplicas: 1,
|
||||
expectedReplicas: math.MaxInt32,
|
||||
metric: &metricInfo{
|
||||
name: "qps",
|
||||
levels: []int64{math.MaxInt64},
|
||||
perPodTargetUsage: 1, // Set to 1 to test replica calculation when targeting a 1:1 ratio between metric value and number of pods
|
||||
metricType: externalPerPodMetric,
|
||||
expectedUsage: math.MaxInt64,
|
||||
selector: &metav1.LabelSelector{MatchLabels: map[string]string{"label": "value"}},
|
||||
},
|
||||
}
|
||||
tc.runTest(t)
|
||||
}
|
||||
|
||||
func TestExternalPerPodMetricUsageOverflow(t *testing.T) {
|
||||
tc := replicaCalcTestCase{
|
||||
currentReplicas: 1,
|
||||
expectedReplicas: 1,
|
||||
metric: &metricInfo{
|
||||
name: "qps",
|
||||
levels: []int64{math.MaxInt64},
|
||||
perPodTargetUsage: math.MaxInt64, // Set to a high value to test replica calculation when targeting a high value:1 ratio between metric value and number of pods
|
||||
metricType: externalPerPodMetric,
|
||||
expectedUsage: math.MaxInt64,
|
||||
selector: &metav1.LabelSelector{MatchLabels: map[string]string{"label": "value"}},
|
||||
},
|
||||
}
|
||||
tc.runTest(t)
|
||||
}
|
||||
|
||||
func TestReplicaCalcScaleHotCpuNoScale(t *testing.T) {
|
||||
tc := replicaCalcTestCase{
|
||||
currentReplicas: 3,
|
||||
|
||||
Reference in New Issue
Block a user