Merge pull request #105211 from xiaopingrubyist/fix-pv-controller-claim-cache-issue

fix:claim cached in pvcontroller is not the newest may cause unexpected issue
This commit is contained in:
Kubernetes Prow Robot 2021-10-14 05:47:18 -07:00 committed by GitHub
commit baaa53db64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 3 deletions

View File

@ -563,6 +563,21 @@ func TestSync(t *testing.T) {
noevents, noerrors, testSyncVolume,
},
{
// syncVolume with volume bound to claim which exists in etcd but not updated to local cache.
"4-12 - volume bound to newest claim but not updated to local cache",
newVolumeArray("volume4-12", "10Gi", "uid4-12-new", "claim4-12", v1.VolumeAvailable, v1.PersistentVolumeReclaimDelete, classEmpty),
newVolumeArray("volume4-12", "10Gi", "uid4-12-new", "claim4-12", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
func() []*v1.PersistentVolumeClaim {
newClaim := newClaimArray("claim4-12", "uid4-12", "10Gi", "volume4-12", v1.ClaimBound, nil, "")
// update uid to new-uid and not sync to cache.
newClaim = append(newClaim, newClaimArray("claim4-12", "uid4-12-new", "10Gi", "volume4-12", v1.ClaimBound, nil, annSkipLocalStore)...)
return newClaim
}(),
newClaimArray("claim4-12", "uid4-12-new", "10Gi", "volume4-12", v1.ClaimBound, nil, annSkipLocalStore),
noevents, noerrors, testSyncVolume,
},
// PVC with class
{
// syncVolume binds a claim to requested class even if there is a

View File

@ -622,9 +622,22 @@ func (ctrl *PersistentVolumeController) syncVolume(volume *v1.PersistentVolume)
if claim != nil && claim.UID != volume.Spec.ClaimRef.UID {
// The claim that the PV was pointing to was deleted, and another
// with the same name created.
klog.V(4).Infof("synchronizing PersistentVolume[%s]: claim %s has different UID, the old one must have been deleted", volume.Name, claimrefToClaimKey(volume.Spec.ClaimRef))
// Treat the volume as bound to a missing claim.
claim = nil
// in some cases, the cached claim is not the newest, and the volume.Spec.ClaimRef.UID is newer than cached.
// so we should double check by calling apiserver and get the newest claim, then compare them.
klog.V(4).Infof("Maybe cached claim: %s is not the newest one, we should fetch it from apiserver", claimrefToClaimKey(volume.Spec.ClaimRef))
claim, err = ctrl.kubeClient.CoreV1().PersistentVolumeClaims(volume.Spec.ClaimRef.Namespace).Get(context.TODO(), volume.Spec.ClaimRef.Name, metav1.GetOptions{})
if err != nil && !apierrors.IsNotFound(err) {
return err
} else if claim != nil {
// Treat the volume as bound to a missing claim.
if claim.UID != volume.Spec.ClaimRef.UID {
klog.V(4).Infof("synchronizing PersistentVolume[%s]: claim %s has a newer UID than pv.ClaimRef, the old one must have been deleted", volume.Name, claimrefToClaimKey(volume.Spec.ClaimRef))
claim = nil
} else {
klog.V(4).Infof("synchronizing PersistentVolume[%s]: claim %s has a same UID with pv.ClaimRef", volume.Name, claimrefToClaimKey(volume.Spec.ClaimRef))
}
}
}
if claim == nil {