✨ Add worker version pinning API and validation - #14036
Conversation
Adds an optional `version` field to MachineDeploymentTopology and MachinePoolTopology, guarded by the new ClusterTopologyWorkerVersionPinning feature gate (alpha, default off). When set, the field pins the Kubernetes version of that MachineDeployment/MachinePool so it can be upgraded independently of Cluster.spec.topology.version. This commit covers the API surface and admission validation only; the topology controller does not act on the field yet. Admission validation of a pinned version: - it can only be set if the feature gate is enabled, - it must be a valid semantic version starting with "v", and is defaulted to add the "v" prefix like Cluster.spec.topology.version, - it must be one of ClusterClass.spec.kubernetesVersions when that list is set, - it cannot be combined with the defer-upgrade or hold-upgrade-sequence annotations, which control the cluster-level upgrade sequence a pinned MachineDeployment/MachinePool is excluded from, - it cannot be decreased, cannot be lower than the version the MachineDeployment/MachinePool currently runs, cannot exceed the control plane version, and must conform to the Kubernetes version skew policy, - it can only be unset once it equals Cluster.spec.topology.version. Cluster.spec.topology.version is validated against every pinned version too, so the Cluster cannot be upgraded past what the skew policy allows for a pinned MachineDeployment/MachinePool. This is the only guard for chained upgrades, where the version ceiling is not validated at all. The control plane and the MachineDeployments/MachinePools are only read when a version actually changed, and a read failure produces a warning rather than rejecting unrelated Cluster updates. Also fixes validateTopologyMachineDeploymentVersions and validateTopologyMachinePoolVersions, which classify any MachineDeployment or MachinePool whose version differs from Cluster.spec.topology.version as "still completing a previous upgrade". A pinned MachineDeployment/MachinePool intentionally runs a different version, so without this fix a single pinned MachineDeployment would block every subsequent topology version change. The pin now silences only the version comparison; the real upgrading check still runs. Conversion to v1beta1 drops the field, so it is restored from the conversion-data annotation, matched by topology name rather than index because v1beta1 clients can reorder the list. The Kubernetes version skew rules move to util/version so the webhook and the MachineSet preflight checks share one implementation.
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @AcidLeroy. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Regular contributors should join the org to skip this step. Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions 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-sigs/prow repository. |
What this PR does / why we need it:
First of three PRs implementing worker version pinning (CAEP #13892). Adds an optional
versionfield toMachineDeploymentTopology/MachinePoolTopologybehind the newClusterTopologyWorkerVersionPinningfeature gate (alpha, off by default), plus admission validation.API and validation only — the topology controller does not read the field yet, so this is a no-op at runtime. Controller and e2e follow in PRs 2 and 3.
flowchart LR A["MD/MP<br/>cluster-managed"] -->|"set version<br/>= running version"| B["pinned<br/>no rollout"] B -->|"raise version"| C["pinned<br/>rolls out"] C -->|"unset version"| A V{"validating<br/>webhook"} B -.-> V C -.-> V V -.- R["no decrease, not below running version<br/>≤ control plane version, within skew policy<br/>unset only when = topology.version<br/>member of ClusterClass.kubernetesVersions<br/>not with defer-upgrade / hold-upgrade-sequence"]Cluster.spec.topology.versionis validated against every pinned version too, so the Cluster cannot outrun a pinned MD/MP's skew budget. This is the only such guard for chained upgrades, where the+2minor ceiling is skipped entirely.Also fixes a latent bug:
validateTopologyMachineDeploymentVersions/validateTopologyMachinePoolVersionstreat any MD/MP whose version differs fromtopology.versionas "still completing a previous upgrade". Without this fix one pinned MD would block every future topology version change.Notes for reviewers:
util/version, shared with the MachineSet preflight checks. The shared helper also compares the major version and avoids the unsigned underflow the previous inline check had when the control plane minor is below the tolerated skew.Which issue(s) this PR fixes:
Part of #13967
/area clusterclass
/area api