Skip to content

Commit 428a8e0

Browse files
authored
Merge pull request kubernetes#75458 from jingxu97/March/raceofActualDesiredState
Fix race condition between actual and desired state in kublet volume manager
2 parents f3efd1d + 7cb5df6 commit 428a8e0

File tree

2 files changed

+119
-4
lines changed

2 files changed

+119
-4
lines changed

pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,15 @@ func (dswp *desiredStateOfWorldPopulator) findAndRemoveDeletedPods() {
253253

254254
if runningContainers {
255255
klog.V(4).Infof(
256-
"Pod %q has been removed from pod manager. However, it still has one or more containers in the non-exited state. Therefore, it will not be removed from volume manager.",
256+
"Pod %q still has one or more containers in the non-exited state. Therefore, it will not be removed from desired state.",
257257
format.Pod(volumeToMount.Pod))
258258
continue
259259
}
260-
261-
if !dswp.actualStateOfWorld.VolumeExists(volumeToMount.VolumeName) && podExists {
262-
klog.V(4).Infof(volumeToMount.GenerateMsgDetailed("Actual state has not yet has this information skip removing volume from desired state", ""))
260+
exists, _, _ := dswp.actualStateOfWorld.PodExistsInVolume(volumeToMount.PodName, volumeToMount.VolumeName)
261+
if !exists && podExists {
262+
klog.V(4).Infof(
263+
volumeToMount.GenerateMsgDetailed(fmt.Sprintf("Actual state has not yet has this volume mounted information and pod (%q) still exists in pod manager, skip removing volume from desired state",
264+
format.Pod(volumeToMount.Pod)), ""))
263265
continue
264266
}
265267
klog.V(4).Infof(volumeToMount.GenerateMsgDetailed("Removing volume from desired state", ""))

pkg/kubelet/volumemanager/populator/desired_state_of_world_populator_test.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,119 @@ func TestFindAndAddNewPods_FindAndRemoveDeletedPods(t *testing.T) {
152152

153153
}
154154

155+
func TestFindAndRemoveDeletedPodsWithActualState(t *testing.T) {
156+
// create dswp
157+
mode := v1.PersistentVolumeFilesystem
158+
pv := &v1.PersistentVolume{
159+
ObjectMeta: metav1.ObjectMeta{
160+
Name: "dswp-test-volume-name",
161+
},
162+
Spec: v1.PersistentVolumeSpec{
163+
ClaimRef: &v1.ObjectReference{Namespace: "ns", Name: "file-bound"},
164+
VolumeMode: &mode,
165+
},
166+
}
167+
pvc := &v1.PersistentVolumeClaim{
168+
Spec: v1.PersistentVolumeClaimSpec{
169+
VolumeName: "dswp-test-volume-name",
170+
},
171+
Status: v1.PersistentVolumeClaimStatus{
172+
Phase: v1.ClaimBound,
173+
},
174+
}
175+
dswp, fakePodManager, fakesDSW := createDswpWithVolume(t, pv, pvc)
176+
177+
// create pod
178+
containers := []v1.Container{
179+
{
180+
VolumeMounts: []v1.VolumeMount{
181+
{
182+
Name: "dswp-test-volume-name",
183+
MountPath: "/mnt",
184+
},
185+
},
186+
},
187+
}
188+
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "file-bound", containers)
189+
190+
fakePodManager.AddPod(pod)
191+
192+
podName := util.GetUniquePodName(pod)
193+
194+
generatedVolumeName := "fake-plugin/" + pod.Spec.Volumes[0].Name
195+
196+
dswp.findAndAddNewPods()
197+
198+
if !dswp.pods.processedPods[podName] {
199+
t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName)
200+
}
201+
202+
expectedVolumeName := v1.UniqueVolumeName(generatedVolumeName)
203+
204+
volumeExists := fakesDSW.VolumeExists(expectedVolumeName)
205+
if !volumeExists {
206+
t.Fatalf(
207+
"VolumeExists(%q) failed. Expected: <true> Actual: <%v>",
208+
expectedVolumeName,
209+
volumeExists)
210+
}
211+
212+
if podExistsInVolume := fakesDSW.PodExistsInVolume(
213+
podName, expectedVolumeName); !podExistsInVolume {
214+
t.Fatalf(
215+
"DSW PodExistsInVolume returned incorrect value. Expected: <true> Actual: <%v>",
216+
podExistsInVolume)
217+
}
218+
219+
verifyVolumeExistsInVolumesToMount(
220+
t, v1.UniqueVolumeName(generatedVolumeName), false /* expectReportedInUse */, fakesDSW)
221+
222+
//let the pod be terminated
223+
podGet, exist := fakePodManager.GetPodByName(pod.Namespace, pod.Name)
224+
if !exist {
225+
t.Fatalf("Failed to get pod by pod name: %s and namespace: %s", pod.Name, pod.Namespace)
226+
}
227+
podGet.Status.Phase = v1.PodFailed
228+
229+
dswp.findAndRemoveDeletedPods()
230+
// Although Pod status is terminated, pod still exists in pod manager and actual state does not has this pod and volume information
231+
// desired state populator will fail to delete this pod and volume first
232+
volumeExists = fakesDSW.VolumeExists(expectedVolumeName)
233+
if !volumeExists {
234+
t.Fatalf(
235+
"VolumeExists(%q) failed. Expected: <true> Actual: <%v>",
236+
expectedVolumeName,
237+
volumeExists)
238+
}
239+
240+
if podExistsInVolume := fakesDSW.PodExistsInVolume(
241+
podName, expectedVolumeName); !podExistsInVolume {
242+
t.Fatalf(
243+
"DSW PodExistsInVolume returned incorrect value. Expected: <true> Actual: <%v>",
244+
podExistsInVolume)
245+
}
246+
247+
// reconcile with actual state so that volume is added into the actual state
248+
// desired state populator now can successfully delete the pod and volume
249+
fakeASW := dswp.actualStateOfWorld
250+
reconcileASW(fakeASW, fakesDSW, t)
251+
dswp.findAndRemoveDeletedPods()
252+
volumeExists = fakesDSW.VolumeExists(expectedVolumeName)
253+
if volumeExists {
254+
t.Fatalf(
255+
"VolumeExists(%q) failed. Expected: <false> Actual: <%v>",
256+
expectedVolumeName,
257+
volumeExists)
258+
}
259+
260+
if podExistsInVolume := fakesDSW.PodExistsInVolume(
261+
podName, expectedVolumeName); podExistsInVolume {
262+
t.Fatalf(
263+
"DSW PodExistsInVolume returned incorrect value. Expected: <false> Actual: <%v>",
264+
podExistsInVolume)
265+
}
266+
}
267+
155268
func TestFindAndAddNewPods_FindAndRemoveDeletedPods_Valid_Block_VolumeDevices(t *testing.T) {
156269
// Enable BlockVolume feature gate
157270
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()

0 commit comments

Comments
 (0)