Cluster API v1.10 compared to v1.11
This document provides an overview over relevant changes between Cluster API v1.10 and v1.11 for all Cluster API users. The document has the following sections:
- A detailed list about API changes and contract changes
- Recommendations for different kind of CAPI users:
Any feedback or contributions to improve following documentation is welcome!
We also recommend to (re)read the Improving status in CAPI resources proposal because most of the changes described below are a consequence of the work for implementing this proposal.
- Cluster API v1.10 compared to v1.11
Go version
- The minimal Go version required to build Cluster API is v1.24.x
- The Go version used by Cluster API is v1.24.x
Dependencies
- The Controller Runtime version used by Cluster API is v0.21.x
- The version of the Kubernetes libraries used by Cluster API is v1.33.x
API Changes
- APIs have been moved to the top-level
apifolder (https://github.com/kubernetes-sigs/cluster-api/pull/12262). If you keep usingv1alpha/v1beta1APIs, imports have to be adjusted accordingly:sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1=>sigs.k8s.io/cluster-api/api/bootstrap/kubeadm/v1beta1(apiGroup:bootstrap.cluster.x-k8s.io)sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1=>sigs.k8s.io/cluster-api/api/controlplane/kubeadm/v1beta1(apiGroup:controlplane.cluster.x-k8s.io)sigs.k8s.io/cluster-api/api/v1beta1=>sigs.k8s.io/cluster-api/api/core/v1beta1(apiGroup:cluster.x-k8s.io)sigs.k8s.io/cluster-api/exp/api/v1beta1=>sigs.k8s.io/cluster-api/api/core/v1beta1(apiGroup:cluster.x-k8s.io)sigs.k8s.io/cluster-api/exp/ipam/api/v1alpha1=>sigs.k8s.io/cluster-api/api/ipam/v1alpha1(apiGroup:ipam.cluster.x-k8s.io)sigs.k8s.io/cluster-api/exp/ipam/api/v1beta1=>sigs.k8s.io/cluster-api/api/ipam/v1beta1(apiGroup:ipam.cluster.x-k8s.io)sigs.k8s.io/cluster-api/exp/runtime/api/v1alpha1=>sigs.k8s.io/cluster-api/api/runtime/v1alpha1(apiGroup:runtime.cluster.x-k8s.io)sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1=>sigs.k8s.io/cluster-api/api/runtime/hooks/v1alpha1(apiGroup:hooks.runtime.cluster.x-k8s.io)
- v1beta2 API version has been introduced and considering the awesome amount of improvements it marks an important
step in the journey towards graduating our API to v1; see following paragraphs for more details.
The new API version have been added in the following packages:
sigs.k8s.io/cluster-api/api/bootstrap/kubeadm/v1beta2(apiGroup:bootstrap.cluster.x-k8s.io)sigs.k8s.io/cluster-api/api/controlplane/kubeadm/v1beta2(apiGroup:controlplane.cluster.x-k8s.io)sigs.k8s.io/cluster-api/api/addons/v1beta2(apiGroup:addons.cluster.x-k8s.io)sigs.k8s.io/cluster-api/api/core/v1beta2(apiGroup:cluster.x-k8s.io)sigs.k8s.io/cluster-api/api/ipam/v1beta2(apiGroup:ipam.cluster.x-k8s.io)sigs.k8s.io/cluster-api/api/runtime/v1beta2(apiGroup:runtime.cluster.x-k8s.io)
- v1beta1 API version is now deprecated and it will be removed tentatively in August 2026
- If you are using the
runtime.cluster.x-k8s.ioAPI group, please be aware thatExtensionConfigv1beta2 has been created (thus aligning with other Cluster API resources)ExtensionConfigv1alpha1 has been deprecated, and it will be removed in a following release.
controllers/remote.ClusterCacheTrackerand corresponding types have been removed- The unused
ClusterStatusstruct in the kubeadm bootstrap apiGroup has been removed
All CRDs
When looking at API changes introduced in the v1beta2 API version for each CRD it could help to keep in mind a few high level themes:
- Improve status:
- The transition to the new K8s aligned conditions using
metav1.Conditionstypes and the new condition semantic has been completed. - Replica counters are now consistent with new conditions and across all resources; new replica counters have been added at cluster level.
- Semantic of contract fields in status have been improved and are now consistent across all resources.
- The confusing
FailureReasonandFailureMessagefields have been dropped.
- The transition to the new K8s aligned conditions using
- Support CC across namespaces:
- API changes planned for this feature have been implemented.
- Improve object references:
- Unnecessary fields have been dropped from object reference.
- Object references are now GitOps friendly (API version is not overwritten anymore by controllers).
- KubeadmConfig and KubeadmControlPlane APIs have been aligned with kubeadm v1beta4 API.
- Additionally, fields inferred from top level objects have been removed, thus getting rid of a common source of confusion/issues.
- Compliance with K8s API guidelines:
- Thanks to the adoption of the KAL linter compliance with K8s API guidelines has been greatly improved.
- All
metav1.Durationfields (e.g.nodeDeletionTimeout) are now represented as*int32fields with units being part of the field name (e.g.nodeDeletionTimeoutSeconds).- A side effect of this is that if durations were specified on a sub-second granularity conversion will truncate to seconds.
E.g. this means if you apply a v1beta1 object with
nodeDeletionTimeout: 1s5msonly1swill be stored and returned on reads.
- A side effect of this is that if durations were specified on a sub-second granularity conversion will truncate to seconds.
E.g. this means if you apply a v1beta1 object with
- All
boolfields have been changed to*boolto preserve user intent. - Extensive work has been done to ensure
requiredandoptionalis explicitly set in the API, and that both serialization and validation works accordingly:- Stop rendering empty structs (review of all occurrences of
omitemptyand introduction ofomitzero) - Do not allow
""when it is not semantically different from value not set (either you have to provide a non-empty string value or not set the field at all). - Do not allow
0when it is not semantically different from value not set (either you have to provide a non-0 int value or not set the field at all). - Do not allow
{}when it is not semantically different from value not set (either you have to set at least one property in the object or not set the field at all). - Do not allow
[]when it is not semantically different from value not set (either you have to set at least one item in the list or not set the field at all). - Ensure validation for all enum types.
- Stop rendering empty structs (review of all occurrences of
- Missing list markers have been added for SSA.
- Note: For sake of simplicity, changes about
omitempty,requiredandoptionalmarkers or other related validation markers have not been documented in the following paragraphs. Please look at the CRD definitions if you are interested in these changes.
- Drop unnecessary pointers:
- After fixing
requiredandoptionalaccording to K8s API guidelines, extensive work has been done to drop unnecessary pointers thus improving the usability of the API’s Go structs.
- After fixing
- Avoid embedding structs:
- Coupling between API types has been reduced by reducing the usage of embedded structs.
- Improve consistency:
- Extensive work has been done to improve consistency across all resources:
- Fields for Machine deletion are under a new
deletionstruct in all resources. - Settings about
rollouthave been logically grouped in all resources. - Settings about health checks and
remediationhave been logically grouped in all resources. - Etc..
- Fields for Machine deletion are under a new
- Extensive work has been done to improve consistency across all resources:
- Missing validations have been added where required.
- Tech debt has been reduced by dropping deprecated fields.
- Important! Please pay attention to field removals, e.g. if you are using GitOps tools, either migrate to v1beta2 or make sure
to stop setting the removed fields. The removed fields won’t be preserved even if setting them via v1beta1
(as they don’t exist in v1beta2).
- For example, we removed the
clusterNamefield fromKubeadmControlPlane.spec.kubeadmConfigSpec.clusterConfiguration
- For example, we removed the
- Important! Please pay attention to field removals, e.g. if you are using GitOps tools, either migrate to v1beta2 or make sure
to stop setting the removed fields. The removed fields won’t be preserved even if setting them via v1beta1
(as they don’t exist in v1beta2).
Cluster
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
- Pointers have been removed from various struct fields. See #12545 for details (drop unnecessary pointers)
- The type of the
spec.pausedfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The
spec.controlPlaneRefandspec.infrastructureReffields are now usingContractVersionedObjectReferencetype instead ofcorev1.ObjectReference(improve object references)- The following fields have been removed:
namespace,uid,resourceVersion,fieldPath apiVersionhas been replaced withapiGroup. As before, the version will be read from the corresponding CRD
- The following fields have been removed:
- The
spec.controlPlaneEndpoint.hostfield does not accept “” anymore as a value (missing validation) - The
spec.controlPlaneEndpoint.portfield does not accept 0 anymore as a value (missing validation) - The type of the
spec.clusterNetwork.apiServerPortfield has been changed from*int32toint32(drop unnecessary pointers)- This field does not accept 0 anymore as a value (missing validation)
- The type of the
spec.clusterNetwork.servicesandspec.clusterNetwork.podsfields has been changed from*NetworkRangestoNetworkRanges(drop unnecessary pointers) - The
spec.topology.classfield has been renamed tospec.topology.classRef.name(support CC across namespaces) - The
spec.topology.classNamespacefield has been renamed tospec.topology.classRef.namespace(support CC across namespaces) - The
spec.topology.rolloutAfterfield has been removed because the corresponding functionality was never implemented (tech debt) - The
definitionFromfield (deprecated since CAPI v1.8) has been removed fromspec.topology.variablesspec.topology.controlPlane.variables.overrides[]spec.topology.workers.machineDeployments[].variables.overrides[]spec.topology.workers.machinePools[].variables.overrides[]
- The type of the
spec.workersfield has been changed from*WorkersTopologytoWorkersTopology(drop unnecessary pointers) - The type of the
spec.topology.controlPlane.variablesfield has been changed from*ControlPlaneVariablestoControlPlaneVariables(drop unnecessary pointers) - The type of the
spec.topology.workers.machineDeployments[].failureDomainfield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.topology.workers.machineDeployments[].deletion.orderfield, previouslyspec.topology.workers.machineDeployments[].strategy.rollingUpdate.deletePolicy, has been changed from*stringtoMachineSetDeletionOrder(improve consistency) - A new
spec.topology.workers.machineDeployments[].rolloutfield has been introduced, it contains the previousspec.topology.workers.machineDeployments[].strategyfield. The Go structs have been modified accordingly. For more details see YAML above (improve consistency) - The type of the
spec.topology.workers.machineDeployments[].variablesfield has been changed from*MachineDeploymentVariablestoMachineDeploymentVariables(drop unnecessary pointers) - The type of the
spec.topology.workers.machinePools[].variablesfield has been changed from*MachinePoolVariablestoMachinePoolVariables(drop unnecessary pointers) - All fields of type Duration in
spec.topology.{controlPlane,workers.machineDeployments[],workers.machinePools[]}have been renamed by adding theSecondssuffix, moved into thedeletionsection and their type was changed to int32 (compliance with K8s API guidelines)nodeDrainTimeout=>deletion.nodeDrainTimeoutSecondsnodeVolumeDetachTimeout=>deletion.nodeVolumeDetachTimeoutSecondsnodeDeletionTimeout=>deletion.nodeDeletionTimeoutSeconds
- The
spec.topology.controlPlane.healthCheckfield, previouslyspec.topology.controlPlane.machineHealthCheck, has been restructured and made consistent across all resources. Notably fields for checks and remediation are now well identified under corresponding fields. The Go structs have been modified accordingly. For more details see YAML above (improve consistency).- The same change has been applied to
spec.topology.workers.machineDeployments[].healthCheck, previouslyspec.topology.workers.machineDeployments[].machineHealthCheck - Also the
spec.topology.workers.machineDeployments[].healthCheck.remediation.maxInFlightfield has been moved fromspec.topology.workers.machineDeployments[].strategy.remediation.maxInFlight
- The same change has been applied to
- All fields of type Duration in
spec.topology.{controlPlane.healthCheck.checks,workers.machineDeployments[].healthCheck.checks}, previouslyspec.topology.{controlPlane.healthCheck,workers.machineDeployments[].machineHealthCheck}have been renamed by adding theSecondssuffix and their type was changed to*int32(compliance with K8s API guidelines)nodeStartupTimeout=>nodeStartupTimeoutSecondsunhealthyNodeConditions[].timeout=>unhealthyNodeConditions[].timeoutSeconds
- All the
remediation.templateReffields have been migrated from typecorev1.ObjectReferencetoMachineHealthCheckRemediationTemplateReference:spec.topology.controlPlane.healthCheck.remediation.templateRef, previouslyspec.topology.controlPlane.machineHealthCheck.remediationTemplatespec.topology.workers.machineDeployments[].healthCheck.remediation.templateRef, previouslyspec.topology.workers.machineDeployments[].machineHealthCheck.remediationTemplate- For all the above, the following fields have been removed from
remediation.templateRef:namespace,uid,resourceVersion,fieldPath
- The type of the
spec.topology.controlPlane.healthCheck.remediation.triggerIf.unhealthyInRange,spec.topology.workers.machineDeployments[].healthCheck.remediation.triggerIf.unhealthyInRangefields, previouslyspec.topology.controlPlane.machineHealthCheck.unhealthyRange,spec.topology.workers.machineDeployments[].machineHealthCheck.unhealthyRange, have been changed from*stringtostring(drop unnecessary pointers) status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
- Information about the initial provisioning process are now surfacing under the new
status.initializationfield (improve status)status.infrastructureReadyhas been replaced bystatus.initialization.infrastructureProvisionedstatus.controlPlaneReadyhas been replaced bystatus.initialization.controlPlaneInitialized
- The
.status.failureDomainsfield has been changed from a map to an array - New fields for replica counters have been added to the cluster object (improve status):
status.controlPlanenow reports replica counters surfaced from the control plane objectstatus.workersnow reports replica counters fromMachineDeploymentsand standaloneMachineSetandMachines
- Support for terminal errors has been dropped (improve status)
status.failureReasonandstatus.failureMessagewill continue to exist temporarily understatus.deprecated.v1beta1- The const values for
Failedphase has been deprecated in the enum type forstatus.phase(controllers are not setting this value anymore)
- The
GetIPFamilymethod (deprecated since CAPI v1.8) has been removed from the Cluster struct. - The
index.ByClusterClassName,index.ClusterByClusterClassClassNameandindex.ClusterClassNameFieldtypes have been removed in favor ofindex.ByClusterClassRef,index.ClusterByClusterClassRefandindex.ClusterClassRefPath
MachineDeployment
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
- Pointers have been removed from various struct fields. See #12545 for details (drop unnecessary pointers)
- The
spec.machineNamingStrategyfield was renamed tospec.machineNamingand is now usingMachineNamingSpectype instead of*MachineNamingStrategy(improve consistency, drop unnecessary pointers) - The
spec.template.spec.bootstrap.configRefandspec.template.spec.infrastructureReffields are now usingContractVersionedObjectReferencetype instead ofcorev1.ObjectReference(improve object references)- The following fields have been removed:
namespace,uid,resourceVersion,fieldPath apiVersionhas been replaced withapiGroup. As before, the version will be read from the corresponding CRD
- The following fields have been removed:
- The
spec.progressDeadlineSecondsfield (deprecated since CAPI v1.9) has been removed - All fields of type Duration in
spec.template.spechave been renamed by adding theSecondssuffix, moved into thedeletionsection and their type was changed to int32 (compliance with K8s API guidelines)nodeDrainTimeout=>deletion.nodeDrainTimeoutSecondsnodeVolumeDetachTimeout=>deletion.nodeVolumeDetachTimeoutSecondsnodeDeletionTimeout=>deletion.nodeDeletionTimeoutSeconds
- The type of the
spec.pausedfield has been changed fromboolto*bool(compliance with K8s API guidelines) - A new
spec.rolloutfield has been introduced, it combines previousspec.rolloutAfterandspec.strategyfields. The Go structs have been modified accordingly. For more details see YAML above (improve consistency)- The type of the
spec.rollout.after, previouslyspec.rolloutAfter, field has been changed from*metav1.Timetometav1.Time(drop unnecessary pointers)
- The type of the
- The type of the
spec.remediationfield, previouslyspec.strategy.remediation, has been changed from*RemediationStrategytoMachineDeploymentRemediationSpec(improve consistency, drop unnecessary pointers) - The type of the
spec.deletion.orderfield, previouslyspec.strategy.rollingUpdate.deletePolicy, has been changed from*stringtoMachineSetDeletionOrder(improve consistency) - The
spec.revisionHistoryLimitfield has been removed. The MachineDeployment controller will now clean up all MachineSets without replicas (tech debt)- The corresponding
machinedeployment.clusters.x-k8s.io/revision-historyannotation has also been removed
- The corresponding
status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
- Replica counters are now consistent with replica counters from other resources (improve status):
status.replicaswas made a pointer and omitempty was addedstatus.readyReplicashas now a new semantic based on machine’sReadyconditionstatus.availableReplicashas now a new semantic based on machine’sAvailableconditionstatus.upToDateReplicashas now a new semantic (and name) based on machine’sUpToDatecondition- Temporarily, old replica counters will still be available under the
status.deprecated.v1beta1struct
- Support for terminal errors has been dropped (improve status)
status.failureReasonandstatus.failureMessagewill continue to exist temporarily understatus.deprecated.v1beta1- The const values for
Failedphase has been deprecated in the enum type forstatus.phase(controllers are not setting this value anymore)
- The
status.phasesfield is now computed using the same logic used forScalingUpandScalingDownconditions (improve status)
MachineSet
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
- Pointers have been removed from various struct fields. See #12545 for details (drop unnecessary pointers)
- The
spec.machineNamingStrategyfield was renamed tospec.machineNamingand is now usingMachineNamingSpectype instead of*MachineNamingStrategy(improve consistency, drop unnecessary pointers) - The
spec.template.spec.bootstrap.configRefandspec.template.spec.infrastructureReffields are now usingContractVersionedObjectReferencetype instead ofcorev1.ObjectReference(improve object references)- The following fields have been removed:
namespace,uid,resourceVersion,fieldPath apiVersionhas been replaced withapiGroup. As before, the version will be read from the corresponding CRD
- The following fields have been removed:
- The type of the
spec.deletion.orderfield, previouslyspec.deletePolicy, field has been changed fromstringtoMachineSetDeletionOrder(improve consistency) - All fields of type Duration in
spec.template.spechave been renamed by adding theSecondssuffix, moved into thedeletionsection and their type was changed to int32 (compliance with K8s API guidelines)nodeDrainTimeout=>deletion.nodeDrainTimeoutSecondsnodeVolumeDetachTimeout=>deletion.nodeVolumeDetachTimeoutSecondsnodeDeletionTimeout=>deletion.nodeDeletionTimeoutSeconds
status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
- Replica counters fields are now consistent with replica counters from other resources (improve status):
status.replicaswas made a pointer and omitempty was addedstatus.readyReplicashas now a new semantic based on machine’sReadyconditionstatus.availableReplicashas now a new semantic based on machine’sAvailableconditionstatus.upToDateReplicashas now a new semantic (and name) based on machine’sUpToDatecondition- Temporarily, old replica counters will still be available under the
status.deprecated.v1beta1struct
- Support for terminal errors has been dropped (improve status).
status.failureReasonandstatus.failureMessagewill continue to exist temporarily understatus.deprecated.v1beta1
MachinePool
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
- Pointers have been removed from various struct fields. See #12545 for details (drop unnecessary pointers)
- The
spec.template.spec.bootstrap.configRefandspec.template.spec.infrastructureReffields are now usingContractVersionedObjectReferencetype instead ofcorev1.ObjectReference(improve object references)- The following fields have been removed:
namespace,uid,resourceVersion,fieldPath apiVersionhas been replaced withapiGroup. As before, the version will be read from the corresponding CRD
- The following fields have been removed:
- All fields of type Duration in
spec.template.spechave been renamed by adding theSecondssuffix, moved into thedeletionsection and their type was changed to int32 (compliance with K8s API guidelines)nodeDrainTimeout=>deletion.nodeDrainTimeoutSecondsnodeVolumeDetachTimeout=>deletion.nodeVolumeDetachTimeoutSecondsnodeDeletionTimeout=>deletion.nodeDeletionTimeoutSeconds
status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
status.replicaswas made a pointer and omitempty was added (improve status)- Support for terminal errors has been dropped (improve status)
status.failureReasonandstatus.failureMessagewill continue to exist temporarily understatus.deprecated.v1beta1- The const values for
Failedphase has been deprecated in the enum type forstatus.phasebecause controllers are not setting this value anymore
Machine
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
- Pointers have been removed from various struct fields. See #12545 for details (drop unnecessary pointers)
- The
spec.bootstrap.configRefandspec.infrastructureReffields are now usingContractVersionedObjectReferencetype instead ofcorev1.ObjectReference(improve object references)- The following fields have been removed:
namespace,uid,resourceVersion,fieldPath apiVersionhas been replaced withapiGroup. As before, the version will be read from the corresponding CRD
- The following fields have been removed:
- All fields of type Duration in
spechave been renamed by adding theSecondssuffix, moved into thedeletionsection and their type was changed to int32 (compliance with K8s API guidelines)nodeDrainTimeout=>deletion.nodeDrainTimeoutSecondsnodeVolumeDetachTimeout=>deletion.nodeVolumeDetachTimeoutSecondsnodeDeletionTimeout=>deletion.nodeDeletionTimeoutSeconds
- The type of the
spec.versionfield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.providerIDfield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.failureDomainfield has been changed from*stringtostring(drop unnecessary pointers) status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
- Information about the initial provisioning process is now surfacing under the new
status.initializationfield (improve status)status.infrastructureReadyhas been replaced bystatus.initialization.infrastructureProvisionedstatus.bootstrapReadyhas been replaced bystatus.initialization.bootstrapDataSecretCreated
- Support for terminal errors has been dropped (improve status)
status.failureReasonandstatus.failureMessagewill continue to exist temporarily understatus.deprecated.v1beta1- The const values for
Failedphase has been deprecated in the enum type forstatus.phase(controllers are not setting this value anymore)
- The type of the
status.nodeReffield has been changed fromcorev1.ObjectReferencetoMachineNodeReference(improve object references)- The following fields have been removed from
status.nodeRef:kind,namespace,uid,apiVersion,resourceVersion,fieldPath
- The following fields have been removed from
- The type of the following fields has been changed from
*metav1.Timetometav1.Time(drop unnecessary pointers)status.lastUpdatedstatus.certificatesExpiryDatestatus.deletion.nodeDrainStartTimestatus.deletion.waitForNodeVolumeDetachStartTime
MachineHealthCheck
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
- Pointers have been removed from various struct fields. See #12545 for details (drop unnecessary pointers)
- The
spechas been restructured and made consistent across all resources. Notably fields for checks and remediation are now well identified under corresponding fields. The Go structs have been modified accordingly. For more details see YAML above (improve consistency). - The type of the
spec.checks.nodeStartupTimeoutSecondsfield, previouslyspec.nodeStartupTimeout, was changed to int32 (compliance with K8s API guidelines) - The
spec.unhealthyConditionsfield has been renamed tospec.checks.unhealthyNodeConditions(improve consistency) - The type of the
spec.checks.unhealthyNodeConditions[].timeoutSecondsfield, previouslyspec.unhealthyConditions[].timeout, was changed to*int32(compliance with K8s API guidelines) - The type of the
spec.remediation.templateReffield, previouslyspec.remediationTemplate, was changed fromcorev1.ObjectReferencetoMachineHealthCheckRemediationTemplateReference(improve object references):- The following fields have been removed from
templateRef:namespace,uid,resourceVersion,fieldPath
- The following fields have been removed from
- The type of the
spec.remediation.triggerIf.unhealthyInRangefield, previouslyspec.unhealthyRange, was changed from*stringtostring(drop unnecessary pointers) - The
spec.maxUnhealthyfield has been renamed tospec.remediation.triggerIf.unhealthyLessThanOrEqualTo(improve consistency) status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
- The type of the
status.expectedMachinesfield has been changed from*int32toint32(drop unnecessary pointers) - The type of the
status.currentHealthyfield has been changed from*int32toint32(drop unnecessary pointers) - The type of the
status.remediationsAllowedfield has been changed from*int32toint32(drop unnecessary pointers)
ClusterClass
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
- Pointers have been removed from various struct fields. See #12545 for details (drop unnecessary pointers)
- All fields of type Duration in
spec.{controlPlane,workers.machineDeployments[],workers.machinePools[]}have been renamed by adding theSecondssuffix, moved into thedeletionsection and their type was changed to int32 (compliance with K8s API guidelines)nodeDrainTimeout=>deletion.nodeDrainTimeoutSecondsnodeVolumeDetachTimeout=>deletion.nodeVolumeDetachTimeoutSecondsnodeDeletionTimeout=>deletion.nodeDeletionTimeoutSeconds
- All fields of type Duration in
spec.controlPlane.healthCheckandspec.workers.machineDeployments[].healthCheck, previouslyspec.controlPlane.machineHealthCheckandspec.workers.machineDeployments[].machineHealthCheck, have been renamed by adding theSecondssuffix and their type was changed to*int32(compliance with K8s API guidelines)nodeStartupTimeout=>nodeStartupTimeoutSecondsunhealthyNodeConditions[].timeout=>unhealthyNodeConditions[].timeoutSeconds
- All fields implementing or embedding a reference to a template are now using the
ClusterClassTemplateReferencetype instead ofcorev1.ObjectReference; additionally field have been renamed and unnecessary nested structs dropped (improve object references):spec.infrastructure.templateRef, previouslyspec.infrastructure.refspec.controlPlane.templateRef, previouslyspec.controlPlane.refspec.controlPlane.machineInfrastructure.templateRef, previouslyspec.controlPlane.machineInfrastructure.refspec.workers.machineDeployments[].bootstrap.templateRef, previouslyspec.workers.machineDeployments[].template.bootstrap.refspec.workers.machineDeployments[].infrastructure.templateRef, previouslyspec.workers.machineDeployments[].template.infrastructure.refspec.workers.machinePool[].bootstrap.templateRef, previouslyspec.workers.machinePool[].template.bootstrap.refspec.workers.machinePool[].infrastructure.templateRef, previouslyspec.workers.machinePool[].template.infrastructure.ref- For all the above, the following fields have been removed from
*.ref:namespace,uid,resourceVersion,fieldPath
- The
spec.controlPlane.healthCheckfield, previouslyspec.controlPlane.machineHealthCheck, has been restructured and made consistent across all resources. Notably fields for checks and remediation are now well identified under corresponding fields. The Go structs have been modified accordingly. For more details see YAML above (improve consistency).- The same change has been applied to
spec.workers.machineDeployments[].healthCheck, previouslyspec.workers.machineDeployments[].machineHealthCheck - Also the
spec.workers.machineDeployments[].healthCheck.remediation.maxInFlightfield has been moved fromspec.workers.machineDeployments[].strategy.remediation.maxInFlight
- The same change has been applied to
- All fields of type Duration in
spec.{controlPlane.healthCheck.checks,workers.machineDeployments[].healthCheck.checks}, previouslyspec.{controlPlane.healthCheck,workers.machineDeployments[].machineHealthCheck}have been renamed by adding theSecondssuffix and their type was changed to*int32(compliance with K8s API guidelines)nodeStartupTimeout=>nodeStartupTimeoutSecondsunhealthyNodeConditions[].timeout=>unhealthyNodeConditions[].timeoutSeconds
- All the
remediation.templateReffields have been migrated from typecorev1.ObjectReferencetoMachineHealthCheckRemediationTemplateReference:spec.controlPlane.healthCheck.remediation.templateRef, previouslyspec.controlPlane.machineHealthCheck.remediationTemplatespec.workers.machineDeployments[].healthCheck.remediation.templateRef, previouslyspec.workers.machineDeployments[].machineHealthCheck.remediationTemplate- For all the above, the following fields have been removed from
remediation.templateRef:namespace,uid,resourceVersion,fieldPath
- The type of the
spec.controlPlane.healthCheck.remediation.triggerIf.unhealthyInRange,spec.workers.machineDeployments[].healthCheck.remediation.triggerIf.unhealthyInRangefields, previouslyspec.controlPlane.machineHealthCheck.unhealthyRange,spec.workers.machineDeployments[].machineHealthCheck.unhealthyRange, has been changed from*stringtostring(drop unnecessary pointers) - The
spec.workers.machineDeployments[].template.metadatafield has been moved tospec.workers.machineDeployments[].metadata(drop unnecessary nested struct) - The
spec.workers.machinePools[].template.metadatafield has been moved tospec.workers.machinePools[].metadata(drop unnecessary nested struct) - The
spec.infrastructureNamingStrategyfield was renamed tospec.infrastructure.namingand is now usingInfrastructureClassNamingSpectype (improve consistency, drop unnecessary pointers)- The type of the
spec.infrastructure.naming.templatefield has been changed from*stringtostring(drop unnecessary pointers)
- The type of the
- The
spec.controlPlane.namingStrategy.templatefield was renamed tospec.controlPlane.namingand is now usingControlPlaneClassNamingSpectype (improve consistency, drop unnecessary pointers)- The type of the
spec.controlPlane.naming.templatefield has been changed from*stringtostring(drop unnecessary pointers)
- The type of the
- The type of the
spec.workers.machineDeployments[].failureDomainfield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.workers.machineDeployments[].deletion.orderfield, previouslyspec.workers.machineDeployments[].strategy.rollingUpdate.deletePolicy, has been changed from*stringtoMachineSetDeletionOrder(improve consistency) - A new
spec.workers.machineDeployments[].rolloutfield has been introduced, it contains the previousspec.workers.machineDeployments[].strategyfield. The Go structs have been modified accordingly. For more details see YAML above (improve consistency) - The
spec.workers.machineDeployments[].namingStrategyfield was renamed tospec.workers.machineDeployments[].namingand is now usingMachineDeploymentClassNamingSpectype (improve consistency, drop unnecessary pointers)- The type of the
spec.workers.machineDeployments[].naming.templatefield has been changed from*stringtostring(drop unnecessary pointers)
- The type of the
- The
spec.workers.machinePools[].namingStrategyfield was renamed tospec.workers.machinePools[].namingand is now usingMachinePoolClassNamingSpectype (improve consistency, drop unnecessary pointers)- The type of the
spec.workers.machinePools[].naming.templatefield has been changed from*stringtostring(drop unnecessary pointers)
- The type of the
- The type of the
spec.patches[].enabledIffield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.patches[].definitions[].selector.matchResources.controlPlane,spec.patches[].definitions[].selector.matchResources.infrastructureClusterfields has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.patches[].definitions[].jsonPatches[].valueFrom.template,spec.patches[].definitions[].jsonPatches[].valueFrom.variablefields has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.patches[].external.generatePatchesExtension(previouslygenerateExtension),spec.patches[].external.validateTopologyExtension(previouslyvalidateExtension),spec.patches[].external.discoverVariablesExtensionfields has been changed from*stringtostring(drop unnecessary pointers) - The deprecated
spec.variables[].metadataand.status.variables[].definitions[].metadatafields have been renamed tospec.variables[].deprecatedV1Beta1Metadataand.status.variables[].definitions[].deprecatedV1Beta1Metadata- These fields are deprecated and will be removed when support for v1beta1 will be dropped
- Please use
XMetadatainJSONSchemaPropsinstead
- The type of the
spec.variables[].required,spec.variables[].schema.openAPIV3Schema.uniqueItems,spec.variables[].schema.openAPIV3Schema.exclusiveMaximum,spec.variables[].schema.openAPIV3Schema.exclusiveMinimum,spec.variables[].schema.openAPIV3Schema.x-kubernetes-preserve-unknown-fields,spec.variables[].schema.openAPIV3Schema.x-kubernetes-int-or-string,.status.variables[].definitions[].requiredfields has been changed fromboolto*bool(compliance with K8s API guidelines)- Same applies to the corresponding fields under:
spec.variables.schema.openAPIV3Schema.properties[]spec.variables.schema.openAPIV3Schema.additionalPropertiesspec.variables.schema.openAPIV3Schema.allOf[]spec.variables.schema.openAPIV3Schema.oneOf[]spec.variables.schema.openAPIV3Schema.anyOf[]spec.variables.schema.openAPIV3Schema.not- and all the corresponding fields under
status.variables[]
- Same applies to the corresponding fields under:
status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
- The type of the field
status.patches[].definitionsConflicthas been changed fromboolto*bool(compliance with K8s API guidelines) - The
builtin.cluster.classRef.Nameandbuiltin.cluster.classRef.Namespacevariables have been added (support CC across namespaces)- The
builtin.cluster.classandbuiltin.cluster.classNamespaceare deprecated and will be removed with the next apiVersion.
- The
- The deprecated
builtin.cluster.network.ipFamilyvariable has been removed and it cannot be used anymore in patches
KubeadmConfig
| v1beta1 | v1beta2 |
|
|
- KubeadmConfig (and the entire CABPK provider) now implements the v1beta2 Cluster API contract
- See changes that apply to all CRDs
- Pointers have been removed from various struct fields. See #12545 and #12560 for details (drop unnecessary pointers)
extraArgfield types have been changed frommap[string]stingto[]Arg, thus aligning with kubeadm v1beta4 API; however, using multiple args with the same name will be enabled only when v1beta1 is removed, tentatively in August 2026spec.clusterConfiguration.apiServer.extraArgstype has been changed to[]Argspec.clusterConfiguration.controllerManager.extraArgstype has been changed to[]Argspec.clusterConfiguration.scheduler.extraArgstype has been changed to[]Argspec.clusterConfiguration.etcd.local.extraArgstype has been changed to[]Argspec.initConfiguration.nodeRegistration.kubeletExtraArgstype has been changed to[]Argspec.joinConfiguration.nodeRegistration.kubeletExtraArgstype has been changed to[]Arg
imagePullPolicyfield types have been changed fromstringtocorev1.PullPolicy, thus aligning with kubeadm v1beta4 APIspec.initConfiguration.nodeRegistration.imagePullPolicytype has been changed tocorev1.PullPolicyspec.joinConfiguration.nodeRegistration.imagePullPolicytype has been changed tocorev1.PullPolicy
timeoutfields have been aligned with kubeadm v1beta4 API, but field names and types have been adapted according to K8s API guidelinesspec.initConfiguration.timeoutsstruct has been added with the following fields:controlPlaneComponentHealthCheckSecondskubeletHealthCheckSecondskubernetesAPICallSecondsetcdAPICallSecondstlsBootstrapSecondsdiscoverySeconds
spec.joinConfiguration.timeoutsfield has been added with the same set of timeouts listed abovespec.clusterConfiguration.apiServer.timeoutForControlPlanefield has been removed Usespec.initConfiguration.timeouts.controlPlaneComponentHealthCheckSecondsandspec.joinConfiguration.timeouts.controlPlaneComponentHealthCheckSecondsinstead; however, using different timeouts for init and join will be enabled only when v1beta1 is removedspec.joinConfiguration.discovery.timeoutfield has been removed. Usespec.joinConfiguration.timeouts.tlsBootstrapSecondsinstead
- The
spec.clusterConfiguration.certificateValidityPeriodDaysandspec.clusterConfiguration.caCertificateValidityPeriodDayshave been added thus aligning with kubeadm v1beta4 API - The
spec.clusterConfiguration.apiServerfield does not embedControlPlaneComponentanymore (avoid embedding structs)extraArgs,extraVolumes,extraEnvsfields have been added to thespec.clusterConfiguration.apiServerstruct
- The type of the
spec.clusterConfiguration.controllerManagerfield has been changed fromControlPlaneComponenttoControllerManager(avoid embedding structs) - The type of the
spec.clusterConfiguration.schedulerfield has been changed fromControlPlaneComponenttoScheduler(avoid embedding structs) - The type of the
extraEnvsfields inspec.clusterConfiguration.apiServer,spec.clusterConfiguration.controllerManager,spec.clusterConfiguration.schedulerandspec.clusterConfiguration.etcd.localhas been changed from[]EnvVarto*[]EnvVar(compliance with K8s API guidelines) - The type of the
spec.clusterConfiguration.apiServer.extraVolumes.readOnly,spec.clusterConfiguration.controllerManager.extraVolumes.readOnly,spec.clusterConfiguration.scheduler.extraVolumes.readOnlyfields have been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.initConfiguration.bootstrapTokens[].tokenfield has been changed from*BootstrapTokenStringtoBootstrapTokenString(drop unnecessary pointers) - The type of the
spec.initConfiguration.nodeRegistration,spec.joinConfiguration.nodeRegistrationfields have been changed from[]corev1.Taintto*[]corev1.Taint(avoid custom serialization) - The type of the
spec.joinConfiguration.discovery.bootstrapToken.unsafeSkipCAVerificationfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.joinConfiguration.discovery.file.kubeConfig.cluster.insecureSkipTLSVerifyfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.joinConfiguration.discovery.file.kubeConfig.user.exec.provideClusterInfofield has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.files[].appendfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.users[].gecos,spec.users[].groups,spec.users[].homeDir,spec.users[].shell,spec.users[].passwd,spec.users[].pr,spec.users[].sudofields have been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.diskSetup.filesystems[].partition,spec.diskSetup.filesystems[].replaceFSfields have been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.diskSetup.partitions[].tableTypefield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.diskSetup.partitions[].layoutfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.ignition.containerLinuxConfig.strictfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The
spec.useExperimentalRetryJoinfield (deprecated in CAPI v1.2!) has been removed - The following
specfields have been removed because they are not necessary because Cluster API automatically applies the right gvk when generating kubeadm config files:clusterConfiguration.apiVersion,clusterConfiguration.kindinitConfiguration.apiVersion,initConfiguration.kindjoinConfiguration.apiVersion,joinConfiguration.kind
- The following
spec.clusterConfigurationfields have been removed because they are duplicates to fields that already exist in the Cluster object:networking.serviceSubnet(can still be set viaCluster.spec.clusterNetwork.services.cidrBlocks)networking.podSubnet(can still be set viaCluster.spec.clusterNetwork.pods.cidrBlocks)networking.dnsDomain(can still be set viaCluster.spec.clusterNetwork.serviceDomain)kubernetesVersion(can still be set viaMachine.spec.version)clusterName(can still be set viaCluster.metadata.name) Note: The ClusterConfiguration fields could previously be used to overwrite the fields from Cluster, now we only use the fields from Cluster
- All fields of type Duration in
spec.initConfiguration.bootstrapTokens[]have been renamed by adding theSecondssuffix and their type was changed to int32 (compliance with K8s API guidelines).ttl=>.ttlSeconds
- The type of the
spec.initConfiguration.bootstrapTokens[].expiresfield has been changed from*metav1.Timetometav1.Time(drop unnecessary pointers) status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
- The type of the field
status.dataSecretNamehas been changed from*stringtostring(drop unnecessary pointers) - Information about the initial provisioning process is now surfacing under the new
status.initializationfield (improve status)status.readyhas been replaced bystatus.initialization.dataSecretCreated
- Support for terminal errors has been dropped (improve status)
status.failureReasonandstatus.failureMessagewill continue to exist temporarily understatus.deprecated.v1beta1
KubeadmConfigTemplate
KubeadmConfigTemplate spec.template.spec has been aligned to changes in the KubeadmConfig spec struct
KubeadmControlPlane
| v1beta1 | v1beta2 |
|
|
- KubeadmControlPlane (and the entire KCP provider) now implements the v1beta2 Cluster API contract
- See changes that apply to all CRDs
- Pointers have been removed from various struct fields. See #12545 and #12560 for details (drop unnecessary pointers)
- The
spec.machineNamingStrategyfield was renamed tospec.machineNamingand is now usingMachineNamingSpectype instead of*MachineNamingStrategy(improve consistency, drop unnecessary pointers) - The
spec.machineTemplate.infrastructureReffield was moved tospec.machineTemplate.spec.infrastructureRefand is now usingContractVersionedObjectReferencetype instead ofcorev1.ObjectReference- The following fields have been removed:
namespace,uid,resourceVersion,fieldPath apiVersionhas been replaced withapiGroup. As before, the version will be read from the corresponding CRD
- The following fields have been removed:
- The
spec.machineTemplate.readinessGatesfield was moved tospec.machineTemplate.spec.readinessGates. extraArgfield types have been changed frommap[string]stingto[]Arg, thus aligning with kubeadm v1beta4 API; however, using multiple args with the same name will be enabled only when v1beta1 is removed, tentatively in August 2026spec.kubeadmConfigSpec.clusterConfiguration.apiServer.extraArgstype has been changed to[]Argspec.kubeadmConfigSpec.clusterConfiguration.controllerManager.extraArgstype has been changed to[]Argspec.kubeadmConfigSpec.clusterConfiguration.scheduler.extraArgstype has been changed to[]Argspec.kubeadmConfigSpec.clusterConfiguration.etcd.local.extraArgstype has been changed to[]Argspec.kubeadmConfigSpec.initConfiguration.nodeRegistration.kubeletExtraArgstype has been changed to[]Argspec.kubeadmConfigSpec.joinConfiguration.nodeRegistration.kubeletExtraArgstype has been changed to[]Arg
imagePullPolicyfield types have been changed fromstringtocorev1.PullPolicy, thus aligning with kubeadm v1beta4 APIspec.kubeadmConfigSpec.initConfiguration.nodeRegistration.imagePullPolicytype has been changed tocorev1.PullPolicyspec.kubeadmConfigSpec.joinConfiguration.nodeRegistration.imagePullPolicytype has been changed tocorev1.PullPolicy
timeoutfields have been aligned with kubeadm v1beta4 API, but field names and types have been adapted according to API guidelinesspec.kubeadmConfigSpec.initConfiguration.timeoutsstruct has been added with the following fields:controlPlaneComponentHealthCheckSecondskubeletHealthCheckSecondskubernetesAPICallSecondsetcdAPICallSecondstlsBootstrapSecondsdiscoverySeconds
spec.kubeadmConfigSpec.joinConfiguration.timeoutsfield has been added with the same set of timeouts listed abovespec.kubeadmConfigSpec.clusterConfiguration.apiServer.timeoutForControlPlanefield has been removed Usespec.kubeadmConfigSpec.initConfiguration.timeouts.controlPlaneComponentHealthCheckSecondsandspec.kubeadmConfigSpec.joinConfiguration.timeouts.controlPlaneComponentHealthCheckSecondsinstead; however, using different timeouts for init and join will be enabled only when v1beta1 is removedspec.kubeadmConfigSpec.joinConfiguration.discovery.timeoutfield has been removed. Usespec.kubeadmConfigSpec.joinConfiguration.timeouts.tlsBootstrapSecondsinstead
- The
spec.kubeadmConfigSpec.clusterConfiguration.certificateValidityPeriodDaysandspec.kubeadmConfigSpec.clusterConfiguration.caCertificateValidityPeriodDayshave been added thus aligning with kubeadm v1beta4 API - The
spec.kubeadmConfigSpec.clusterConfiguration.apiServerfield does not embedControlPlaneComponentanymore (avoid embedding structs)extraArgs,extraVolumes,extraEnvsfields have been added to thespec.kubeadmConfigSpec.clusterConfiguration.apiServerstruct
- The type of the
spec.kubeadmConfigSpec.clusterConfiguration.controllerManagerfield has been changed fromControlPlaneComponenttoControllerManager(avoid embedding structs) - The type of the
spec.kubeadmConfigSpec.clusterConfiguration.schedulerfield has been changed fromControlPlaneComponenttoScheduler(avoid embedding structs) - The type of the
extraEnvsfields inspec.kubeadmConfigSpec.clusterConfiguration.apiServer,spec.kubeadmConfigSpec.clusterConfiguration.controllerManager,spec.kubeadmConfigSpec.clusterConfiguration.schedulerandspec.kubeadmConfigSpec.clusterConfiguration.etcd.localhas been changed from[]EnvVarto*[]EnvVar(compliance with K8s API guidelines) - The type of the
spec.kubeadmConfigSpec.clusterConfiguration.apiServer.extraVolumes.readOnly,spec.kubeadmConfigSpec.clusterConfiguration.controllerManager.extraVolumes.readOnly,spec.kubeadmConfigSpec.clusterConfiguration.scheduler.extraVolumes.readOnlyfields have been changed fromboolto*bool(avoid custom serialization) - The type of the
spec.kubeadmConfigSpec.initConfiguration.bootstrapTokens[].tokenfield has been changed from*BootstrapTokenStringtoBootstrapTokenString(drop unnecessary pointers) - The type of the
spec.kubeadmConfigSpec.initConfiguration.nodeRegistration,spec.kubeadmConfigSpec.joinConfiguration.nodeRegistrationfields have been changed from[]corev1.Taintto*[]corev1.Taint(avoid custom serialization) - The type of the
spec.kubeadmConfigSpec.joinConfiguration.discovery.bootstrapToken.unsafeSkipCAVerificationfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.kubeadmConfigSpec.joinConfiguration.discovery.file.kubeConfig.cluster.insecureSkipTLSVerifyfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.kubeadmConfigSpec.joinConfiguration.discovery.file.kubeConfig.user.exec.provideClusterInfofield has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.kubeadmConfigSpec.files[].appendfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.kubeadmConfigSpec.users[].gecos,spec.kubeadmConfigSpec.users[].groups,spec.kubeadmConfigSpec.users[].homeDir,spec.kubeadmConfigSpec.users[].shell,spec.kubeadmConfigSpec.users[].passwd,spec.kubeadmConfigSpec.users[].primaryGroup,spec.kubeadmConfigSpec.users[].sudofields have been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.kubeadmConfigSpec.diskSetup.filesystems[].partition,spec.kubeadmConfigSpec.diskSetup.filesystems[].replaceFSfields have been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.kubeadmConfigSpec.diskSetup.partitions[].tableTypefield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.kubeadmConfigSpec.diskSetup.partitions[].layoutfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The type of the
spec.kubeadmConfigSpec.ignition.containerLinuxConfig.strictfield has been changed fromboolto*bool(compliance with K8s API guidelines) - The
spec.kubeadmConfigSpec.useExperimentalRetryJoinfield (deprecated in CAPI v1.2!) has been removed - The following
spec.kubeadmConfigSpecfields have been removed because they are not necessary (Cluster API automatically applies the right gvk when generating kubeadm config files):clusterConfiguration.apiVersion,clusterConfiguration.kindinitConfiguration.apiVersion,initConfiguration.kindjoinConfiguration.apiVersion,joinConfiguration.kind
- The following
spec.kubeadmConfigSpec.clusterConfigurationfields have been removed because they are duplicates to fields that already exist in the Cluster object:networking.serviceSubnet(can still be set viaCluster.spec.clusterNetwork.services.cidrBlocks)networking.podSubnet(can still be set viaCluster.spec.clusterNetwork.pods.cidrBlocks)networking.dnsDomain(can still be set viaCluster.spec.clusterNetwork.serviceDomain)kubernetesVersion(can still be set viaKubeadmControlPlane.spec.version)clusterName(can still be set viaCluster.metadata.name) Note: The ClusterConfiguration fields could previously be used to overwrite the fields from Cluster, now we only use the fields from Cluster
- All fields of type Duration in
spec.kubeadmConfigSpec.initConfiguration.bootstrapTokens[]have been renamed by adding theSecondssuffix and their type was changed to int32 (compliance with K8s API guidelines).ttl=>.ttlSeconds
- The type of the
spec.kubeadmConfigSpec.initConfiguration.bootstrapTokens[].expiresfield has been changed from*metav1.Timetometav1.Time(drop unnecessary pointers) - All fields of type Duration in
spec.machineTemplatehave been renamed by adding theSecondssuffix, moved into thedeletionsection and their type was changed to int32 (compliance with K8s API guidelines)nodeDrainTimeout=>deletion.nodeDrainTimeoutSecondsnodeVolumeDetachTimeout=>deletion.nodeVolumeDetachTimeoutSecondsnodeDeletionTimeout=>deletion.nodeDeletionTimeoutSeconds
- All fields of type Duration in
spec.remediationStrategyhave been renamed by adding theSecondssuffix and their type was changed to int32 (compliance with K8s API guidelines)retryPeriod=>retryPeriodSecondsminHealthyPeriod=>minHealthyPeriodSeconds
- The type of the
spec.versionfield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.remediationfield (previouslyspec.remediationStrategy) has been changed fromRemediationStrategytoKubeadmControlPlaneRemediationSpec(improve consistency) - A new
spec.rolloutfield has been introduced, it combines previousspec.rolloutBefore,spec.rolloutAfterandspec.rolloutStrategyfields. The Go structs have been modified accordingly. For more details see YAML above (improve consistency)- The type of the
spec.rollout.after, previouslyspec.rolloutAfter, field has been changed from*metav1.Timetometav1.Time(drop unnecessary pointers)
- The type of the
- The type of the
spec.remediation.retryPeriodSecondsfield (previouslyspec.remediationStrategy.retryPeriod) has been changed from*stringtostring(drop unnecessary pointers) status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
- Replica counters fields are now consistent with replica counters from other resources (improve status)
status.replicaswas made a pointer and omitempty was addedstatus.readyReplicashas now a new semantic based on machine’sReadyconditionstatus.availableReplicashas now a new semantic based on machine’sAvailableconditionstatus.upToDateReplicashas now a new semantic (and name) based on machine’sUpToDatecondition- Temporarily, old replica counters will still be available under the
status.deprecated.v1beta1struct
- Information about the initial provisioning process is now surfacing under the new
status.initializationfield (improve status)status.readyhas been droppedstatus.initializedhas been replaced bystatus.initialization.controlPlaneInitialized
- Support for terminal errors has been dropped (improve status)
status.failureReasonandstatus.failureMessagewill continue to exist temporarily understatus.deprecated.v1beta1
- The type of the
status.versionfield has been changed from*stringtostring(drop unnecessary pointers) - The
status.lastRemediation.timestampfield has been renamed tostatus.lastRemediation.time(compliance with K8s API guidelines) - The type of the
status.lastRemediation.retryCountfield has been changed fromint32to*int32(compliance with K8s API guidelines)
KubeadmControlPlaneTemplate
KubeadmControlPlaneTemplate spec.template.spec has been aligned to changes in the KubeadmControlPlane spec struct
ClusterResourceSet
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
ClusterResourceSetBinding
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
- The type of the
spec.bindingsfield has been changed from[]*ResourceSetBindingto[]ResourceSetBinding(drop unnecessary pointers) - The type of the
spec.bindings[].resources[].lastAppliedTimefield has been changed from*metav1.Timetometav1.Time(drop unnecessary pointers) - The type of the
spec.bindings[].resources[].appliedfield has been changed fromboolto*bool(compliance with K8s API guidelines) - Remove deprecated
ClusterResourceSetBinding.DeleteBindingfunc
ExtensionConfig
| v1beta1 | v1beta2 |
|
|
ExtensionConfigv1beta2 has been created, thus aligning with other Cluster API resourcesExtensionConfigv1alpha1 has been deprecated, and it will be removed in a following release- See changes that apply to all CRDs
- Pointers have been removed from various struct fields. See #12545 for details (drop unnecessary pointers)
- The type of the
spec.clientConfig.urlfield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.clientConfig.service.pathfield has been changed from*stringtostring(drop unnecessary pointers) status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
- The type of the
status.handlers[].timeoutSecondsfield has been changed from*int32toint32(drop unnecessary pointers) - The type of the
status.handlers[].failurePolicyfield has been changed from*FailurePolicytoFailurePolicy(drop unnecessary pointers)
IPAddress
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
- The type of the
spec.claimReffield has been changed fromcorev1.LocalObjectReferencetoIPAddressClaimReference(improve object references) - The type of the
spec.poolReffield has been changed fromcorev1.TypedLocalObjectReferencetoIPPoolReference(improve object references) - The type of the
spec.poolRef.apiGroupfield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
spec.prefixfield has been changed fromint32to*int32(compliance with K8s API guidelines)
IPAddressClaim
| v1beta1 | v1beta2 |
|
|
- See changes that apply to all CRDs
- The type of the
spec.poolReffield has been changed fromcorev1.TypedLocalObjectReferencetoIPPoolReference(improve object references) - The type of the
spec.poolRef.apiGroupfield has been changed from*stringtostring(drop unnecessary pointers) - The type of the
status.addressReffield has been changed fromcorev1.LocalObjectReferencetoIPAddressReference(improve object references) status.conditionshas been replaced withstatus.v1beta2.conditionsbased on metav1 condition types (improve status)- the old
status.conditionsbased on custom cluster API condition types will continue to exist temporarily understatus.deprecated.v1beta1.conditionsfor the sake of down conversions and to provide a temporary option for users willing to continue using old conditions.
- the old
Cluster API Contract changes
-
v1beta1 version of the Cluster API contract is now deprecated
- In order to ease the transition to the new v1beta2 version of the Cluster API contract, v1beta2 version
will implement temporarily compatibility with the deprecated v1beta1 version of the Cluster API contract
- Compatibility is only intended to ease the transition for providers, and it has some limitations; please read details in following paragraphs.
- Compatibility support for the v1beta1 version of the Cluster API contract will be removed tentatively in August 2026
- After compatibility support for the v1beta1 version of the Cluster API contract is removed, providers which are implementing the v1beta1 contract will stop to work (they will work only with older versions of Cluster API).
- In order to ease the transition to the new v1beta2 version of the Cluster API contract, v1beta2 version
will implement temporarily compatibility with the deprecated v1beta1 version of the Cluster API contract
-
v1beta2 version of the Cluster API contract has been introduced; see following paragraphs for more details
Contract rules for InfraCluster
Following rules have been changed or are not supported anymore; please read corresponding notes about compatibility for providers still implementing the v1beta1 contract.
- InfraCluster: control plane endpoint
- InfraCluster: failure domains
- InfraCluster: initialization completed
- InfraCluster: conditions
- The fact that Providers are not required to implement conditions remains valid
- In case a provider implements conditions, Cluster API doesn’t require anymore usage of a specific condition type,
even if transition to
metav1.Conditionsis highly recommended.
- InfraCluster: terminal failures
- The Cluster controller won’t consider the presence of
status.failureReasonandstatus.failureMessageinfo as “terminal failures”
- The Cluster controller won’t consider the presence of
Contract rules for InfraMachine
Following rules have been changed or are not supported anymore; please read corresponding notes about compatibility for providers still implementing the v1beta1 contract.
- InfraMachine: provider ID
- Type of the
spec.providerIDfield was changed from*stringtostring.
- Type of the
- InfraMachine: initialization completed
- InfraMachine: conditions
- The fact that Providers are not required to implement conditions remains valid
- In case a provider implements conditions, Cluster API doesn’t require anymore usage of a specific condition type,
even if transition to
metav1.Conditionsis highly recommended.
- InfraMachine: terminal failures
- The Machine controller won’t consider the presence of
status.failureReasonandstatus.failureMessageinfo as “terminal failures” - MachineHealthCheck controller won’t consider the presence of
status.failureReasonandstatus.failureMessageto determine when a Machine needs remediation.
- The Machine controller won’t consider the presence of
Contract rules for BootstrapConfig
Following rules have been changed or are not supported anymore; please read corresponding notes about compatibility for providers still implementing the v1beta1 contract.
- BootstrapConfig: initialization completed
- BootstrapConfig: data secret
- Type of the
status.dataSecretNamefield was changed from*stringtostring.
- Type of the
- BootstrapConfig: conditions
- The fact that Providers are not required to implement conditions remains valid
- In case a provider implements conditions, Cluster API doesn’t require anymore usage of a specific condition type,
even if transition to
metav1.Conditionsis highly recommended.
- BootstrapConfig: terminal failures
- The Machine controller won’t consider the presence of
status.failureReasonandstatus.failureMessageinfo as “terminal failures” - MachineHealthCheck controller won’t consider the presence of
status.failureReasonandstatus.failureMessageto determine when a Machine needs remediation.
- The Machine controller won’t consider the presence of
Contract rules for ControlPlane
Following rules have been changed or are not supported anymore; please read corresponding notes about compatibility for providers still implementing the v1beta1 contract.
- ControlPlane: control plane endpoint
- ControlPlane: machines
- ControlPlane: initialization completed
- ControlPlane: replicas
- ControlPlane: version
- Type of the
status.versionfield was changed from*stringtostring.
- Type of the
- ControlPlane: machines
- Type of the
status.externalManagedControlPlanefield was changed fromboolto*bool. - Fields in
spec.machineTemplatewere restructured.
- Type of the
- ControlPlane: conditions
- The fact that Providers are not required to implement conditions remains valid
- In case a provider implements conditions, Cluster API doesn’t require anymore usage of a specific condition type,
even if transition to
metav1.Conditionsis highly recommended.
- ControlPlane: terminal failures
- The Cluster controller won’t consider the presence of
status.failureReasonandstatus.failureMessageinfo as “terminal failures”
- The Cluster controller won’t consider the presence of
Contract rules for IPAM provider
TODO
Contract rules for MachinePool
TODO
clusterctl
- Stricter validation for provider metadata: clusterctl now enforces validation rules when reading provider metadata files to ensure they are properly formatted and contain required information.
These changes help surface mis-shaped metadata early and make failures easier to troubleshoot. Providers with invalid metadata.yaml files will need to update them to comply with these validation rules.
The following validation rules are now enforced:
apiVersionmust be set toclusterctl.cluster.x-k8s.io/v1alpha3kindmust be set toMetadatareleaseSeriesmust contain at least one entry
- The
--v1beta2flag in clusterctl describe now defaults totrue; the flag will be removed as soon as v1beta1 API is removed.
Deprecations
-
v1beta1 API version is deprecated and it will be removed tentatively in August 2026
- All the fields under
status.deprecated.v1beta1in the new v1beta2 API are deprecated and whey will be removed. This includes:status.deprecated.v1beta1.conditionsbased on custom cluster API condition typesstatus.deprecated.v1beta1.failureReasonstatus.deprecated.v1beta1.failureMessagestatus.deprecated.v1beta1.readyReplicaswith old semantic forMachineDeployments,MachineSetandKubeadmControlPlanestatus.deprecated.v1beta1.availableReplicaswith old semantic forMachineDeployments,MachineSetstatus.deprecated.v1beta1.unavailableReplicaswith old semantic forMachineDeployments,KubeadmControlPlanestatus.deprecated.v1beta1.updatedReplicaswith old semantic (and name) forMachineDeployments,KubeadmControlPlanestatus.deprecated.v1beta1.fullyLabeledReplicasforMachineSet
- All the fields under
-
v1beta1 conditions utils are now deprecated, and will removed as soon as v1beta1 API will be removed
-
v1beta1 support in the patch helper is now deprecated, and will removed as soon as v1beta1 API will be removed
-
As a consequence of dropping support for terminal errors from all Kinds, the const values for
Failedphase has been deprecated in the following enum types (controllers are not setting this value anymore):ClusterPhase, used incluster.status.phaseMachineDeploymentPhase, used inmachineDeployment.status.phaseMachinePoolPhase, used inmachinePool.status.phaseMachinePhase, used inmachine.status.phase
clusterctl changes
- The
clusterctl alpha rollout undocommand has been removed as the corresponding revision history feature has been removed from MachineDeployment
Removals scheduled for future releases
As documented in Suggested changes for providers, it is highly recommended to start planning for future removals:
- v1beta1 API version will be removed tentatively in August 2026
- Starting from the CAPI release when v1beta1 removal will happen (tentative Aug 2026), the Cluster API project
will remove the Cluster API condition type, the
util/conditions/deprecated/v1beta1package, theutil/deprecated/v1beta1package, the code handling old conditions inutil/patch.Helperand everything related to the custom Cluster API custom condition type. - Compatibility support for the v1beta1 version of the Cluster API contract will be removed tentatively in August 2026
Recommendation for everyone
- As a general recommendation we suggest to upgrade first to CAPI v1.10 before moving to CAPI v1.11 / v1beta2.
- v1.10 introduced additional field validation on API fields.
- Upgrading to v1.10 allows you to first address potential issues with existing invalid field values before picking up CAPI v1.11 / v1beta2, which will start converting v1beta1 objects to v1beta2 objects.
Suggested changes for clients using Cluster API Go types
-
We highly recommend providers to start using Cluster API v1beta2 types when bumping to CAPI v1.11. This requires changing following import:
import ( ... clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta1" )into:
import ( ... clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" )Please refer to API Changes for more details about the changes introduced by this release.
Note: it is technically possible for providers to keep using v1beta1 types from CAPI v1.11, but this is not recommended because it will lead to additional conversion calls.
Additionally, in v1.11 all the CAPI utils like e.g.
IsControlPlaneMachineare now using v1beta2 API types. This might lead to additional work for providers to keep using v1beta1 types from CAPI v1.11 (you have to fork all utils the provider is using from an older CAPI release or replace them with something else).Last but not least, please be aware that given the issues above, this approach was not tested during the implementation, and we don’t know if there are road blockers.
-
If you are using Conditions from Cluster API resources, e.g. by looking at the
ControlPlaneInitializedcondition on the Cluster object, we highly recommend clients to use new conditions instead of old ones. Utils for working with new conditions are available in thesigs.k8s.io/cluster-api/util/conditionspackage.- To keep using old conditions from the Cluster object, temporarily present under
status.deprecated.v1beta1.conditionsit is required to use utils from theutil/conditions/deprecated/v1beta1package. Please note thatstatus.deprecated.v1beta1.conditionswill be removed tentatively in August 2026.
- To keep using old conditions from the Cluster object, temporarily present under
-
References on Cluster, KubeadmControlPlane, MachineDeployment, MachinePool, MachineSet and Machine are now using the
ContractVersionedObjectReferencetype instead ofcorev1.ObjectReference. These references can now be resolved withexternal.GetObjectFromContractVersionedRefinstead ofexternal.Get:external.GetObjectFromContractVersionedRef(ctx, r.Client, cluster.Spec.InfrastructureRef, cluster.Namespace) -
Go clients writing status of core Cluster API objects, should use at least Cluster API v1.9 Go types. If that is not possible, avoid updating or patching the entire status field and instead you should patch only individual fields. (Cluster API v1.9 introduced
.status.v1beta2fields that are necessary for lossless v1beta2 => v1beta1 => v1beta2 round trips) -
Important! Please pay attention to field removals, e.g. if you are using Go types to write object, either migrate to v1beta2 or make sure to stop setting the removed fields. The removed fields won’t be preserved even if setting them via v1beta1 Go types.
-
All
metav1.Durationfields (e.g.nodeDeletionTimeout) are now represented as*int32fields with units being part of the field name (e.g.nodeDeletionTimeoutSeconds).- A side effect of this is that if durations were specified on a sub-second granularity conversion will truncate to seconds.
E.g. this means if you apply a v1beta1 object with
nodeDeletionTimeout: 1s5msonly1swill be stored and returned on reads.
- A side effect of this is that if durations were specified on a sub-second granularity conversion will truncate to seconds.
E.g. this means if you apply a v1beta1 object with
Suggested changes for providers
-
All recommendations in Suggested changes for clients using Cluster API Go types also apply to providers.
-
If providers are using Conditions from Cluster API resources, e.g. by looking at the
ControlPlaneInitializedcondition on the Cluster object, we highly recommend providers to use new conditions instead of old ones. Utils for working with new conditions ara available in thesigs.k8s.io/cluster-api/util/conditionspackage.- To keep using old conditions from the Cluster object, temporarily present under
status.deprecated.v1beta1.conditionsit is required to use utils from theutil/conditions/deprecated/v1beta1package. Please note thatstatus.deprecated.v1beta1.conditionswill be removed tentatively in August 2026.
- To keep using old conditions from the Cluster object, temporarily present under
-
We highly recommend providers to start planning the move to the new v1beta2 version of the Cluster API contract for their own resources, e.g. in the AWSCluster or the AWSMachine resource; the transition MUST be completed before compatibility support for the v1beta1 version of the Cluster API contract will be removed tentatively in August 2026
-
Depending on which Cluster API contract version you are choosing to implement in the provider’s own CRDs, please refer to:
-
We highly recommend providers to define their future strategy for condition management for their own resources, e.g. in the AWSCluster or the AWSMachine resource; also in this case the transition to the new condition management strategy MUST be completed before compatibility support for the v1beta1 version of the Cluster API contract will be removed tentatively in August 2026. Available options are:
- Migrate to
metav1.Conditionslike Cluster API (recommended) - Replace Cluster API’s v1beta1 Conditions with a custom condition implementation that is compliant with
what is required by the v1beta2 Cluster API contract.
- Starting from the CAPI release when v1beta1 removal will happen (tentative August 2026), the Cluster API project
will remove the Cluster API condition type, the
util/conditions/deprecated/v1beta1package, theutil/deprecated/v1beta1package, the code handling old conditions inutil/patch.Helperand everything related to the custom Cluster API custom condition type.
- Starting from the CAPI release when v1beta1 removal will happen (tentative August 2026), the Cluster API project
will remove the Cluster API condition type, the
- Migrate to
-
Depending on which option you are choosing for condition management in the provider’s own CRDs, please refer to:
-
References on Cluster, KubeadmControlPlane, MachineDeployment, MachinePool, MachineSet and Machine are now using the
ContractVersionedObjectReferencetype instead ofcorev1.ObjectReference. These references can now be resolved withexternal.GetObjectFromContractVersionedRefinstead ofexternal.Get:external.GetObjectFromContractVersionedRef(ctx, r.Client, cluster.Spec.InfrastructureRef, cluster.Namespace) -
core Cluster API added the new CRD migrator component in the v1.9 release. For more details, see: https://github.com/kubernetes-sigs/cluster-api/issues/11894
- CRD migration in clusterctl has been deprecated and will be removed in CAPI v1.13, so it’s recommended to adopt the CRD migrator in providers instead.
- Please see the examples in https://github.com/kubernetes-sigs/cluster-api/pull/11889, the following high-level steps are required:
- Add the
--skip-crd-migration-phasescommand-line flag that allows to skip CRD migration phases - Setup the
CRDMigratorcomponent with the manager. - Configure all CRDs owned by your provider, only set
UseCachefor the objects for which your provider already has an informer. - Add the following RBAC:
- resources:
customresourcedefinitions, verbs:get;list;watch - resources:
customresourcedefinitions;customresourcedefinitions/status, resourceNames:<crd-name>, verbs:update;patch- Note: The CRD migrator will add the
crd-migration.cluster.x-k8s.io/observed-generationannotation on the CRD object, please ensure that if these CRD objects are deployed with a tool like kapp / Argo / Flux the annotation is not continuously removed.
- Note: The CRD migrator will add the
- For all CRs that should be migrated by the
CRDMigrator: verbs:get;list;watch;patch;update - For all CRs with
UseStatusForStorageVersionMigration: trueverbs:update;patchon their/statusresource (e.g.ipaddressclaims/status)
- Add the
How to bump to CAPI V1.11 but keep implementing the deprecated v1beta1 contract
CAPI v1.11 implements the v1beta2 version of the Cluster API contract.
However, in order to ease the transition for providers, the v1beta2 version of the Cluster API contract temporarily preserves compatibility with the deprecated v1beta1 contract; a few limitations apply, please read Cluster API Contract changes for more details.
Provider’s implementing the deprecated v1beta1 contract can leverage compatibility support without any change, but it is crucial for them to start planning for the implementation of the new v1beta2 version of the Cluster API contract as soon a possible.
The implementation of the new v1beta2 version of the Cluster API contract MUST be completed before compatibility support for the v1beta1 version of the Cluster API contract will be removed tentatively in August 2026.
After compatibility support for the v1beta1 version of the Cluster API contract will be removed, providers which are still implementing the v1beta1 contract will stop to work (they will work only with older versions of Cluster API).
Please see Cluster API Contract changes and provider contracts for more details.
How to implement the new v1beta2 contract
We highly recommend providers to start planning the move to the new v1beta2 version of the Cluster API contract as soon as possible.
Implementing the new v1beta2 contract for providers is a multistep operation:
- Implement changes defined for a specific provider type; See Cluster API Contract changes and provider contracts for more details.
- In most cases, v1beta2 contract introduced changes in the
initialization completed,conditions,terminal failuresrules; Alsoreplicasrule is changed for control plane providers. - If providers are starting to use
api/core/v1beta2/clusterv1.ObjectMetain your API types, please note that it is necessary to set theomitzeroJSON marker
- While implementing the changes above, It is also highly recommended to check the implementation of all the other rules (documentation for contract rules have been improved in recent releases, worth to take a look!).
- Change the CRD annotation that document which Cluster API contract is implemented by your Provider. e.g.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
cluster.x-k8s.io/v1beta2: <your API version>
name: <your CRD name>
How to bump to CAPI V1.11 but keep using deprecated v1beta1 conditions
A provider can continue to use deprecated v1beta1 conditions also after bumping to CAPI V1.11, but to do so it is required to change following imports:
import (
...
"sigs.k8s.io/cluster-api/util/conditions"
"sigs.k8s.io/cluster-api/util/patch"
)
into:
import (
...
v1beta1conditions "sigs.k8s.io/cluster-api/util/deprecated/v1beta1/conditions"
v1beta1patch "sigs.k8s.io/cluster-api/util/deprecated/v1beta1/patch"
)
Important!
Please pay special attention to use sigs.k8s.io/cluster-api/util/deprecated/v1beta1/patch import everywhere,
because using sigs.k8s.io/cluster-api/util/patch by mistake could in some cases lead to dropping conditions at runtime.
Also, please note that starting from the CAPI release when v1beta1 removal will happen (tentative Aug 2026), the Cluster API project
will remove the Cluster API condition type, the util/conditions/deprecated/v1beta1 package, the util/deprecated/v1beta1 package,
the code handling old conditions in util/patch.Helper and everything related to the custom Cluster API custom condition type.
This means that if a provider wants to keep using deprecated v1beta1 conditions after this date, they have to maintain their own custom copy of the types and related utils.
Also note that the v1beta2 contract is not going to require a specific condition type, so it will be also possible to use a custom condition type,
See Suggested changes for providers and Cluster API Contract changes for more details.
How to start using metav1.conditions
If providers choose to migrate metav1.Conditions, the process described in Improving status in CAPI resources
can be used as a reference about how to implement a phased transition.
As a quick summary, transition should go through following phases:
Stage 1
Add status.v1beta2.conditions to your API (existing conditions will remain at status.conditions)
If you are at this stage, you must use following util packages from CAPI v1.11 (or following releases, see note below):
import (
...
v1beta1conditions "sigs.k8s.io/cluster-api/util/deprecated/v1beta1/conditions"
v1beta2conditions "sigs.k8s.io/cluster-api/util/deprecated/v1beta1/conditions/v1beta2"
v1beta1patch "sigs.k8s.io/cluster-api/util/deprecated/v1beta1/patch"
)
- the
v1beta1conditionspackage alias provides access to utils for managingclusterv1beta1.Conditionsinstatus.conditions - the
v1beta2conditionspackage alias provides access to utils for managingmetav1.Conditionsinstatus.v1beta2.conditions - the
v1beta1patchpackage alias provides access to utils for patching objects in this phase.
Important!
- Please pay special attention to use
sigs.k8s.io/cluster-api/util/deprecated/v1beta1/patchimport everywhere, because usingsigs.k8s.io/cluster-api/util/patchby mistake could in some cases lead to dropping conditions at runtime (note:sigs.k8s.io/cluster-api/util/patchis the package we assume you are using before stage 1). - All packages from the import above (all packages below
sigs.k8s.io/cluster-api/util/deprecated/v1beta1) are going to be removed from CAPI when the v1beta1 removal will happen (tentative Aug 2026).
Stage 2
Create a new API version, swap old conditions and new conditions, implement conversions
- Move old conditions from
status.conditionstostatus.deprecated.v1beta1.conditions - Move new conditions from
status.v1beta2.conditionstostatus.conditions
If you are at this stage, you must use following util packages from CAPI v1.11 (or following releases, see note below):
import (
...
"sigs.k8s.io/cluster-api/util/conditions"
deprecatedv1beta1conditions "sigs.k8s.io/cluster-api/util/conditions/deprecated/v1beta1"
"sigs.k8s.io/cluster-api/util/patch"
)
- the
conditionspackage provides access to utils for managingmetav1.Conditionsinstatus.conditions - the
deprecatedv1beta1conditionspackage alias provides access to utils for managingclusterv1.Conditionsinstatus.deprecated.v1beta1.conditions - the
patchpackage provides access to utils for patching objects in this phase
Important!
- Please pay special attention to use
sigs.k8s.io/cluster-api/util/patchimport everywhere, because usingsigs.k8s.io/cluster-api/util/deprecated/v1beta1/patchby mistake could in some cases lead to dropping conditions at runtime (note:sigs.k8s.io/cluster-api/util/deprecated/v1beta1/patchis the package you were using in stage 1, it should not be used in stage 2). - The package
sigs.k8s.io/cluster-api/util/conditions/deprecated/v1beta1“ is going to be removed from CAPI when the v1beta1 removal will happen (tentative Aug 2026).
Stage 3
When removing the old API version, remove status.deprecated.v1beta1
Following util packages from CAPI v1.11 (or following releases) should be still in use:
import (
...
"sigs.k8s.io/cluster-api/util/conditions"
"sigs.k8s.io/cluster-api/util/patch"
)
- the
conditionspackage provides access to utils for managingmetav1.Conditionsinstatus.conditions - the
patchpackage provides access to utils for patching objects in this phase
Important!
- Please pay special attention to use
sigs.k8s.io/cluster-api/util/patchimport everywhere, because usingsigs.k8s.io/cluster-api/util/deprecated/v1beta1/patchby mistake could in some cases lead to dropping conditions at runtime (note:sigs.k8s.io/cluster-api/util/deprecated/v1beta1/patchis the package in stage 1, if should not be used in following stages).
Annex
Imports for conditions and patch helper utils
In order to help users to transition away from the CAPI conditions type, CAPI v1.11 supports different versions of conditions and patch helper utils.
Following table should help to pick the right utils.
| Field to change | Import for condition util | Import for patch helper |
|---|---|---|
status.conditions of type clusterv1beta1.Conditions | v1beta1conditions "sigs.k8s.io/cluster-api/util/deprecated/v1beta1/conditions" | v1beta1patch "sigs.k8s.io/cluster-api/util/deprecated/v1beta1/patch" |
status.v1beta2.conditions of type []metav1.Conditions | v1beta2conditions "sigs.k8s.io/cluster-api/util/deprecated/v1beta1/conditions/v1beta2" | v1beta1patch "sigs.k8s.io/cluster-api/util/deprecated/v1beta1/patch" |
status.deprecated.v1beta1.conditions of type clusterv1.Conditions | deprecatedv1beta1conditions "sigs.k8s.io/cluster-api/util/conditions/deprecated/v1beta1" | "sigs.k8s.io/cluster-api/util/patch" |
status.conditions of type []metav1.Conditions | "sigs.k8s.io/cluster-api/util/conditions" | "sigs.k8s.io/cluster-api/util/patch" |
Important!
- Please pay special attention to use the correct patch helper import everywhere, because using a wrong one could in some cases lead to dropping conditions at runtime while not having compile errors.