Skip to content

Commit d38be26

Browse files
authored
Merge pull request kubernetes#4529 from sunnylovestiramisu/updateKEP
Update KEP-3751 VolumeAttributesClass Finazlier Management Design
2 parents fef4a92 + 31e452b commit d38be26

File tree

1 file changed

+27
-14
lines changed
  • keps/sig-storage/3751-volume-attributes-class

1 file changed

+27
-14
lines changed

keps/sig-storage/3751-volume-attributes-class/README.md

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -439,31 +439,28 @@ Operation metrics from [csiOperationsLatencyMetric](https://github.com/kubernete
439439

440440
While a VolumeAttributesClass is referenced by any PVC, we will prevent the object from being deleted by adding a finalizer([reference](https://github.com/kubernetes/kubernetes/blob/master/plugin/pkg/admission/storage/storageobjectinuseprotection/admission.go)).
441441

442-
The VACObjectInUseProtection admission controller sets the finalizer on all VolumeAttributesClasses. VACProtectionController removes the finalizer when it's not referenced. This prevents users from deleting a VolumeAttributesClass that's used by a PVC.
442+
The **vac_finalizer_controller** sets/removes the finalizer on all VolumeAttributesClasses. This prevents users from deleting a VolumeAttributesClass that's used by a PVC. The vac_finalizer_controller will maintain a cache of a map of VolumeAttributesClass to the list of PVCs that are using the VolumeAttributesClass.
443443

444444
There are a few conditions that will trigger add/remove pvc finalizers in the VolumeAttributesClass:
445445

446-
447446
1. PVC created with a VolumeAttributesClass
448-
449-
The **VACObjectInUseProtection admission controller**:
450-
* Check if the VolumeAttributesClass exists. If not, the PVC will enter the INPROGRESS state because we do not want to impose ordering on object creation
447+
The **vac_finalizer_controller**:
448+
* If the VolumeAttributesClassName is nil or empty, the VolumeAttributesClass will not be added to the vac_finalizer_controller cache
449+
* Check if the VolumeAttributesClass exists. If not, the VolumeAttributesClass will not be added to the vac_finalizer_controller cache
451450
* Check if this VolumeAttributesClass already has a protection finalizer
452451
* Add the finalizer to the VolumeAttributesClass if there is none
453452
2. PVC created with a VolumeAttributesClass being deleted
454-
The **VACObjectInUseProtection admission controller**:
453+
The **vac_finalizer_controller**:
455454
* Check VolumeAttributesClass is being deleted and PVC creation failed
456455
3. PVC updated to a different VolumeAttributesClass
457-
* The **VACProtectionController** will remove PVC finalizer in previous VolumeAttributesClass if after listing all the PVCs and confirmed that this PVC is the last one that is consuming the previous VolumeAttributesClass
458-
459-
The **VACObjectInUseProtection admission controller**:
456+
* The **vac_finalizer_controller** will remove finalizer in the VolumeAttributesClass only if after listing all the PVCs/PVs and confirm that this PVC/PV is the last one that is consuming the VolumeAttributesClass in the vac_finalizer_controller cache
460457
* Check if the new VolumeAttributesClass already has a protection finalizer
461458
* Add the finalizer to the new VolumeAttributesClass if there is none
462459
4. PVC updated to a different VolumeAttributesClass that is being deleted
463-
The **VACObjectInUseProtection admission controller**:
460+
The **vac_finalizer_controller**:
464461
* Check VolumeAttributesClass is being deleted and PVC update failed
465462
5. PVC has a VolumeAttributesClass and this PVC is deleted
466-
* The **VACProtectionController** will remove finalizer in the VolumeAttributesClass only if after listing all the PVCs and confirm that this PVC is the last one that is consuming the VolumeAttributesClass
463+
* The **vac_finalizer_controller** will remove finalizer in the VolumeAttributesClass only if after listing all the PVCs/PVs and confirm that this PVC/PV is the last one that is consuming the VolumeAttributesClass in the informer(a cache of VolumeAttributesClass) **only**
467464
6. Delete a VolumeAttributesClass while there is **kubernetes.io/vac-protection** finalizer associated with this VolumeAttributesClass
468465
* Deletion will not return an error but it will add a deletionTimestamp and wait for the finalizer being removed, then remove the VolumeAttributesClass
469466
7. Delete a VolumeAttributesClass without any finalizers
@@ -472,12 +469,28 @@ There are a few conditions that will trigger add/remove pvc finalizers in the Vo
472469
For unbound PVs referencing a VAC:
473470

474471
1. Unbound PV created with a VolumeAttributesClass
475-
The **VACObjectInUseProtection admission controller**:
476-
* Check if the VolumeAttributesClass exists. If not, the PV will enter the INPROGRESS state because we do not want to impose ordering on object creation
472+
The **vac_finalizer_controller**:
473+
* If the VolumeAttributesClassName is nil or empty, the VolumeAttributesClass will not be added to the vac_finalizer_controller cache
477474
* Check if this VolumeAttributesClass already has a protection finalizer
478475
* Add the finalizer to the VolumeAttributesClass if there is none
479476
2. PV has a VolumeAttributesClass and this PV is deleted
480-
* The **VACProtectionController** will remove finalizer in the VolumeAttributesClass only if after listing all the PVs and confirm that this PV is the last one that is consuming the VolumeAttributesClass
477+
* The **vac_finalizer_controller** will remove finalizer in the VolumeAttributesClass only if after listing all the PVCs/PVs and confirm that this PVC/PV is the last one that is consuming the VolumeAttributesClass in the informer(a cache of VolumeAttributesClass) **only**
478+
479+
Only the **vac_finalizer_controller** will remove finalizers on VolumeAttributesClass. If the **vac_finalizer_controller** fails at the step of removing finalizer even there is no PVC/PV using the VolumeAttributesClass anymore, the **vac_finalizer_controller** should retry the deletion as a separate go routine.
480+
481+
The vac_finalizer_controller will use only informers and therefore it may remove the finalizer too early. One scenario is:
482+
483+
1. There is a VolumeAttributesClass that is not used by any PVC. This VolumeAttributesClass is synced to all informers (external-provisioner, external-resizer, KCM)
484+
2. At the same time:
485+
* User creates a PVC that uses this VolumeAttributesClass
486+
* Another user deletes the VolumeAttributesClass
487+
3. VolumeAttributesClass deletion event with DeletionTimestamp reaches vac_finalizer_controller. Because the PVC creation event has not yet reached KCM informers, the controller lets the VolumeAttributesClass to be deleted by removing the finalizer. PVC creation event reaches the external-provisioner, before VolumeAttributesClass update. The external-provisioner will try to provision a new volume using the VolumeAttributesClass that will get deleted soon.
488+
* If the external-provisioner gets the VolumeAttributesClass before deletion in the informer, the provisioning will succeed
489+
* Otherwise the external-prosivioner will fail the provisioning
490+
491+
Solving this scenario properly requires to Get/List requests to the API server, which will cause performance issue in larger cluster similar to the existing PVC protection controller - [related issue](https://github.com/kubernetes/kubernetes/issues/109282).
492+
493+
Since finalizer is more of a best effort instead of accuracy to prevent users making mistakes. The cluster admin can still force add/delete finalizers to the VAC when needed.
481494

482495
#### Create VolumeAttributesClass
483496

0 commit comments

Comments
 (0)