kubernetes: Cannot update HPA objects using object metrics with AverageValue
What happened:
When attempting to label a HorizontalPodAutoscaler (autoscaling/v2beta2) object that has an object metric using AverageValue, received the following error:
The HorizontalPodAutoscaler "<hpa-name>" is invalid: spec.metrics[0].object.target.value: Invalid value: resource.Quantity{i:resource.int64Amount{value:0, scale:0}, d:resource.infDecAmount{Dec:(*inf.Dec)(nil)}, s:"0", Format:"DecimalSI"}: must be positive
What you expected to happen:
The label command should properly label the HPA object with no errors, since the HPA was able to build and run without errors.
How to reproduce it (as minimally and precisely as possible):
- Create a hpa.v2beta2.autoscaling object that includes the following metric:
- object:
describedObject:
kind: Service
name: svc-name
metric:
name: metric-name:sum
target:
averageValue: 4650
type: AverageValue
type: Object
Make sure that you’re using AverageValue and don’t have a Value set.
- Run the following command:
kubectl label hpa hpa_name -n namespace_name testlabel=test
Anything else we need to know?:
We were able to build and apply the HPA object without encountering any errors, and it appears to be scaling properly. This error only happens when calling kubectl label on the existing HPA object.
Environment:
- Kubernetes version (use
kubectl version): tried in both 1.15.3 and 1.16.4 - Cloud provider or hardware configuration: AWS
- OS (e.g:
cat /etc/os-release): darwin/amd64 - Kernel (e.g.
uname -a): Darwin Kernel Version 17.7.0: Fri Jul 6 19:54:51 PDT 2018; root:xnu-4570.71.3~2/RELEASE_X86_64 x86_64
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 12
- Comments: 53 (22 by maintainers)
Hitting this issue as well. There is a workaround tho
Then spot every
spec.metrics.*.objectthat usesAverageValue. Remove the.value( that in my case is always"0").After that, you can freely edit w/e you want from the rest of the document. The bad news, the
.value: "0"returns after saving, so you need to delete it every time you want to edit again.@k8s-triage-robot: Closing this issue.
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.
I meet the same question in k8s 1.22 , and debug it
when create v2beta2 hpa
apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: sample-app namespace: default spec: maxReplicas: 10 metrics: - object: describedObject: kind: Service name: sample-app metric: name: http_requests_count target: averageValue: "1" type: AverageValue type: Object minReplicas: 7 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: sample-appand the object send to kube-apiserver , and v2beta2 hpa convert to internal hpa object. when read the internal hpa obj to v1 hpa obj, because metrics switch to annotation to the v1 hpa object, we can found the annotaion
apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: annotations: autoscaling.alpha.kubernetes.io/conditions: '[{"type":"AbleToScale","status":"False","lastTransitionTime":"2022-09-29T12:31:03Z","reason":"FailedGetScale","message":"the HPA controller was unable to get the target''s current scale: deployments/scale.apps \"sample-app\" not found"}]' autoscaling.alpha.kubernetes.io/metrics: '[{"type":"Object","object":{"target":{"kind":"Service","name":"sample-app"},"metricName":"http_requests_count","targetValue":"0","averageValue":"1"}}]' creationTimestamp: "2022-09-29T12:30:48Z" name: sample-app namespace: default resourceVersion: "9314762"in annotion exist “targetValue”:“0”
In v1 hpa define in vendor/k8s.io/api/autoscaling/v1/types.go:227, the TargetValue is resource.Quantity type.
type ObjectMetricSource struct { // target is the described Kubernetes object. Target CrossVersionObjectReference `json:"target" protobuf:"bytes,1,name=target"` // metricName is the name of the metric in question. MetricName string `json:"metricName" protobuf:"bytes,2,name=metricName"` // targetValue is the target value of the metric (as a quantity). TargetValue resource.Quantity `json:"targetValue" protobuf:"bytes,3,name=targetValue"`` --- }and in v2beta2 hpa define in vendor/k8s.io/api/autoscaling/v2beta2/types.go:320, the TargetValue is *resource.Quantity type.
// MetricTarget defines the target value, average value, or average utilization of a specific metric type MetricTarget struct { // type represents whether the metric type is Utilization, Value, or AverageValue Type MetricTargetType `json:"type" protobuf:"bytes,1,name=type"` // value is the target value of the metric (as a quantity). // +optional Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` // averageValue is the target value of the average of the // metric across all relevant pods (as a quantity) // +optional AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,3,opt,name=averageValue"` // averageUtilization is the target value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. // Currently only valid for Resource metric source type // +optional AverageUtilization *int32 `json:"averageUtilization,omitempty" protobuf:"bytes,4,opt,name=averageUtilization"` }the TargetValue is not * v1, and in v2beta2 hpa TargetValue is *.
then , the annotation of v1 hpa object will convert to internal hpa object, the “targetValue”:“0” in anntation be convert to internal hpa object, the target value is set to 0 not the nil
debug the problem in k8s 1.22.9 can fix the problem
diff --git a/pkg/apis/autoscaling/v1/conversion.go b/pkg/apis/autoscaling/v1/conversion.go index bf94d48ae17..09fd8f9f337 100644 --- a/pkg/apis/autoscaling/v1/conversion.go +++ b/pkg/apis/autoscaling/v1/conversion.go @@ -90,9 +90,13 @@ func Convert_v1_ObjectMetricSource_To_autoscaling_ObjectMetricSource(in *autosca out.Target = autoscaling.MetricTarget{ Type: metricType, - Value: &in.TargetValue, AverageValue: in.AverageValue, } + + if in.TargetValue.Value() != 0 { + out.Target.Value = &in.TargetValue + } + out.DescribedObject = autoscaling.CrossVersionObjectReference{ Kind: in.Target.Kind, Name: in.Target.Name,@egoroof: You can’t reopen an issue/PR unless you authored it or you are a collaborator.
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.
Is there an update to this problem? We were using v2beta2 and switched to v2. We now get the same error we apply a helm deployment to the service that has an HPA with an Object resource.
We’ve deleted all the HPA’s manually and redeploying with helm works. Except its building the Object reference like this
If we try to do a helm upgrade install after this to the same service, it fails with the same error.
The work around suggested by setting the value of
valueto 1 sounds like it should work and not interferre with our type of AverageValue. But why isvalueneeded if we are not using the type ofValue. This seems like a major oversight and redundant to include values if not in use if this is intended.I using AverageValue target type, not Value - this is all about what this issue is. For AverageValue target type “averageValue” property used, “value” property is just ignored by AverageValue target type. My metric object look like this:
Your example above have different schema, it seems you are using different API version of HPA
Unfortunatelly, this workaround not very aplicable for our workflow with automated HPA updates. So I just set
spec.metrics[0].object.target.valueproperty to “1” - and it seems works, satisfying that mistaken validation rule and being just ignored for AverageValueThe Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.
This bot triages issues and PRs according to the following rules:
lifecycle/staleis appliedlifecycle/stalewas applied,lifecycle/rottenis appliedlifecycle/rottenwas applied, the issue is closedYou can:
/reopen/remove-lifecycle rottenPlease send feedback to sig-contributor-experience at kubernetes/community.
/close
Encountering the same issue, it breaks our CI pipeline. Can we reopen this?
Encountering the same error, are there any updates?
An update: this doesn’t only affect the
labelcommand. Any attempt to patch the affected HPA object (i.e. changingminReplicas) will return the same error.