New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
kubectl apply --server-side --dry-run=server
can duplicate field in an atomic list
#118293
Comments
I tried to add a printf of the json'd merged object right before leaving the ssa code, and the field isn't duplicated. So something else must be trying to merge somehow!? |
I also checked that it's not kubectl doing anything crazy, the response from the server includes the duplicated field. |
Checked both before and after admission, object seems to be properly merged. |
Ah, something not mentioned in the bug, applying without dry-run doesn't trigger the same behavior. |
storage version changed to v2 in 1.27 (#114358) HPA conversion is really weird (taking v2 fields and putting them in annotations in v1, then shipping annotations back into appended items when converting back to v2)... I'd suspect something in the storage → conversion path |
Right, the exact conversions that we do are different in dry-run vs non-dry-run because we have to storage version. I'm still investigating the conversion path to see if anything seems shady and I've made progress on that. |
OK, this is the trace that leads to the internal HorizontalPodAutoscaler object to have the metrics field duplicated is this one:
So definitely in the path to dry-run. The following test reproduces the error, as it fails with two identical metrics. in := &autoscalingv1.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"autoscaling.alpha.kubernetes.io/metrics": "[{\"type\":\"External\",\"external\":{\"metricName\":\"foo\",\"targetAverageValue\":\"10\"}}]",
},
},
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
MinReplicas: utilpointer.Int32Ptr(1),
MaxReplicas: 5,
},
}
out := &autoscaling.HorizontalPodAutoscaler{
Spec: autoscaling.HorizontalPodAutoscalerSpec{
Metrics: []autoscaling.MetricSpec{
{
Type: autoscaling.ExternalMetricSourceType,
External: &autoscaling.ExternalMetricSource{
Target: autoscaling.MetricTarget{
Type: autoscaling.AverageValueMetricType,
AverageValue: resource.NewMilliQuantity(10, resource.DecimalSI),
},
},
},
},
},
}
expectOut := &autoscaling.HorizontalPodAutoscaler{
Spec: autoscaling.HorizontalPodAutoscalerSpec{
MinReplicas: utilpointer.Int32Ptr(1),
MaxReplicas: 5,
Metrics: []autoscaling.MetricSpec{
{
Type: autoscaling.ExternalMetricSourceType,
External: &autoscaling.ExternalMetricSource{
Target: autoscaling.MetricTarget{
Type: autoscaling.AverageValueMetricType,
AverageValue: resource.NewMilliQuantity(10, resource.DecimalSI),
},
},
},
},
},
}
if err := Convert_v1_HorizontalPodAutoscaler_To_autoscaling_HorizontalPodAutoscaler(in, out, nil); err != nil {
t.Errorf("Convert_v1_HorizontalPodAutoscaler_To_autoscaling_HorizontalPodAutoscaler() error = %v", err)
}
assert.Equal(t, expectOut, out) Problem is probably that 1. the "out" object isn't cleared before |
Did anyone find a workaround for this bug? Currently trying to compare equality between two objects after a dry-run to populate default fields. |
Apparently, the bug happens in 1.26.3 but not in 1.27.1 so maybe it's been fixed somewhere.
Here are the steps to reproduce:
Note that the metrics list is atomic, so the list should be entirely replaced every-time, not merged/appended.
https://github.com/kubernetes/kubernetes/blob/v1.27.2/staging/src/k8s.io/api/autoscaling/v2/types.go#L67-L77
/wg api-expression
/triage accepted
/priority important-soon
The text was updated successfully, but these errors were encountered: