What steps did you take and what happened?
- Had a cluster created with CAPI ≤ v1.11
- Management cluster was upgraded to CAPI v1.12.5
- Added logic for inplace update for updating
spec.clusterConfiguration.etcd.local.extraArgs in KCP specs.
- Changed
spec.clusterConfiguration.etcd.local.extraArgs in the KCP spec (e.g. updated quota-backend-bytes from 6000000000 to 8000000000)
- In-place update was triggered for existing CP machines. 1st machine got reprovisioned, and next one into
Updating state.
- The KCP reconcile loop repeatedly failed for 2nd CP with the following error on every reconcile, The machine stays stuck in
Updating phase indefinitely.
inplace_trigger.go:44] "Triggering in-place update for Machine test-2npxs-tjx8v" controller="kubeadmcontrolplane" controllerGroup="controlplane.cluster.x-k8s.io" controllerKind="KubeadmControlPlane" KubeadmControlPlane="test/test-2npxs" reconcileID="e3a4b919-8045-40de-abf7-469eedc12b41" Cluster="test/test" Machine="test/test-2npxs-tjx8v"
E0803 13:08:34.537165 1 controller.go:474] "Reconciler error" err="failed to complete triggering in-place update for Machine test/test-2npxs-tjx8v: failed to apply KubeadmConfig: KubeadmConfig.bootstrap.cluster.x-k8s.io \"test-2npxs-tjx8v\" is invalid: spec.clusterConfiguration.etcd.local.extraArgs: Invalid value: \"array\": extraArgs name must be unique" controller="kubeadmcontrolplane" controllerGroup="controlplane.cluster.x-k8s.io" controllerKind="KubeadmControlPlane" KubeadmControlPlane="test/testl-2npxs" reconcileID="e3a4b919-8045-40de-abf7-469eedc12b41"
During In-Place update, existing spec.clusterConfiguration.etcd.local.extraArgs in old kubeadmconfig is not identified and SSA is trying add a new one with same name.
Checking managedFields on the affected KubeadmConfig shows f:spec is not owned by any field manager after migration:
On the affected KubeadmConfig (old cluster-created before capi1.11, old kubeadmconfig, post-migration):
kubectl get kubeadmconfig <name> -n <namespace> --show-managed-fields -o yaml
- apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations: {}
f:labels:
f:cluster.x-k8s.io/cluster-name: {}
f:cluster.x-k8s.io/control-plane: {}
f:cluster.x-k8s.io/control-plane-name: {}
f:topology.cluster.x-k8s.io/owned: {}
manager: capi-kubeadmcontrolplane-metadata
operation: Apply
# f:spec has NO owner — entire spec is orphaned
On a KubeadmConfig from a newly rolled-out node (same cluster, CAPI v1.12):
managedFields:
- apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
fieldsType: FieldsV1
fieldsV1:
f:spec:
f:clusterConfiguration:
......
f:etcd:
f:local:
f:extraArgs:
k:{"name":"auto-compaction-mode","value":"revision"}:
.: {}
f:name: {}
f:value: {}
k:{"name":"auto-compaction-retention","value":"150000"}:
.: {}
f:name: {}
f:value: {}
k:{"name":"quota-backend-bytes","value":"8000000000"}:
.: {}
f:name: {}
f:value: {}
....................
f:joinConfiguration:
f:controlPlane: {}
f:nodeRegistration:
f:imagePullPolicy: {}
f:kubeletExtraArgs:
k:{"name":"config","value":"/etc/kubernetes/kubelet/config.yaml"}:
.: {}
f:name: {}
f:value: {}
f:name: {}
f:timeouts:
f:controlPlaneComponentHealthCheckSeconds: {}
f:postKubeadmCommands: {}
f:preKubeadmCommands: {}
manager: capi-kubeadmcontrolplane # owns f:spec ✅
operation: Apply
So potentially, capi-kubeadmcontrolplane does not own the old spec and trying to add a new spec.clusterConfiguration.etcd.local.extraArgs?
Steps to reproduce
- Have a cluster created with CAPI ≤ v1.11
- Upgrade management cluster to CAPI v1.12+
- Verify
f:spec is orphaned:
kubectl get kubeadmconfig <name> -n <namespace> --show-managed-fields -o yaml
Confirm no manager owns f:spec
- Add in place update for
etcd.local.extraArgs
- Change
etcd.local.extraArgs (e.g. update quota-backend-bytes) in KCP spec
- Observe
inplace_trigger.go entering a retry loop with extraArgs name must be unique in capi-kubeadm-control-plane-controller-manager logs
What did you expect to happen?
The in-place update should replace the existing quota-backend-bytes value cleanly — the same as it works correctly on clusters created with CAPI ≥ v1.12, and on new nodes created via rolling replace on the same old cluster.
Confirmed that on newly created clusters (CAPI ≥ v1.12 from day one), repeated in-place updates of the same extraArg (e.g. 150000 → 200000 → 210000) work correctly
Cluster API version
CAPI version: v1.12.5
Kubernetes version
No response
Anything else you would like to add?
Potentially, related to this kubeadmcontrolplane_controller.go#L948 ?
initConfiguration is already handled in inplace_trigger.go#L143
Label(s) to be applied
/kind bug
/area provider/control-plane-kubeadm
What steps did you take and what happened?
spec.clusterConfiguration.etcd.local.extraArgsin KCP specs.spec.clusterConfiguration.etcd.local.extraArgsin the KCP spec (e.g. updatedquota-backend-bytesfrom6000000000to8000000000)Updatingstate.Updatingphase indefinitely.During In-Place update, existing
spec.clusterConfiguration.etcd.local.extraArgsin old kubeadmconfig is not identified and SSA is trying add a new one with same name.Checking
managedFieldson the affected KubeadmConfig showsf:specis not owned by any field manager after migration:On the affected KubeadmConfig (old cluster-created before capi1.11, old kubeadmconfig, post-migration):
On a KubeadmConfig from a newly rolled-out node (same cluster, CAPI v1.12):
So potentially,
capi-kubeadmcontrolplanedoes not own the oldspecand trying to add a newspec.clusterConfiguration.etcd.local.extraArgs?Steps to reproduce
f:specis orphaned:f:specetcd.local.extraArgsetcd.local.extraArgs(e.g. updatequota-backend-bytes) in KCP specinplace_trigger.goentering a retry loop withextraArgs name must be uniqueincapi-kubeadm-control-plane-controller-managerlogsWhat did you expect to happen?
The in-place update should replace the existing
quota-backend-bytesvalue cleanly — the same as it works correctly on clusters created with CAPI ≥ v1.12, and on new nodes created via rolling replace on the same old cluster.Confirmed that on newly created clusters (CAPI ≥ v1.12 from day one), repeated in-place updates of the same extraArg (e.g.
150000 → 200000 → 210000) work correctlyCluster API version
CAPI version: v1.12.5
Kubernetes version
No response
Anything else you would like to add?
Potentially, related to this kubeadmcontrolplane_controller.go#L948 ?
initConfiguration is already handled in inplace_trigger.go#L143
Label(s) to be applied
/kind bug
/area provider/control-plane-kubeadm