diff --git a/pkg/kubelet/kubelet_volumes.go b/pkg/kubelet/kubelet_volumes.go index 5942da47afa..0ec1e5e9f9c 100644 --- a/pkg/kubelet/kubelet_volumes.go +++ b/pkg/kubelet/kubelet_volumes.go @@ -71,7 +71,7 @@ func (kl *Kubelet) ListBlockVolumesForPod(podUID types.UID) (map[string]volume.B } // podVolumesExist checks with the volume manager and returns true any of the -// pods for the specified volume are mounted. +// pods for the specified volume are mounted or are uncertain. func (kl *Kubelet) podVolumesExist(podUID types.UID) bool { if mountedVolumes := kl.volumeManager.GetPossiblyMountedVolumesForPod( diff --git a/pkg/kubelet/volumemanager/cache/actual_state_of_world.go b/pkg/kubelet/volumemanager/cache/actual_state_of_world.go index 62025e7114a..db0ad30dc83 100644 --- a/pkg/kubelet/volumemanager/cache/actual_state_of_world.go +++ b/pkg/kubelet/volumemanager/cache/actual_state_of_world.go @@ -110,6 +110,14 @@ type ActualStateOfWorld interface { // volumes that do not need to update contents should not fail. PodExistsInVolume(podName volumetypes.UniquePodName, volumeName v1.UniqueVolumeName) (bool, string, error) + // PodRemovedFromVolume returns true if the given pod does not exist in the list of + // mountedPods for the given volume in the cache, indicating that the pod has + // fully unmounted it or it was never mounted the volume. + // If the volume is fully mounted or is in uncertain mount state for the pod, it is + // considered that the pod still exists in volume manager's actual state of the world + // and false is returned. + PodRemovedFromVolume(podName volumetypes.UniquePodName, volumeName v1.UniqueVolumeName) bool + // VolumeExistsWithSpecName returns true if the given volume specified with the // volume spec name (a.k.a., InnerVolumeSpecName) exists in the list of // volumes that should be attached to this node. @@ -686,6 +694,31 @@ func (asw *actualStateOfWorld) PodExistsInVolume( return podExists, volumeObj.devicePath, nil } +func (asw *actualStateOfWorld) PodRemovedFromVolume( + podName volumetypes.UniquePodName, + volumeName v1.UniqueVolumeName) bool { + asw.RLock() + defer asw.RUnlock() + + volumeObj, volumeExists := asw.attachedVolumes[volumeName] + if !volumeExists { + return true + } + + podObj, podExists := volumeObj.mountedPods[podName] + if podExists { + // if volume mount was uncertain we should keep trying to unmount the volume + if podObj.volumeMountStateForPod == operationexecutor.VolumeMountUncertain { + return false + } + if podObj.volumeMountStateForPod == operationexecutor.VolumeMounted { + return false + } + } + + return true +} + func (asw *actualStateOfWorld) VolumeExistsWithSpecName(podName volumetypes.UniquePodName, volumeSpecName string) bool { asw.RLock() defer asw.RUnlock() diff --git a/pkg/kubelet/volumemanager/cache/actual_state_of_world_test.go b/pkg/kubelet/volumemanager/cache/actual_state_of_world_test.go index b019c2040b9..fc15804bdc8 100644 --- a/pkg/kubelet/volumemanager/cache/actual_state_of_world_test.go +++ b/pkg/kubelet/volumemanager/cache/actual_state_of_world_test.go @@ -671,6 +671,10 @@ func TestUncertainVolumeMounts(t *testing.T) { if volExists { t.Fatalf("expected volume %s to not exist in asw", generatedVolumeName1) } + removed := asw.PodRemovedFromVolume(podName1, generatedVolumeName1) + if removed { + t.Fatalf("expected volume %s not to be removed in asw", generatedVolumeName1) + } } func verifyVolumeExistsInGloballyMountedVolumes( diff --git a/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go b/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go index 8300d9e08e9..f9c4f46f312 100644 --- a/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go +++ b/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go @@ -278,12 +278,12 @@ func (dswp *desiredStateOfWorldPopulator) findAndRemoveDeletedPods() { klog.V(4).InfoS("Pod still has one or more containers in the non-exited state and will not be removed from desired state", "pod", klog.KObj(volumeToMount.Pod)) continue } - exists, _, _ := dswp.actualStateOfWorld.PodExistsInVolume(volumeToMount.PodName, volumeToMount.VolumeName) var volumeToMountSpecName string if volumeToMount.VolumeSpec != nil { volumeToMountSpecName = volumeToMount.VolumeSpec.Name() } - if !exists && podExists { + removed := dswp.actualStateOfWorld.PodRemovedFromVolume(volumeToMount.PodName, volumeToMount.VolumeName) + if removed && podExists { klog.V(4).InfoS("Actual state does not yet have volume mount information and pod still exists in pod manager, skip removing volume from desired state", "pod", klog.KObj(volumeToMount.Pod), "podUID", volumeToMount.Pod.UID, "volumeName", volumeToMountSpecName) continue }