Skip to content

✨ Add worker version pinning API and validation - #14036

Draft
AcidLeroy wants to merge 1 commit into
kubernetes-sigs:mainfrom
AcidLeroy:worker-version-pinning-api
Draft

✨ Add worker version pinning API and validation#14036
AcidLeroy wants to merge 1 commit into
kubernetes-sigs:mainfrom
AcidLeroy:worker-version-pinning-api

Conversation

@AcidLeroy

@AcidLeroy AcidLeroy commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

First of three PRs implementing worker version pinning (CAEP #13892). Adds an optional version field to MachineDeploymentTopology/MachinePoolTopology behind the new ClusterTopologyWorkerVersionPinning feature 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/>&le; 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"]
Loading

Cluster.spec.topology.version is 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 +2 minor ceiling is skipped entirely.

Also fixes a latent bug: validateTopologyMachineDeploymentVersions/validateTopologyMachinePoolVersions treat any MD/MP whose version differs from topology.version as "still completing a previous upgrade". Without this fix one pinned MD would block every future topology version change.

Notes for reviewers:

  • v1beta1 conversion drops the field, so it is restored from the conversion-data annotation matched by topology name, not index — v1beta1 clients can reorder the list.
  • Skew rules moved to 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

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.
@kubernetes-prow kubernetes-prow Bot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. area/clusterclass Issues or PRs related to clusterclass area/api Issues or PRs related to the APIs cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Aug 6, 2026
@kubernetes-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign chrischdi for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubernetes-prow kubernetes-prow Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Aug 6, 2026
@kubernetes-prow

Copy link
Copy Markdown
Contributor

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 /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

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-sigs/prow repository.

@kubernetes-prow kubernetes-prow Bot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Aug 6, 2026
@kubernetes-prow
kubernetes-prow Bot requested review from chrischdi and sivchari August 6, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api Issues or PRs related to the APIs area/clusterclass Issues or PRs related to clusterclass cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant