Skip to content

Commit

Permalink
Fix DownwardAPI refresh race.
Browse files Browse the repository at this point in the history
WaitForAttachAndMount should mark only pod in DesiredStateOfWorldPopulator (DSWP)
and DSWP should mark the volume to be remounted only when the new pod has been
processed.

Otherwise DSWP and reconciler race who gets the new pod first. If it's reconciler,
then DownwardAPI and Projected volumes of the pod are not refreshed with new
content and they are updated after the next periodic sync (60-90 seconds).

RelatedTo: kubernetes#59873
  • Loading branch information
KubeStacker authored and Shu Yingya committed Jan 25, 2019
1 parent f815c6c commit d9ed0fb
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ func NewDesiredStateOfWorldPopulator(
podManager pod.Manager,
podStatusProvider status.PodStatusProvider,
desiredStateOfWorld cache.DesiredStateOfWorld,
actualStateOfWorld cache.ActualStateOfWorld,
kubeContainerRuntime kubecontainer.Runtime,
keepTerminatedPodVolumes bool) DesiredStateOfWorldPopulator {
return &desiredStateOfWorldPopulator{
Expand All @@ -93,6 +94,7 @@ func NewDesiredStateOfWorldPopulator(
podManager: podManager,
podStatusProvider: podStatusProvider,
desiredStateOfWorld: desiredStateOfWorld,
actualStateOfWorld: actualStateOfWorld,
pods: processedPods{
processedPods: make(map[volumetypes.UniquePodName]bool)},
kubeContainerRuntime: kubeContainerRuntime,
Expand All @@ -109,6 +111,7 @@ type desiredStateOfWorldPopulator struct {
podManager pod.Manager
podStatusProvider status.PodStatusProvider
desiredStateOfWorld cache.DesiredStateOfWorld
actualStateOfWorld cache.ActualStateOfWorld
pods processedPods
kubeContainerRuntime kubecontainer.Runtime
timeOfLastGetPodStatus time.Time
Expand Down Expand Up @@ -302,6 +305,9 @@ func (dswp *desiredStateOfWorldPopulator) processPodVolumes(pod *v1.Pod) {
// some of the volume additions may have failed, should not mark this pod as fully processed
if allVolumesAdded {
dswp.markPodProcessed(uniquePodName)
// New pod has been synced. Re-mount all volumes that need it
// (e.g. DownwardAPI)
dswp.actualStateOfWorld.MarkRemountRequired(uniquePodName)
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ func createDswpWithVolume(t *testing.T, pv *v1.PersistentVolume, pvc *v1.Persist
podtest.NewFakeMirrorClient(), fakeSecretManager, fakeConfigMapManager)

fakesDSW := cache.NewDesiredStateOfWorld(fakeVolumePluginMgr)
fakeASW := cache.NewActualStateOfWorld("fake", fakeVolumePluginMgr)
fakeRuntime := &containertest.FakeRuntime{}

fakeStatusManager := status.NewManager(fakeClient, fakePodManager, &statustest.FakePodDeletionSafetyProvider{})
Expand All @@ -536,6 +537,7 @@ func createDswpWithVolume(t *testing.T, pv *v1.PersistentVolume, pvc *v1.Persist
podManager: fakePodManager,
podStatusProvider: fakeStatusManager,
desiredStateOfWorld: fakesDSW,
actualStateOfWorld: fakeASW,
pods: processedPods{
processedPods: make(map[types.UniquePodName]bool)},
kubeContainerRuntime: fakeRuntime,
Expand Down
2 changes: 1 addition & 1 deletion pkg/kubelet/volumemanager/volume_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ func NewVolumeManager(
podManager,
podStatusProvider,
vm.desiredStateOfWorld,
vm.actualStateOfWorld,
kubeContainerRuntime,
keepTerminatedPodVolumes)
vm.reconciler = reconciler.NewReconciler(
Expand Down Expand Up @@ -347,7 +348,6 @@ func (vm *volumeManager) WaitForAttachAndMount(pod *v1.Pod) error {
// Remount plugins for which this is true. (Atomically updating volumes,
// like Downward API, depend on this to update the contents of the volume).
vm.desiredStateOfWorldPopulator.ReprocessPod(uniquePodName)
vm.actualStateOfWorld.MarkRemountRequired(uniquePodName)

err := wait.Poll(
podAttachAndMountRetryInterval,
Expand Down

0 comments on commit d9ed0fb

Please sign in to comment.