From 7186d3ba8ba3df736f6a41e3ab773db3a3698f3f Mon Sep 17 00:00:00 2001 From: Krzysztof Jastrzebski Date: Mon, 28 Jan 2019 14:07:20 +0100 Subject: [PATCH] Delete pods assigned to not existing nodes. --- pkg/controller/daemon/daemon_controller.go | 21 +++++++++++++++++++ .../daemon/daemon_controller_test.go | 19 +++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/pkg/controller/daemon/daemon_controller.go b/pkg/controller/daemon/daemon_controller.go index bf7019f117c..4a2dd7a1e95 100644 --- a/pkg/controller/daemon/daemon_controller.go +++ b/pkg/controller/daemon/daemon_controller.go @@ -964,6 +964,9 @@ func (dsc *DaemonSetsController) manage(ds *apps.DaemonSet, hash string) error { failedPodsObserved += failedPodsObservedOnNode } + // Remove pods assigned to not existing nodes. + podsToDelete = append(podsToDelete, getPodsWithoutNode(nodeList, nodeToDaemonPods)...) + // Label new pods using the hash label value of the current history when creating them if err = dsc.syncNodes(ds, podsToDelete, nodesNeedingDaemonPods, hash); err != nil { return err @@ -1524,3 +1527,21 @@ func (o podByCreationTimestampAndPhase) Less(i, j int) bool { func failedPodsBackoffKey(ds *apps.DaemonSet, nodeName string) string { return fmt.Sprintf("%s/%d/%s", ds.UID, ds.Status.ObservedGeneration, nodeName) } + +// getPodsWithoutNode returns list of pods assigned to not existing nodes. +func getPodsWithoutNode( + runningNodesList []*v1.Node, nodeToDaemonPods map[string][]*v1.Pod) []string { + var results []string + isNodeRunning := make(map[string]bool) + for _, node := range runningNodesList { + isNodeRunning[node.Name] = true + } + for n, pods := range nodeToDaemonPods { + if !isNodeRunning[n] { + for _, pod := range pods { + results = append(results, pod.Name) + } + } + } + return results +} diff --git a/pkg/controller/daemon/daemon_controller_test.go b/pkg/controller/daemon/daemon_controller_test.go index 59fe7c026b3..a2b43dfd197 100644 --- a/pkg/controller/daemon/daemon_controller_test.go +++ b/pkg/controller/daemon/daemon_controller_test.go @@ -2447,6 +2447,25 @@ func TestDeleteNoDaemonPod(t *testing.T) { } } +func TestDeletePodForNotExistingNode(t *testing.T) { + for _, f := range []bool{true, false} { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)() + for _, strategy := range updateStrategies() { + ds := newDaemonSet("foo") + ds.Spec.UpdateStrategy = *strategy + manager, podControl, _, err := newTestController(ds) + if err != nil { + t.Fatalf("error creating DaemonSets controller: %v", err) + } + manager.dsStore.Add(ds) + addNodes(manager.nodeStore, 0, 1, nil) + addPods(manager.podStore, "node-0", simpleDaemonSetLabel, ds, 1) + addPods(manager.podStore, "node-1", simpleDaemonSetLabel, ds, 1) + syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 1, 0) + } + } +} + func TestGetNodesToDaemonPods(t *testing.T) { for _, f := range []bool{true, false} { defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()