mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Don't try to create VolumeSpec immediately after underlying PVC is being deleted
Signed-off-by: Ted Yu <yuzhihong@gmail.com>
This commit is contained in:
parent
861c918a44
commit
723761aa88
@ -56,8 +56,8 @@ import (
|
|||||||
type DesiredStateOfWorldPopulator interface {
|
type DesiredStateOfWorldPopulator interface {
|
||||||
Run(sourcesReady config.SourcesReady, stopCh <-chan struct{})
|
Run(sourcesReady config.SourcesReady, stopCh <-chan struct{})
|
||||||
|
|
||||||
// ReprocessPod removes the specified pod from the list of processedPods
|
// ReprocessPod sets value for the specified pod in processedPods
|
||||||
// (if it exists) forcing it to be reprocessed. This is required to enable
|
// to false, forcing it to be reprocessed. This is required to enable
|
||||||
// remounting volumes on pod updates (volumes like Downward API volumes
|
// remounting volumes on pod updates (volumes like Downward API volumes
|
||||||
// depend on this behavior to ensure volume content is updated).
|
// depend on this behavior to ensure volume content is updated).
|
||||||
ReprocessPod(podName volumetypes.UniquePodName)
|
ReprocessPod(podName volumetypes.UniquePodName)
|
||||||
@ -150,7 +150,7 @@ func (dswp *desiredStateOfWorldPopulator) Run(sourcesReady config.SourcesReady,
|
|||||||
|
|
||||||
func (dswp *desiredStateOfWorldPopulator) ReprocessPod(
|
func (dswp *desiredStateOfWorldPopulator) ReprocessPod(
|
||||||
podName volumetypes.UniquePodName) {
|
podName volumetypes.UniquePodName) {
|
||||||
dswp.deleteProcessedPod(podName)
|
dswp.markPodProcessingFailed(podName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dswp *desiredStateOfWorldPopulator) HasAddedPods() bool {
|
func (dswp *desiredStateOfWorldPopulator) HasAddedPods() bool {
|
||||||
@ -362,6 +362,12 @@ func (dswp *desiredStateOfWorldPopulator) processPodVolumes(
|
|||||||
dswp.actualStateOfWorld.MarkRemountRequired(uniquePodName)
|
dswp.actualStateOfWorld.MarkRemountRequired(uniquePodName)
|
||||||
// Remove any stored errors for the pod, everything went well in this processPodVolumes
|
// Remove any stored errors for the pod, everything went well in this processPodVolumes
|
||||||
dswp.desiredStateOfWorld.PopPodErrors(uniquePodName)
|
dswp.desiredStateOfWorld.PopPodErrors(uniquePodName)
|
||||||
|
} else if dswp.podHasBeenSeenOnce(uniquePodName) {
|
||||||
|
// For the Pod which has been processed at least once, even though some volumes
|
||||||
|
// may not have been reprocessed successfully this round, we still mark it as processed to avoid
|
||||||
|
// processing it at a very high frequency. The pod will be reprocessed when volume manager calls
|
||||||
|
// ReprocessPod() which is triggered by SyncPod.
|
||||||
|
dswp.markPodProcessed(uniquePodName)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -434,14 +440,32 @@ func volumeRequiresFSResize(pvc *v1.PersistentVolumeClaim, pv *v1.PersistentVolu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// podPreviouslyProcessed returns true if the volumes for this pod have already
|
// podPreviouslyProcessed returns true if the volumes for this pod have already
|
||||||
// been processed by the populator
|
// been processed/reprocessed by the populator. Otherwise, the volumes for this pod need to
|
||||||
|
// be reprocessed.
|
||||||
func (dswp *desiredStateOfWorldPopulator) podPreviouslyProcessed(
|
func (dswp *desiredStateOfWorldPopulator) podPreviouslyProcessed(
|
||||||
podName volumetypes.UniquePodName) bool {
|
podName volumetypes.UniquePodName) bool {
|
||||||
dswp.pods.RLock()
|
dswp.pods.RLock()
|
||||||
defer dswp.pods.RUnlock()
|
defer dswp.pods.RUnlock()
|
||||||
|
|
||||||
_, exists := dswp.pods.processedPods[podName]
|
return dswp.pods.processedPods[podName]
|
||||||
return exists
|
}
|
||||||
|
|
||||||
|
// markPodProcessingFailed marks the specified pod from processedPods as false to indicate that it failed processing
|
||||||
|
func (dswp *desiredStateOfWorldPopulator) markPodProcessingFailed(
|
||||||
|
podName volumetypes.UniquePodName) {
|
||||||
|
dswp.pods.Lock()
|
||||||
|
dswp.pods.processedPods[podName] = false
|
||||||
|
dswp.pods.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// podHasBeenSeenOnce returns true if the pod has been seen by the popoulator
|
||||||
|
// at least once.
|
||||||
|
func (dswp *desiredStateOfWorldPopulator) podHasBeenSeenOnce(
|
||||||
|
podName volumetypes.UniquePodName) bool {
|
||||||
|
dswp.pods.RLock()
|
||||||
|
_, exist := dswp.pods.processedPods[podName]
|
||||||
|
dswp.pods.RUnlock()
|
||||||
|
return exist
|
||||||
}
|
}
|
||||||
|
|
||||||
// markPodProcessed records that the volumes for the specified pod have been
|
// markPodProcessed records that the volumes for the specified pod have been
|
||||||
|
@ -47,6 +47,111 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/volume/util/types"
|
"k8s.io/kubernetes/pkg/volume/util/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func pluginPVOmittingClient(dswp *desiredStateOfWorldPopulator) {
|
||||||
|
fakeClient := &fake.Clientset{}
|
||||||
|
fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {
|
||||||
|
return false, nil, nil
|
||||||
|
})
|
||||||
|
fakeClient.AddReactor("get", "persistentvolumes", func(action core.Action) (bool, runtime.Object, error) {
|
||||||
|
return false, nil, nil
|
||||||
|
})
|
||||||
|
dswp.kubeClient = fakeClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareDswpWithVolume(t *testing.T) (*desiredStateOfWorldPopulator, kubepod.Manager) {
|
||||||
|
// create dswp
|
||||||
|
mode := v1.PersistentVolumeFilesystem
|
||||||
|
pv := &v1.PersistentVolume{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "dswp-test-volume-name",
|
||||||
|
},
|
||||||
|
Spec: v1.PersistentVolumeSpec{
|
||||||
|
ClaimRef: &v1.ObjectReference{Namespace: "ns", Name: "file-bound"},
|
||||||
|
VolumeMode: &mode,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
|
VolumeName: "dswp-test-volume-name",
|
||||||
|
},
|
||||||
|
Status: v1.PersistentVolumeClaimStatus{
|
||||||
|
Phase: v1.ClaimBound,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dswp, fakePodManager, _ := createDswpWithVolume(t, pv, pvc)
|
||||||
|
return dswp, fakePodManager
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFindAndAddNewPods_WithReprocessPodAndVolumeRetrievalError(t *testing.T) {
|
||||||
|
// create dswp
|
||||||
|
dswp, fakePodManager := prepareDswpWithVolume(t)
|
||||||
|
|
||||||
|
// create pod
|
||||||
|
containers := []v1.Container{
|
||||||
|
{
|
||||||
|
VolumeMounts: []v1.VolumeMount{
|
||||||
|
{
|
||||||
|
Name: "dswp-test-volume-name",
|
||||||
|
MountPath: "/mnt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "file-bound", containers)
|
||||||
|
|
||||||
|
fakePodManager.AddPod(pod)
|
||||||
|
|
||||||
|
podName := util.GetUniquePodName(pod)
|
||||||
|
|
||||||
|
dswp.findAndAddNewPods()
|
||||||
|
|
||||||
|
if !dswp.podPreviouslyProcessed(podName) {
|
||||||
|
t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName)
|
||||||
|
}
|
||||||
|
pluginPVOmittingClient(dswp)
|
||||||
|
|
||||||
|
dswp.ReprocessPod(podName)
|
||||||
|
dswp.findAndAddNewPods()
|
||||||
|
|
||||||
|
if !dswp.podPreviouslyProcessed(podName) {
|
||||||
|
t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName)
|
||||||
|
}
|
||||||
|
fakePodManager.DeletePod(pod)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFindAndAddNewPods_WithVolumeRetrievalError(t *testing.T) {
|
||||||
|
// create dswp
|
||||||
|
dswp, fakePodManager := prepareDswpWithVolume(t)
|
||||||
|
|
||||||
|
pluginPVOmittingClient(dswp)
|
||||||
|
|
||||||
|
// create pod
|
||||||
|
containers := []v1.Container{
|
||||||
|
{
|
||||||
|
VolumeMounts: []v1.VolumeMount{
|
||||||
|
{
|
||||||
|
Name: "dswp-test-volume-name",
|
||||||
|
MountPath: "/mnt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "file-bound", containers)
|
||||||
|
|
||||||
|
fakePodManager.AddPod(pod)
|
||||||
|
|
||||||
|
podName := util.GetUniquePodName(pod)
|
||||||
|
|
||||||
|
dswp.findAndAddNewPods()
|
||||||
|
|
||||||
|
if dswp.podPreviouslyProcessed(podName) {
|
||||||
|
t.Fatalf("The volumes for the specified pod: %s should not have been processed by the populator", podName)
|
||||||
|
}
|
||||||
|
if dswp.podHasBeenSeenOnce(podName) {
|
||||||
|
t.Fatalf("The volumes for the specified pod: %s should not have been processed by the populator", podName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFindAndAddNewPods_FindAndRemoveDeletedPods(t *testing.T) {
|
func TestFindAndAddNewPods_FindAndRemoveDeletedPods(t *testing.T) {
|
||||||
// create dswp
|
// create dswp
|
||||||
mode := v1.PersistentVolumeFilesystem
|
mode := v1.PersistentVolumeFilesystem
|
||||||
|
Loading…
Reference in New Issue
Block a user