mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
requested changes: fix return type variables
This commit is contained in:
parent
cbea8d2248
commit
01b553145c
@ -373,7 +373,7 @@ func (a *HorizontalController) reconcileKey(ctx context.Context, key string) (de
|
|||||||
// computeStatusForObjectMetric computes the desired number of replicas for the specified metric of type ObjectMetricSourceType.
|
// computeStatusForObjectMetric computes the desired number of replicas for the specified metric of type ObjectMetricSourceType.
|
||||||
func (a *HorizontalController) computeStatusForObjectMetric(specReplicas, statusReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus, metricSelector labels.Selector) (replicas int32, timestamp time.Time, metricName string, condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) {
|
func (a *HorizontalController) computeStatusForObjectMetric(specReplicas, statusReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus, metricSelector labels.Selector) (replicas int32, timestamp time.Time, metricName string, condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) {
|
||||||
if metricSpec.Object.Target.Type == autoscalingv2.ValueMetricType {
|
if metricSpec.Object.Target.Type == autoscalingv2.ValueMetricType {
|
||||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetObjectMetricReplicas(specReplicas, metricSpec.Object.Target.Value.MilliValue(), metricSpec.Object.Metric.Name, hpa.Namespace, &metricSpec.Object.DescribedObject, selector, metricSelector)
|
replicaCountProposal, usageProposal, timestampProposal, err := a.replicaCalc.GetObjectMetricReplicas(specReplicas, metricSpec.Object.Target.Value.MilliValue(), metricSpec.Object.Metric.Name, hpa.Namespace, &metricSpec.Object.DescribedObject, selector, metricSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
condition := a.getUnableComputeReplicaCountCondition(hpa, "FailedGetObjectMetric", err)
|
condition := a.getUnableComputeReplicaCountCondition(hpa, "FailedGetObjectMetric", err)
|
||||||
return 0, timestampProposal, "", condition, err
|
return 0, timestampProposal, "", condition, err
|
||||||
@ -387,13 +387,13 @@ func (a *HorizontalController) computeStatusForObjectMetric(specReplicas, status
|
|||||||
Selector: metricSpec.Object.Metric.Selector,
|
Selector: metricSpec.Object.Metric.Selector,
|
||||||
},
|
},
|
||||||
Current: autoscalingv2.MetricValueStatus{
|
Current: autoscalingv2.MetricValueStatus{
|
||||||
Value: resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
Value: resource.NewMilliQuantity(usageProposal, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("%s metric %s", metricSpec.Object.DescribedObject.Kind, metricSpec.Object.Metric.Name), autoscalingv2.HorizontalPodAutoscalerCondition{}, nil
|
return replicaCountProposal, timestampProposal, fmt.Sprintf("%s metric %s", metricSpec.Object.DescribedObject.Kind, metricSpec.Object.Metric.Name), autoscalingv2.HorizontalPodAutoscalerCondition{}, nil
|
||||||
} else if metricSpec.Object.Target.Type == autoscalingv2.AverageValueMetricType {
|
} else if metricSpec.Object.Target.Type == autoscalingv2.AverageValueMetricType {
|
||||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetObjectPerPodMetricReplicas(statusReplicas, metricSpec.Object.Target.AverageValue.MilliValue(), metricSpec.Object.Metric.Name, hpa.Namespace, &metricSpec.Object.DescribedObject, metricSelector)
|
replicaCountProposal, usageProposal, timestampProposal, err := a.replicaCalc.GetObjectPerPodMetricReplicas(statusReplicas, metricSpec.Object.Target.AverageValue.MilliValue(), metricSpec.Object.Metric.Name, hpa.Namespace, &metricSpec.Object.DescribedObject, metricSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
condition := a.getUnableComputeReplicaCountCondition(hpa, "FailedGetObjectMetric", err)
|
condition := a.getUnableComputeReplicaCountCondition(hpa, "FailedGetObjectMetric", err)
|
||||||
return 0, time.Time{}, "", condition, fmt.Errorf("failed to get %s object metric: %v", metricSpec.Object.Metric.Name, err)
|
return 0, time.Time{}, "", condition, fmt.Errorf("failed to get %s object metric: %v", metricSpec.Object.Metric.Name, err)
|
||||||
@ -406,7 +406,7 @@ func (a *HorizontalController) computeStatusForObjectMetric(specReplicas, status
|
|||||||
Selector: metricSpec.Object.Metric.Selector,
|
Selector: metricSpec.Object.Metric.Selector,
|
||||||
},
|
},
|
||||||
Current: autoscalingv2.MetricValueStatus{
|
Current: autoscalingv2.MetricValueStatus{
|
||||||
AverageValue: resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
AverageValue: resource.NewMilliQuantity(usageProposal, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -420,7 +420,7 @@ func (a *HorizontalController) computeStatusForObjectMetric(specReplicas, status
|
|||||||
|
|
||||||
// computeStatusForPodsMetric computes the desired number of replicas for the specified metric of type PodsMetricSourceType.
|
// computeStatusForPodsMetric computes the desired number of replicas for the specified metric of type PodsMetricSourceType.
|
||||||
func (a *HorizontalController) computeStatusForPodsMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus, metricSelector labels.Selector) (replicaCountProposal int32, timestampProposal time.Time, metricNameProposal string, condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) {
|
func (a *HorizontalController) computeStatusForPodsMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus, metricSelector labels.Selector) (replicaCountProposal int32, timestampProposal time.Time, metricNameProposal string, condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) {
|
||||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetMetricReplicas(currentReplicas, metricSpec.Pods.Target.AverageValue.MilliValue(), metricSpec.Pods.Metric.Name, hpa.Namespace, selector, metricSelector)
|
replicaCountProposal, usageProposal, timestampProposal, err := a.replicaCalc.GetMetricReplicas(currentReplicas, metricSpec.Pods.Target.AverageValue.MilliValue(), metricSpec.Pods.Metric.Name, hpa.Namespace, selector, metricSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetPodsMetric", err)
|
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetPodsMetric", err)
|
||||||
return 0, timestampProposal, "", condition, err
|
return 0, timestampProposal, "", condition, err
|
||||||
@ -433,7 +433,7 @@ func (a *HorizontalController) computeStatusForPodsMetric(currentReplicas int32,
|
|||||||
Selector: metricSpec.Pods.Metric.Selector,
|
Selector: metricSpec.Pods.Metric.Selector,
|
||||||
},
|
},
|
||||||
Current: autoscalingv2.MetricValueStatus{
|
Current: autoscalingv2.MetricValueStatus{
|
||||||
AverageValue: resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
AverageValue: resource.NewMilliQuantity(usageProposal, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -449,7 +449,7 @@ func (a *HorizontalController) computeStatusForResourceMetricGeneric(ctx context
|
|||||||
var rawProposal int64
|
var rawProposal int64
|
||||||
replicaCountProposal, rawProposal, timestampProposal, err := a.replicaCalc.GetRawResourceReplicas(ctx, currentReplicas, target.AverageValue.MilliValue(), resourceName, namespace, selector, container)
|
replicaCountProposal, rawProposal, timestampProposal, err := a.replicaCalc.GetRawResourceReplicas(ctx, currentReplicas, target.AverageValue.MilliValue(), resourceName, namespace, selector, container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, time.Time{}, "", condition, fmt.Errorf("failed to get %s utilization: %v", resourceName, err)
|
return 0, nil, time.Time{}, "", condition, fmt.Errorf("failed to get %s usage: %v", resourceName, err)
|
||||||
}
|
}
|
||||||
metricNameProposal = fmt.Sprintf("%s resource", resourceName.String())
|
metricNameProposal = fmt.Sprintf("%s resource", resourceName.String())
|
||||||
status := autoscalingv2.MetricValueStatus{
|
status := autoscalingv2.MetricValueStatus{
|
||||||
@ -459,7 +459,7 @@ func (a *HorizontalController) computeStatusForResourceMetricGeneric(ctx context
|
|||||||
}
|
}
|
||||||
|
|
||||||
if target.AverageUtilization == nil {
|
if target.AverageUtilization == nil {
|
||||||
errMsg := "invalid resource metric source: neither an average utilization target nor an average value target was set"
|
errMsg := "invalid resource metric source: neither an average utilization target nor an average value (usage) target was set"
|
||||||
return 0, nil, time.Time{}, "", condition, fmt.Errorf(errMsg)
|
return 0, nil, time.Time{}, "", condition, fmt.Errorf(errMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,7 +519,7 @@ func (a *HorizontalController) computeStatusForContainerResourceMetric(ctx conte
|
|||||||
// computeStatusForExternalMetric computes the desired number of replicas for the specified metric of type ExternalMetricSourceType.
|
// computeStatusForExternalMetric computes the desired number of replicas for the specified metric of type ExternalMetricSourceType.
|
||||||
func (a *HorizontalController) computeStatusForExternalMetric(specReplicas, statusReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus) (replicaCountProposal int32, timestampProposal time.Time, metricNameProposal string, condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) {
|
func (a *HorizontalController) computeStatusForExternalMetric(specReplicas, statusReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus) (replicaCountProposal int32, timestampProposal time.Time, metricNameProposal string, condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) {
|
||||||
if metricSpec.External.Target.AverageValue != nil {
|
if metricSpec.External.Target.AverageValue != nil {
|
||||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetExternalPerPodMetricReplicas(statusReplicas, metricSpec.External.Target.AverageValue.MilliValue(), metricSpec.External.Metric.Name, hpa.Namespace, metricSpec.External.Metric.Selector)
|
replicaCountProposal, usageProposal, timestampProposal, err := a.replicaCalc.GetExternalPerPodMetricReplicas(statusReplicas, metricSpec.External.Target.AverageValue.MilliValue(), metricSpec.External.Metric.Name, hpa.Namespace, metricSpec.External.Metric.Selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetExternalMetric", err)
|
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetExternalMetric", err)
|
||||||
return 0, time.Time{}, "", condition, fmt.Errorf("failed to get %s external metric: %v", metricSpec.External.Metric.Name, err)
|
return 0, time.Time{}, "", condition, fmt.Errorf("failed to get %s external metric: %v", metricSpec.External.Metric.Name, err)
|
||||||
@ -532,14 +532,14 @@ func (a *HorizontalController) computeStatusForExternalMetric(specReplicas, stat
|
|||||||
Selector: metricSpec.External.Metric.Selector,
|
Selector: metricSpec.External.Metric.Selector,
|
||||||
},
|
},
|
||||||
Current: autoscalingv2.MetricValueStatus{
|
Current: autoscalingv2.MetricValueStatus{
|
||||||
AverageValue: resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
AverageValue: resource.NewMilliQuantity(usageProposal, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("external metric %s(%+v)", metricSpec.External.Metric.Name, metricSpec.External.Metric.Selector), autoscalingv2.HorizontalPodAutoscalerCondition{}, nil
|
return replicaCountProposal, timestampProposal, fmt.Sprintf("external metric %s(%+v)", metricSpec.External.Metric.Name, metricSpec.External.Metric.Selector), autoscalingv2.HorizontalPodAutoscalerCondition{}, nil
|
||||||
}
|
}
|
||||||
if metricSpec.External.Target.Value != nil {
|
if metricSpec.External.Target.Value != nil {
|
||||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetExternalMetricReplicas(specReplicas, metricSpec.External.Target.Value.MilliValue(), metricSpec.External.Metric.Name, hpa.Namespace, metricSpec.External.Metric.Selector, selector)
|
replicaCountProposal, usageProposal, timestampProposal, err := a.replicaCalc.GetExternalMetricReplicas(specReplicas, metricSpec.External.Target.Value.MilliValue(), metricSpec.External.Metric.Name, hpa.Namespace, metricSpec.External.Metric.Selector, selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetExternalMetric", err)
|
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetExternalMetric", err)
|
||||||
return 0, time.Time{}, "", condition, fmt.Errorf("failed to get external metric %s: %v", metricSpec.External.Metric.Name, err)
|
return 0, time.Time{}, "", condition, fmt.Errorf("failed to get external metric %s: %v", metricSpec.External.Metric.Name, err)
|
||||||
@ -552,7 +552,7 @@ func (a *HorizontalController) computeStatusForExternalMetric(specReplicas, stat
|
|||||||
Selector: metricSpec.External.Metric.Selector,
|
Selector: metricSpec.External.Metric.Selector,
|
||||||
},
|
},
|
||||||
Current: autoscalingv2.MetricValueStatus{
|
Current: autoscalingv2.MetricValueStatus{
|
||||||
Value: resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
Value: resource.NewMilliQuantity(usageProposal, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -51,16 +51,16 @@ func GetResourceUtilizationRatio(metrics PodMetricsInfo, requests map[string]int
|
|||||||
return float64(currentUtilization) / float64(targetUtilization), currentUtilization, metricsTotal / int64(numEntries), nil
|
return float64(currentUtilization) / float64(targetUtilization), currentUtilization, metricsTotal / int64(numEntries), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricUtilizationRatio takes in a set of metrics and a target utilization value,
|
// GetMetricUsageRatio takes in a set of metrics and a target usage value,
|
||||||
// and calculates the ratio of desired to actual utilization
|
// and calculates the ratio of desired to actual usage
|
||||||
// (returning that and the actual utilization)
|
// (returning that and the actual usage)
|
||||||
func GetMetricUtilizationRatio(metrics PodMetricsInfo, targetUtilization int64) (utilizationRatio float64, currentUtilization int64) {
|
func GetMetricUsageRatio(metrics PodMetricsInfo, targetUsage int64) (usageRatio float64, currentUsage int64) {
|
||||||
metricsTotal := int64(0)
|
metricsTotal := int64(0)
|
||||||
for _, metric := range metrics {
|
for _, metric := range metrics {
|
||||||
metricsTotal += metric.Value
|
metricsTotal += metric.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
currentUtilization = metricsTotal / int64(len(metrics))
|
currentUsage = metricsTotal / int64(len(metrics))
|
||||||
|
|
||||||
return float64(currentUtilization) / float64(targetUtilization), currentUtilization
|
return float64(currentUsage) / float64(targetUsage), currentUsage
|
||||||
}
|
}
|
||||||
|
@ -49,19 +49,19 @@ func (tc *resourceUtilizationRatioTestCase) runTest(t *testing.T) {
|
|||||||
assert.Equal(t, tc.expectedRawAverageValue, actualRawAverageValue, "the raw average value should be as expected")
|
assert.Equal(t, tc.expectedRawAverageValue, actualRawAverageValue, "the raw average value should be as expected")
|
||||||
}
|
}
|
||||||
|
|
||||||
type metricUtilizationRatioTestCase struct {
|
type metricUsageRatioTestCase struct {
|
||||||
metrics PodMetricsInfo
|
metrics PodMetricsInfo
|
||||||
targetUtilization int64
|
targetUsage int64
|
||||||
|
|
||||||
expectedUtilizationRatio float64
|
expectedUsageRatio float64
|
||||||
expectedCurrentUtilization int64
|
expectedCurrentUsage int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *metricUtilizationRatioTestCase) runTest(t *testing.T) {
|
func (tc *metricUsageRatioTestCase) runTest(t *testing.T) {
|
||||||
actualUtilizationRatio, actualCurrentUtilization := GetMetricUtilizationRatio(tc.metrics, tc.targetUtilization)
|
actualUsageRatio, actualCurrentUsage := GetMetricUsageRatio(tc.metrics, tc.targetUsage)
|
||||||
|
|
||||||
assert.Equal(t, tc.expectedUtilizationRatio, actualUtilizationRatio, "the utilization ratios should be as expected")
|
assert.Equal(t, tc.expectedUsageRatio, actualUsageRatio, "the usage ratios should be as expected")
|
||||||
assert.Equal(t, tc.expectedCurrentUtilization, actualCurrentUtilization, "the current utilization should be as expected")
|
assert.Equal(t, tc.expectedCurrentUsage, actualCurrentUsage, "the current usage should be as expected")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetResourceUtilizationRatioBaseCase(t *testing.T) {
|
func TestGetResourceUtilizationRatioBaseCase(t *testing.T) {
|
||||||
@ -135,14 +135,14 @@ func TestGetResourceUtilizationRatioNoRequests(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetMetricUtilizationRatioBaseCase(t *testing.T) {
|
func TestGetMetricUsageRatioBaseCase(t *testing.T) {
|
||||||
tc := metricUtilizationRatioTestCase{
|
tc := metricUsageRatioTestCase{
|
||||||
metrics: PodMetricsInfo{
|
metrics: PodMetricsInfo{
|
||||||
"test-pod-0": {Value: 5000}, "test-pod-1": {Value: 10000},
|
"test-pod-0": {Value: 5000}, "test-pod-1": {Value: 10000},
|
||||||
},
|
},
|
||||||
targetUtilization: 10000,
|
targetUsage: 10000,
|
||||||
expectedUtilizationRatio: .75,
|
expectedUsageRatio: .75,
|
||||||
expectedCurrentUtilization: 7500,
|
expectedCurrentUsage: 7500,
|
||||||
}
|
}
|
||||||
|
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
|
@ -149,33 +149,33 @@ func (c *ReplicaCalculator) GetResourceReplicas(ctx context.Context, currentRepl
|
|||||||
return newReplicas, utilization, rawUtilization, timestamp, nil
|
return newReplicas, utilization, rawUtilization, timestamp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRawResourceReplicas calculates the desired replica count based on a target resource utilization (as a raw milli-value)
|
// GetRawResourceReplicas calculates the desired replica count based on a target resource usage (as a raw milli-value)
|
||||||
// for pods matching the given selector in the given namespace, and the current replica count
|
// for pods matching the given selector in the given namespace, and the current replica count
|
||||||
func (c *ReplicaCalculator) GetRawResourceReplicas(ctx context.Context, currentReplicas int32, targetUsage int64, resource v1.ResourceName, namespace string, selector labels.Selector, container string) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
func (c *ReplicaCalculator) GetRawResourceReplicas(ctx context.Context, currentReplicas int32, targetUsage int64, resource v1.ResourceName, namespace string, selector labels.Selector, container string) (replicaCount int32, usage int64, timestamp time.Time, err error) {
|
||||||
metrics, timestamp, err := c.metricsClient.GetResourceMetric(ctx, resource, namespace, selector, container)
|
metrics, timestamp, err := c.metricsClient.GetResourceMetric(ctx, resource, namespace, selector, container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, time.Time{}, fmt.Errorf("unable to get metrics for resource %s: %v", resource, err)
|
return 0, 0, time.Time{}, fmt.Errorf("unable to get metrics for resource %s: %v", resource, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
replicaCount, utilization, err = c.calcPlainMetricReplicas(metrics, currentReplicas, targetUsage, namespace, selector, resource)
|
replicaCount, usage, err = c.calcPlainMetricReplicas(metrics, currentReplicas, targetUsage, namespace, selector, resource)
|
||||||
return replicaCount, utilization, timestamp, err
|
return replicaCount, usage, timestamp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricReplicas calculates the desired replica count based on a target metric utilization
|
// GetMetricReplicas calculates the desired replica count based on a target metric usage
|
||||||
// (as a milli-value) for pods matching the given selector in the given namespace, and the
|
// (as a milli-value) for pods matching the given selector in the given namespace, and the
|
||||||
// current replica count
|
// current replica count
|
||||||
func (c *ReplicaCalculator) GetMetricReplicas(currentReplicas int32, targetUsage int64, metricName string, namespace string, selector labels.Selector, metricSelector labels.Selector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
func (c *ReplicaCalculator) GetMetricReplicas(currentReplicas int32, targetUsage int64, metricName string, namespace string, selector labels.Selector, metricSelector labels.Selector) (replicaCount int32, usage int64, timestamp time.Time, err error) {
|
||||||
metrics, timestamp, err := c.metricsClient.GetRawMetric(metricName, namespace, selector, metricSelector)
|
metrics, timestamp, err := c.metricsClient.GetRawMetric(metricName, namespace, selector, metricSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, time.Time{}, fmt.Errorf("unable to get metric %s: %v", metricName, err)
|
return 0, 0, time.Time{}, fmt.Errorf("unable to get metric %s: %v", metricName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
replicaCount, utilization, err = c.calcPlainMetricReplicas(metrics, currentReplicas, targetUsage, namespace, selector, v1.ResourceName(""))
|
replicaCount, usage, err = c.calcPlainMetricReplicas(metrics, currentReplicas, targetUsage, namespace, selector, v1.ResourceName(""))
|
||||||
return replicaCount, utilization, timestamp, err
|
return replicaCount, usage, timestamp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// calcPlainMetricReplicas calculates the desired replicas for plain (i.e. non-utilization percentage) metrics.
|
// calcPlainMetricReplicas calculates the desired replicas for plain (i.e. non-utilization percentage) metrics.
|
||||||
func (c *ReplicaCalculator) calcPlainMetricReplicas(metrics metricsclient.PodMetricsInfo, currentReplicas int32, targetUsage int64, namespace string, selector labels.Selector, resource v1.ResourceName) (replicaCount int32, utilization int64, err error) {
|
func (c *ReplicaCalculator) calcPlainMetricReplicas(metrics metricsclient.PodMetricsInfo, currentReplicas int32, targetUsage int64, namespace string, selector labels.Selector, resource v1.ResourceName) (replicaCount int32, usage int64, err error) {
|
||||||
|
|
||||||
podList, err := c.podLister.Pods(namespace).List(selector)
|
podList, err := c.podLister.Pods(namespace).List(selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -194,18 +194,18 @@ func (c *ReplicaCalculator) calcPlainMetricReplicas(metrics metricsclient.PodMet
|
|||||||
return 0, 0, fmt.Errorf("did not receive metrics for any ready pods")
|
return 0, 0, fmt.Errorf("did not receive metrics for any ready pods")
|
||||||
}
|
}
|
||||||
|
|
||||||
usageRatio, utilization := metricsclient.GetMetricUtilizationRatio(metrics, targetUsage)
|
usageRatio, usage := metricsclient.GetMetricUsageRatio(metrics, targetUsage)
|
||||||
|
|
||||||
scaleUpWithUnready := len(unreadyPods) > 0 && usageRatio > 1.0
|
scaleUpWithUnready := len(unreadyPods) > 0 && usageRatio > 1.0
|
||||||
|
|
||||||
if !scaleUpWithUnready && len(missingPods) == 0 {
|
if !scaleUpWithUnready && len(missingPods) == 0 {
|
||||||
if math.Abs(1.0-usageRatio) <= c.tolerance {
|
if math.Abs(1.0-usageRatio) <= c.tolerance {
|
||||||
// return the current replicas if the change would be too small
|
// return the current replicas if the change would be too small
|
||||||
return currentReplicas, utilization, nil
|
return currentReplicas, usage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we don't have any unready or missing pods, we can calculate the new replica count now
|
// if we don't have any unready or missing pods, we can calculate the new replica count now
|
||||||
return int32(math.Ceil(usageRatio * float64(readyPodCount))), utilization, nil
|
return int32(math.Ceil(usageRatio * float64(readyPodCount))), usage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(missingPods) > 0 {
|
if len(missingPods) > 0 {
|
||||||
@ -229,37 +229,37 @@ func (c *ReplicaCalculator) calcPlainMetricReplicas(metrics metricsclient.PodMet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-run the utilization calculation with our new numbers
|
// re-run the usage calculation with our new numbers
|
||||||
newUsageRatio, _ := metricsclient.GetMetricUtilizationRatio(metrics, targetUsage)
|
newUsageRatio, _ := metricsclient.GetMetricUsageRatio(metrics, targetUsage)
|
||||||
|
|
||||||
if math.Abs(1.0-newUsageRatio) <= c.tolerance || (usageRatio < 1.0 && newUsageRatio > 1.0) || (usageRatio > 1.0 && newUsageRatio < 1.0) {
|
if math.Abs(1.0-newUsageRatio) <= c.tolerance || (usageRatio < 1.0 && newUsageRatio > 1.0) || (usageRatio > 1.0 && newUsageRatio < 1.0) {
|
||||||
// return the current replicas if the change would be too small,
|
// return the current replicas if the change would be too small,
|
||||||
// or if the new usage ratio would cause a change in scale direction
|
// or if the new usage ratio would cause a change in scale direction
|
||||||
return currentReplicas, utilization, nil
|
return currentReplicas, usage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
newReplicas := int32(math.Ceil(newUsageRatio * float64(len(metrics))))
|
newReplicas := int32(math.Ceil(newUsageRatio * float64(len(metrics))))
|
||||||
if (newUsageRatio < 1.0 && newReplicas > currentReplicas) || (newUsageRatio > 1.0 && newReplicas < currentReplicas) {
|
if (newUsageRatio < 1.0 && newReplicas > currentReplicas) || (newUsageRatio > 1.0 && newReplicas < currentReplicas) {
|
||||||
// return the current replicas if the change of metrics length would cause a change in scale direction
|
// return the current replicas if the change of metrics length would cause a change in scale direction
|
||||||
return currentReplicas, utilization, nil
|
return currentReplicas, usage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the result, where the number of replicas considered is
|
// return the result, where the number of replicas considered is
|
||||||
// however many replicas factored into our calculation
|
// however many replicas factored into our calculation
|
||||||
return newReplicas, utilization, nil
|
return newReplicas, usage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObjectMetricReplicas calculates the desired replica count based on a target metric utilization (as a milli-value)
|
// GetObjectMetricReplicas calculates the desired replica count based on a target metric usage (as a milli-value)
|
||||||
// for the given object in the given namespace, and the current replica count.
|
// for the given object in the given namespace, and the current replica count.
|
||||||
func (c *ReplicaCalculator) GetObjectMetricReplicas(currentReplicas int32, targetUsage int64, metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, selector labels.Selector, metricSelector labels.Selector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
func (c *ReplicaCalculator) GetObjectMetricReplicas(currentReplicas int32, targetUsage int64, metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, selector labels.Selector, metricSelector labels.Selector) (replicaCount int32, usage int64, timestamp time.Time, err error) {
|
||||||
utilization, _, err = c.metricsClient.GetObjectMetric(metricName, namespace, objectRef, metricSelector)
|
usage, _, err = c.metricsClient.GetObjectMetric(metricName, namespace, objectRef, metricSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, time.Time{}, fmt.Errorf("unable to get metric %s: %v on %s %s/%s", metricName, objectRef.Kind, namespace, objectRef.Name, err)
|
return 0, 0, time.Time{}, fmt.Errorf("unable to get metric %s: %v on %s %s/%s", metricName, objectRef.Kind, namespace, objectRef.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
usageRatio := float64(utilization) / float64(targetUsage)
|
usageRatio := float64(usage) / float64(targetUsage)
|
||||||
replicaCount, timestamp, err = c.getUsageRatioReplicaCount(currentReplicas, usageRatio, namespace, selector)
|
replicaCount, timestamp, err = c.getUsageRatioReplicaCount(currentReplicas, usageRatio, namespace, selector)
|
||||||
return replicaCount, utilization, timestamp, err
|
return replicaCount, usage, timestamp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// getUsageRatioReplicaCount calculates the desired replica count based on usageRatio and ready pods count.
|
// getUsageRatioReplicaCount calculates the desired replica count based on usageRatio and ready pods count.
|
||||||
@ -284,22 +284,22 @@ func (c *ReplicaCalculator) getUsageRatioReplicaCount(currentReplicas int32, usa
|
|||||||
return replicaCount, timestamp, err
|
return replicaCount, timestamp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObjectPerPodMetricReplicas calculates the desired replica count based on a target metric utilization (as a milli-value)
|
// GetObjectPerPodMetricReplicas calculates the desired replica count based on a target metric usage (as a milli-value)
|
||||||
// for the given object in the given namespace, and the current replica count.
|
// for the given object in the given namespace, and the current replica count.
|
||||||
func (c *ReplicaCalculator) GetObjectPerPodMetricReplicas(statusReplicas int32, targetAverageUtilization int64, metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, metricSelector labels.Selector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
func (c *ReplicaCalculator) GetObjectPerPodMetricReplicas(statusReplicas int32, targetAverageUsage int64, metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, metricSelector labels.Selector) (replicaCount int32, usage int64, timestamp time.Time, err error) {
|
||||||
utilization, timestamp, err = c.metricsClient.GetObjectMetric(metricName, namespace, objectRef, metricSelector)
|
usage, timestamp, err = c.metricsClient.GetObjectMetric(metricName, namespace, objectRef, metricSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, time.Time{}, fmt.Errorf("unable to get metric %s: %v on %s %s/%s", metricName, objectRef.Kind, namespace, objectRef.Name, err)
|
return 0, 0, time.Time{}, fmt.Errorf("unable to get metric %s: %v on %s %s/%s", metricName, objectRef.Kind, namespace, objectRef.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
replicaCount = statusReplicas
|
replicaCount = statusReplicas
|
||||||
usageRatio := float64(utilization) / (float64(targetAverageUtilization) * float64(replicaCount))
|
usageRatio := float64(usage) / (float64(targetAverageUsage) * float64(replicaCount))
|
||||||
if math.Abs(1.0-usageRatio) > c.tolerance {
|
if math.Abs(1.0-usageRatio) > c.tolerance {
|
||||||
// update number of replicas if change is large enough
|
// update number of replicas if change is large enough
|
||||||
replicaCount = int32(math.Ceil(float64(utilization) / float64(targetAverageUtilization)))
|
replicaCount = int32(math.Ceil(float64(usage) / float64(targetAverageUsage)))
|
||||||
}
|
}
|
||||||
utilization = int64(math.Ceil(float64(utilization) / float64(statusReplicas)))
|
usage = int64(math.Ceil(float64(usage) / float64(statusReplicas)))
|
||||||
return replicaCount, utilization, timestamp, nil
|
return replicaCount, usage, timestamp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO(mattjmcnaughton) Many different functions in this module use variations
|
// @TODO(mattjmcnaughton) Many different functions in this module use variations
|
||||||
@ -329,7 +329,7 @@ func (c *ReplicaCalculator) getReadyPodsCount(namespace string, selector labels.
|
|||||||
// GetExternalMetricReplicas calculates the desired replica count based on a
|
// GetExternalMetricReplicas calculates the desired replica count based on a
|
||||||
// target metric value (as a milli-value) for the external metric in the given
|
// target metric value (as a milli-value) for the external metric in the given
|
||||||
// namespace, and the current replica count.
|
// namespace, and the current replica count.
|
||||||
func (c *ReplicaCalculator) GetExternalMetricReplicas(currentReplicas int32, targetUsage int64, metricName, namespace string, metricSelector *metav1.LabelSelector, podSelector labels.Selector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
func (c *ReplicaCalculator) GetExternalMetricReplicas(currentReplicas int32, targetUsage int64, metricName, namespace string, metricSelector *metav1.LabelSelector, podSelector labels.Selector) (replicaCount int32, usage int64, timestamp time.Time, err error) {
|
||||||
metricLabelSelector, err := metav1.LabelSelectorAsSelector(metricSelector)
|
metricLabelSelector, err := metav1.LabelSelectorAsSelector(metricSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, time.Time{}, err
|
return 0, 0, time.Time{}, err
|
||||||
@ -338,20 +338,20 @@ func (c *ReplicaCalculator) GetExternalMetricReplicas(currentReplicas int32, tar
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, time.Time{}, fmt.Errorf("unable to get external metric %s/%s/%+v: %s", namespace, metricName, metricSelector, err)
|
return 0, 0, time.Time{}, fmt.Errorf("unable to get external metric %s/%s/%+v: %s", namespace, metricName, metricSelector, err)
|
||||||
}
|
}
|
||||||
utilization = 0
|
usage = 0
|
||||||
for _, val := range metrics {
|
for _, val := range metrics {
|
||||||
utilization = utilization + val
|
usage = usage + val
|
||||||
}
|
}
|
||||||
|
|
||||||
usageRatio := float64(utilization) / float64(targetUsage)
|
usageRatio := float64(usage) / float64(targetUsage)
|
||||||
replicaCount, timestamp, err = c.getUsageRatioReplicaCount(currentReplicas, usageRatio, namespace, podSelector)
|
replicaCount, timestamp, err = c.getUsageRatioReplicaCount(currentReplicas, usageRatio, namespace, podSelector)
|
||||||
return replicaCount, utilization, timestamp, err
|
return replicaCount, usage, timestamp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExternalPerPodMetricReplicas calculates the desired replica count based on a
|
// GetExternalPerPodMetricReplicas calculates the desired replica count based on a
|
||||||
// target metric value per pod (as a milli-value) for the external metric in the
|
// target metric value per pod (as a milli-value) for the external metric in the
|
||||||
// given namespace, and the current replica count.
|
// given namespace, and the current replica count.
|
||||||
func (c *ReplicaCalculator) GetExternalPerPodMetricReplicas(statusReplicas int32, targetUsagePerPod int64, metricName, namespace string, metricSelector *metav1.LabelSelector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
func (c *ReplicaCalculator) GetExternalPerPodMetricReplicas(statusReplicas int32, targetUsagePerPod int64, metricName, namespace string, metricSelector *metav1.LabelSelector) (replicaCount int32, usage int64, timestamp time.Time, err error) {
|
||||||
metricLabelSelector, err := metav1.LabelSelectorAsSelector(metricSelector)
|
metricLabelSelector, err := metav1.LabelSelectorAsSelector(metricSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, time.Time{}, err
|
return 0, 0, time.Time{}, err
|
||||||
@ -360,19 +360,19 @@ func (c *ReplicaCalculator) GetExternalPerPodMetricReplicas(statusReplicas int32
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, time.Time{}, fmt.Errorf("unable to get external metric %s/%s/%+v: %s", namespace, metricName, metricSelector, err)
|
return 0, 0, time.Time{}, fmt.Errorf("unable to get external metric %s/%s/%+v: %s", namespace, metricName, metricSelector, err)
|
||||||
}
|
}
|
||||||
utilization = 0
|
usage = 0
|
||||||
for _, val := range metrics {
|
for _, val := range metrics {
|
||||||
utilization = utilization + val
|
usage = usage + val
|
||||||
}
|
}
|
||||||
|
|
||||||
replicaCount = statusReplicas
|
replicaCount = statusReplicas
|
||||||
usageRatio := float64(utilization) / (float64(targetUsagePerPod) * float64(replicaCount))
|
usageRatio := float64(usage) / (float64(targetUsagePerPod) * float64(replicaCount))
|
||||||
if math.Abs(1.0-usageRatio) > c.tolerance {
|
if math.Abs(1.0-usageRatio) > c.tolerance {
|
||||||
// update number of replicas if the change is large enough
|
// update number of replicas if the change is large enough
|
||||||
replicaCount = int32(math.Ceil(float64(utilization) / float64(targetUsagePerPod)))
|
replicaCount = int32(math.Ceil(float64(usage) / float64(targetUsagePerPod)))
|
||||||
}
|
}
|
||||||
utilization = int64(math.Ceil(float64(utilization) / float64(statusReplicas)))
|
usage = int64(math.Ceil(float64(usage) / float64(statusReplicas)))
|
||||||
return replicaCount, utilization, timestamp, nil
|
return replicaCount, usage, timestamp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func groupPods(pods []*v1.Pod, metrics metricsclient.PodMetricsInfo, resource v1.ResourceName, cpuInitializationPeriod, delayOfInitialReadinessStatus time.Duration) (readyPodCount int, unreadyPods, missingPods, ignoredPods sets.String) {
|
func groupPods(pods []*v1.Pod, metrics metricsclient.PodMetricsInfo, resource v1.ResourceName, cpuInitializationPeriod, delayOfInitialReadinessStatus time.Duration) (readyPodCount int, unreadyPods, missingPods, ignoredPods sets.String) {
|
||||||
|
Loading…
Reference in New Issue
Block a user