mirror of
https://github.com/kubernetes/kubernetes.git
synced 2026-04-29 01:59:25 -04:00
Merge pull request #134339 from huww98/mutable-pv-affinity
KEP-5381: mutable pv nodeAffinity
This commit is contained in:
commit
326ce8b16d
13 changed files with 41 additions and 9 deletions
2
api/openapi-spec/swagger.json
generated
2
api/openapi-spec/swagger.json
generated
|
|
@ -9488,7 +9488,7 @@
|
|||
},
|
||||
"nodeAffinity": {
|
||||
"$ref": "#/definitions/io.k8s.api.core.v1.VolumeNodeAffinity",
|
||||
"description": "nodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume."
|
||||
"description": "nodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume. This field is mutable if MutablePVNodeAffinity feature gate is enabled."
|
||||
},
|
||||
"persistentVolumeReclaimPolicy": {
|
||||
"description": "persistentVolumeReclaimPolicy defines what happens to a persistent volume when released from its claim. Valid options are Retain (default for manually created PersistentVolumes), Delete (default for dynamically provisioned PersistentVolumes), and Recycle (deprecated). Recycle must be supported by the volume plugin underlying this PersistentVolume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming",
|
||||
|
|
|
|||
2
api/openapi-spec/v3/api__v1_openapi.json
generated
2
api/openapi-spec/v3/api__v1_openapi.json
generated
|
|
@ -5018,7 +5018,7 @@
|
|||
"$ref": "#/components/schemas/io.k8s.api.core.v1.VolumeNodeAffinity"
|
||||
}
|
||||
],
|
||||
"description": "nodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume."
|
||||
"description": "nodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume. This field is mutable if MutablePVNodeAffinity feature gate is enabled."
|
||||
},
|
||||
"persistentVolumeReclaimPolicy": {
|
||||
"description": "persistentVolumeReclaimPolicy defines what happens to a persistent volume when released from its claim. Valid options are Retain (default for manually created PersistentVolumes), Delete (default for dynamically provisioned PersistentVolumes), and Recycle (deprecated). Recycle must be supported by the volume plugin underlying this PersistentVolume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming",
|
||||
|
|
|
|||
|
|
@ -800,7 +800,7 @@
|
|||
"$ref": "#/components/schemas/io.k8s.api.core.v1.VolumeNodeAffinity"
|
||||
}
|
||||
],
|
||||
"description": "nodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume."
|
||||
"description": "nodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume. This field is mutable if MutablePVNodeAffinity feature gate is enabled."
|
||||
},
|
||||
"persistentVolumeReclaimPolicy": {
|
||||
"description": "persistentVolumeReclaimPolicy defines what happens to a persistent volume when released from its claim. Valid options are Retain (default for manually created PersistentVolumes), Delete (default for dynamically provisioned PersistentVolumes), and Recycle (deprecated). Recycle must be supported by the volume plugin underlying this PersistentVolume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming",
|
||||
|
|
|
|||
|
|
@ -398,6 +398,7 @@ type PersistentVolumeSpec struct {
|
|||
VolumeMode *PersistentVolumeMode
|
||||
// NodeAffinity defines constraints that limit what nodes this volume can be accessed from.
|
||||
// This field influences the scheduling of pods that use this volume.
|
||||
// This field is mutable if MutablePVNodeAffinity feature gate is enabled.
|
||||
// +optional
|
||||
NodeAffinity *VolumeNodeAffinity
|
||||
// Name of VolumeAttributesClass to which this persistent volume belongs. Empty value
|
||||
|
|
|
|||
|
|
@ -2272,7 +2272,8 @@ func ValidatePersistentVolumeUpdate(newPv, oldPv *core.PersistentVolume, opts Pe
|
|||
allErrs = append(allErrs, ValidateImmutableField(newPv.Spec.VolumeMode, oldPv.Spec.VolumeMode, field.NewPath("volumeMode"))...)
|
||||
|
||||
// Allow setting NodeAffinity if oldPv NodeAffinity was not set
|
||||
if oldPv.Spec.NodeAffinity != nil {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.MutablePVNodeAffinity) &&
|
||||
oldPv.Spec.NodeAffinity != nil {
|
||||
allErrs = append(allErrs, validatePvNodeAffinity(newPv.Spec.NodeAffinity, oldPv.Spec.NodeAffinity, field.NewPath("nodeAffinity"))...)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1241,9 +1241,10 @@ func multipleVolumeNodeAffinity(terms [][]topologyPair) *core.VolumeNodeAffinity
|
|||
|
||||
func TestValidateVolumeNodeAffinityUpdate(t *testing.T) {
|
||||
scenarios := map[string]struct {
|
||||
isExpectedFailure bool
|
||||
oldPV *core.PersistentVolume
|
||||
newPV *core.PersistentVolume
|
||||
mutablePVNodeAffinity bool
|
||||
isExpectedFailure bool
|
||||
oldPV *core.PersistentVolume
|
||||
newPV *core.PersistentVolume
|
||||
}{
|
||||
"nil-nothing-changed": {
|
||||
isExpectedFailure: false,
|
||||
|
|
@ -1508,9 +1509,16 @@ func TestValidateVolumeNodeAffinityUpdate(t *testing.T) {
|
|||
oldPV: testVolumeWithNodeAffinity(simpleVolumeNodeAffinity(v1.LabelInstanceType, "-1")),
|
||||
newPV: testVolumeWithNodeAffinity(simpleVolumeNodeAffinity(v1.LabelInstanceTypeStable, "-1")),
|
||||
},
|
||||
"MutablePVNodeAffinity": {
|
||||
mutablePVNodeAffinity: true,
|
||||
isExpectedFailure: false,
|
||||
oldPV: testVolumeWithNodeAffinity(simpleVolumeNodeAffinity("foo", "bar")),
|
||||
newPV: testVolumeWithNodeAffinity(simpleVolumeNodeAffinity("foo", "baz")),
|
||||
},
|
||||
}
|
||||
|
||||
for name, scenario := range scenarios {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MutablePVNodeAffinity, scenario.mutablePVNodeAffinity)
|
||||
originalNewPV := scenario.newPV.DeepCopy()
|
||||
originalOldPV := scenario.oldPV.DeepCopy()
|
||||
opts := ValidationOptionsForPersistentVolume(scenario.newPV, scenario.oldPV)
|
||||
|
|
|
|||
|
|
@ -596,6 +596,13 @@ const (
|
|||
// update the number of volumes that can be allocated on a node
|
||||
MutableCSINodeAllocatableCount featuregate.Feature = "MutableCSINodeAllocatableCount"
|
||||
|
||||
// owner: huww98
|
||||
// kep: https://kep.k8s.io/5381
|
||||
//
|
||||
// Makes PersistentVolume.Spec.NodeAffinity mutable, allowing CSI drivers to
|
||||
// update the topology info when the data is migrated
|
||||
MutablePVNodeAffinity featuregate.Feature = "MutablePVNodeAffinity"
|
||||
|
||||
// owner: @kannon92
|
||||
// kep: https://kep.k8s.io/5440
|
||||
//
|
||||
|
|
@ -1480,6 +1487,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
|
|||
{Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
MutablePVNodeAffinity: {
|
||||
{Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
MutablePodResourcesForSuspendedJobs: {
|
||||
{Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
|
@ -2244,6 +2255,8 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature
|
|||
|
||||
MutableCSINodeAllocatableCount: {},
|
||||
|
||||
MutablePVNodeAffinity: {},
|
||||
|
||||
MutablePodResourcesForSuspendedJobs: {},
|
||||
|
||||
MutableSchedulingDirectivesForSuspendedJobs: {},
|
||||
|
|
|
|||
2
pkg/generated/openapi/zz_generated.openapi.go
generated
2
pkg/generated/openapi/zz_generated.openapi.go
generated
|
|
@ -28414,7 +28414,7 @@ func schema_k8sio_api_core_v1_PersistentVolumeSpec(ref common.ReferenceCallback)
|
|||
},
|
||||
"nodeAffinity": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "nodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume.",
|
||||
Description: "nodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume. This field is mutable if MutablePVNodeAffinity feature gate is enabled.",
|
||||
Ref: ref(corev1.VolumeNodeAffinity{}.OpenAPIModelName()),
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3604,6 +3604,7 @@ message PersistentVolumeSpec {
|
|||
|
||||
// nodeAffinity defines constraints that limit what nodes this volume can be accessed from.
|
||||
// This field influences the scheduling of pods that use this volume.
|
||||
// This field is mutable if MutablePVNodeAffinity feature gate is enabled.
|
||||
// +optional
|
||||
optional VolumeNodeAffinity nodeAffinity = 9;
|
||||
|
||||
|
|
|
|||
|
|
@ -427,6 +427,7 @@ type PersistentVolumeSpec struct {
|
|||
VolumeMode *PersistentVolumeMode `json:"volumeMode,omitempty" protobuf:"bytes,8,opt,name=volumeMode,casttype=PersistentVolumeMode"`
|
||||
// nodeAffinity defines constraints that limit what nodes this volume can be accessed from.
|
||||
// This field influences the scheduling of pods that use this volume.
|
||||
// This field is mutable if MutablePVNodeAffinity feature gate is enabled.
|
||||
// +optional
|
||||
NodeAffinity *VolumeNodeAffinity `json:"nodeAffinity,omitempty" protobuf:"bytes,9,opt,name=nodeAffinity"`
|
||||
// Name of VolumeAttributesClass to which this persistent volume belongs. Empty value
|
||||
|
|
|
|||
|
|
@ -1585,7 +1585,7 @@ var map_PersistentVolumeSpec = map[string]string{
|
|||
"storageClassName": "storageClassName is the name of StorageClass to which this persistent volume belongs. Empty value means that this volume does not belong to any StorageClass.",
|
||||
"mountOptions": "mountOptions is the list of mount options, e.g. [\"ro\", \"soft\"]. Not validated - mount will simply fail if one is invalid. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#mount-options",
|
||||
"volumeMode": "volumeMode defines if a volume is intended to be used with a formatted filesystem or to remain in raw block state. Value of Filesystem is implied when not included in spec.",
|
||||
"nodeAffinity": "nodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume.",
|
||||
"nodeAffinity": "nodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume. This field is mutable if MutablePVNodeAffinity feature gate is enabled.",
|
||||
"volumeAttributesClassName": "Name of VolumeAttributesClass to which this persistent volume belongs. Empty value is not allowed. When this field is not set, it indicates that this volume does not belong to any VolumeAttributesClass. This field is mutable and can be changed by the CSI driver after a volume has been updated successfully to a new class. For an unbound PersistentVolume, the volumeAttributesClassName will be matched with unbound PersistentVolumeClaims during the binding process.",
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ type PersistentVolumeSpecApplyConfiguration struct {
|
|||
VolumeMode *corev1.PersistentVolumeMode `json:"volumeMode,omitempty"`
|
||||
// nodeAffinity defines constraints that limit what nodes this volume can be accessed from.
|
||||
// This field influences the scheduling of pods that use this volume.
|
||||
// This field is mutable if MutablePVNodeAffinity feature gate is enabled.
|
||||
NodeAffinity *VolumeNodeAffinityApplyConfiguration `json:"nodeAffinity,omitempty"`
|
||||
// Name of VolumeAttributesClass to which this persistent volume belongs. Empty value
|
||||
// is not allowed. When this field is not set, it indicates that this volume does not belong to any
|
||||
|
|
|
|||
|
|
@ -1071,6 +1071,12 @@
|
|||
lockToDefault: false
|
||||
preRelease: Alpha
|
||||
version: "1.35"
|
||||
- name: MutablePVNodeAffinity
|
||||
versionedSpecs:
|
||||
- default: false
|
||||
lockToDefault: false
|
||||
preRelease: Alpha
|
||||
version: "1.35"
|
||||
- name: MutableSchedulingDirectivesForSuspendedJobs
|
||||
versionedSpecs:
|
||||
- default: false
|
||||
|
|
|
|||
Loading…
Reference in a new issue