Skip to content

Commit 1335f20

Browse files
committed
kubelet: Fix the volume manager did't check the device mount state in the actual state of the world before marking the volume as detached. It may cause a pod to be stuck in the Terminating state due to the above issue when it was deleted.
1 parent 98e5a70 commit 1335f20

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

pkg/kubelet/volumemanager/cache/actual_state_of_world.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ type ActualStateOfWorld interface {
176176
// or have a mount/unmount operation pending.
177177
GetAttachedVolumes() []AttachedVolume
178178

179+
// GetAttachedVolume returns the volume that is known to be attached to the node
180+
// with the given volume name. If the volume is not found, the second return value
181+
// is false.
182+
GetAttachedVolume(volumeName v1.UniqueVolumeName) (AttachedVolume, bool)
183+
179184
// Add the specified volume to ASW as uncertainly attached.
180185
AddAttachUncertainReconstructedVolume(volumeName v1.UniqueVolumeName, volumeSpec *volume.Spec, nodeName types.NodeName, devicePath string) error
181186

@@ -1160,6 +1165,18 @@ func (asw *actualStateOfWorld) GetAttachedVolumes() []AttachedVolume {
11601165
return allAttachedVolumes
11611166
}
11621167

1168+
func (asw *actualStateOfWorld) GetAttachedVolume(volumeName v1.UniqueVolumeName) (AttachedVolume, bool) {
1169+
asw.RLock()
1170+
defer asw.RUnlock()
1171+
1172+
volumeObj, ok := asw.attachedVolumes[volumeName]
1173+
if !ok {
1174+
return AttachedVolume{}, false
1175+
}
1176+
1177+
return asw.newAttachedVolume(&volumeObj), true
1178+
}
1179+
11631180
func (asw *actualStateOfWorld) GetUnmountedVolumes() []AttachedVolume {
11641181
asw.RLock()
11651182
defer asw.RUnlock()

pkg/kubelet/volumemanager/reconciler/reconciler_common.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,11 @@ func (rc *reconciler) unmountDetachDevices() {
275275
// Check IsOperationPending to avoid marking a volume as detached if it's in the process of mounting.
276276
if !rc.desiredStateOfWorld.VolumeExists(attachedVolume.VolumeName, attachedVolume.SELinuxMountContext) &&
277277
!rc.operationExecutor.IsOperationPending(attachedVolume.VolumeName, nestedpendingoperations.EmptyUniquePodName, nestedpendingoperations.EmptyNodeName) {
278+
279+
// Re-read the actual state of the world, maybe the volume got mounted in the meantime.
280+
// This is safe, because there is no pending operation (checked above) and no new operation
281+
// could start in the meantime. The only goroutine that adds new operations is this reconciler.
282+
attachedVolume, _ = rc.actualStateOfWorld.GetAttachedVolume(attachedVolume.VolumeName)
278283
if attachedVolume.DeviceMayBeMounted() {
279284
// Volume is globally mounted to device, unmount it
280285
klog.V(5).InfoS(attachedVolume.GenerateMsgDetailed("Starting operationExecutor.UnmountDevice", ""))

0 commit comments

Comments
 (0)