Commit c232a016 authored by Jan Safranek's avatar Jan Safranek

Fix DownwardAPI refresh race.

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).
parent f114f0e4
...@@ -83,6 +83,7 @@ func NewDesiredStateOfWorldPopulator( ...@@ -83,6 +83,7 @@ func NewDesiredStateOfWorldPopulator(
podManager pod.Manager, podManager pod.Manager,
podStatusProvider status.PodStatusProvider, podStatusProvider status.PodStatusProvider,
desiredStateOfWorld cache.DesiredStateOfWorld, desiredStateOfWorld cache.DesiredStateOfWorld,
actualStateOfWorld cache.ActualStateOfWorld,
kubeContainerRuntime kubecontainer.Runtime, kubeContainerRuntime kubecontainer.Runtime,
keepTerminatedPodVolumes bool) DesiredStateOfWorldPopulator { keepTerminatedPodVolumes bool) DesiredStateOfWorldPopulator {
return &desiredStateOfWorldPopulator{ return &desiredStateOfWorldPopulator{
...@@ -92,6 +93,7 @@ func NewDesiredStateOfWorldPopulator( ...@@ -92,6 +93,7 @@ func NewDesiredStateOfWorldPopulator(
podManager: podManager, podManager: podManager,
podStatusProvider: podStatusProvider, podStatusProvider: podStatusProvider,
desiredStateOfWorld: desiredStateOfWorld, desiredStateOfWorld: desiredStateOfWorld,
actualStateOfWorld: actualStateOfWorld,
pods: processedPods{ pods: processedPods{
processedPods: make(map[volumetypes.UniquePodName]bool)}, processedPods: make(map[volumetypes.UniquePodName]bool)},
kubeContainerRuntime: kubeContainerRuntime, kubeContainerRuntime: kubeContainerRuntime,
...@@ -108,6 +110,7 @@ type desiredStateOfWorldPopulator struct { ...@@ -108,6 +110,7 @@ type desiredStateOfWorldPopulator struct {
podManager pod.Manager podManager pod.Manager
podStatusProvider status.PodStatusProvider podStatusProvider status.PodStatusProvider
desiredStateOfWorld cache.DesiredStateOfWorld desiredStateOfWorld cache.DesiredStateOfWorld
actualStateOfWorld cache.ActualStateOfWorld
pods processedPods pods processedPods
kubeContainerRuntime kubecontainer.Runtime kubeContainerRuntime kubecontainer.Runtime
timeOfLastGetPodStatus time.Time timeOfLastGetPodStatus time.Time
...@@ -302,6 +305,9 @@ func (dswp *desiredStateOfWorldPopulator) processPodVolumes(pod *v1.Pod) { ...@@ -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 // some of the volume additions may have failed, should not mark this pod as fully processed
if allVolumesAdded { if allVolumesAdded {
dswp.markPodProcessed(uniquePodName) dswp.markPodProcessed(uniquePodName)
// New pod has been synced. Re-mount all volumes that need it
// (e.g. DownwardAPI)
dswp.actualStateOfWorld.MarkRemountRequired(uniquePodName)
} }
} }
......
...@@ -525,6 +525,7 @@ func createDswpWithVolume(t *testing.T, pv *v1.PersistentVolume, pvc *v1.Persist ...@@ -525,6 +525,7 @@ func createDswpWithVolume(t *testing.T, pv *v1.PersistentVolume, pvc *v1.Persist
podtest.NewFakeMirrorClient(), fakeSecretManager, fakeConfigMapManager) podtest.NewFakeMirrorClient(), fakeSecretManager, fakeConfigMapManager)
fakesDSW := cache.NewDesiredStateOfWorld(fakeVolumePluginMgr) fakesDSW := cache.NewDesiredStateOfWorld(fakeVolumePluginMgr)
fakeASW := cache.NewActualStateOfWorld("fake", fakeVolumePluginMgr)
fakeRuntime := &containertest.FakeRuntime{} fakeRuntime := &containertest.FakeRuntime{}
fakeStatusManager := status.NewManager(fakeClient, fakePodManager, &statustest.FakePodDeletionSafetyProvider{}) fakeStatusManager := status.NewManager(fakeClient, fakePodManager, &statustest.FakePodDeletionSafetyProvider{})
...@@ -536,6 +537,7 @@ func createDswpWithVolume(t *testing.T, pv *v1.PersistentVolume, pvc *v1.Persist ...@@ -536,6 +537,7 @@ func createDswpWithVolume(t *testing.T, pv *v1.PersistentVolume, pvc *v1.Persist
podManager: fakePodManager, podManager: fakePodManager,
podStatusProvider: fakeStatusManager, podStatusProvider: fakeStatusManager,
desiredStateOfWorld: fakesDSW, desiredStateOfWorld: fakesDSW,
actualStateOfWorld: fakeASW,
pods: processedPods{ pods: processedPods{
processedPods: make(map[types.UniquePodName]bool)}, processedPods: make(map[types.UniquePodName]bool)},
kubeContainerRuntime: fakeRuntime, kubeContainerRuntime: fakeRuntime,
......
...@@ -179,6 +179,7 @@ func NewVolumeManager( ...@@ -179,6 +179,7 @@ func NewVolumeManager(
podManager, podManager,
podStatusProvider, podStatusProvider,
vm.desiredStateOfWorld, vm.desiredStateOfWorld,
vm.actualStateOfWorld,
kubeContainerRuntime, kubeContainerRuntime,
keepTerminatedPodVolumes) keepTerminatedPodVolumes)
vm.reconciler = reconciler.NewReconciler( vm.reconciler = reconciler.NewReconciler(
...@@ -345,7 +346,6 @@ func (vm *volumeManager) WaitForAttachAndMount(pod *v1.Pod) error { ...@@ -345,7 +346,6 @@ func (vm *volumeManager) WaitForAttachAndMount(pod *v1.Pod) error {
// Remount plugins for which this is true. (Atomically updating volumes, // Remount plugins for which this is true. (Atomically updating volumes,
// like Downward API, depend on this to update the contents of the volume). // like Downward API, depend on this to update the contents of the volume).
vm.desiredStateOfWorldPopulator.ReprocessPod(uniquePodName) vm.desiredStateOfWorldPopulator.ReprocessPod(uniquePodName)
vm.actualStateOfWorld.MarkRemountRequired(uniquePodName)
err := wait.Poll( err := wait.Poll(
podAttachAndMountRetryInterval, podAttachAndMountRetryInterval,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment