Change:
When writing DaemonSets we decided that they shouldn't be deleted by NodeController in case of Node problems. Now that we're moving to using taints and taint-based evictions (NC will just taint Nodes and the rest will be done by generic taint-eviction mechanism) we need to add infinite toleration for those taints to DaemonSets to keep this behavior. cc
Off the top of my head, I think the best way to implement this is to modify the , to special-case DaemonSet pods and add infinite tolerationSeconds to them. (See definition of field in the API for how to do this.) do you think you can do this? It should be a simple change. cc/ BTW the feature Marek described will be alpha in 1.6, but nobody will be able to use it (without breaking DaemonSet) unless this request is implemented. So the 1.6 milestone tag is appropriate.
Why wouldn't the daemon set controller special case that?
Yeah, I guess that's probably better - have the DaemonSet controller create pods with the toleration.
I can do this, and yes, in the DaemonSet controller.

Discussion:
newPod.Namespace = ds.Namespace newPod.Spec.NodeName = node.Name <ins> // DaemonSet pods shouldn't be deleted by NodeController in case of node problems. // Add infinite toleration for taint notReady:NoExecute here // to survive taint-based eviction enforced by NodeController // when node turns not ready. _, err = v1.AddOrUpdateTolerationInPod(newPod, &v1.Toleration{ Key:      metav1.TaintNodeNotReady, Operator: v1.TolerationOpExists, Effect:   v1.TaintEffectNoExecute, }) if err != nil { return false, false, false, err } // DaemonSet pods shouldn't be deleted by NodeController in case of node problems. // Add infinite toleration for taint unreachable:NoExecute here // to survive taint-based eviction enforced by NodeController // when node turns unreachable. _, err = v1.AddOrUpdateTolerationInPod(newPod, &v1.Toleration{ Key:      metav1.TaintNodeUnreachable, Operator: v1.TolerationOpExists, Effect:   v1.TaintEffectNoExecute, }) if err != nil { return false, false, false, err } </ins> pods := []*v1.Pod{} podList, err := dsc.podLister.List(labels.Everything())

noScheduleTaints      = []v1.Taint{{Key: "dedicated", Value: "user1", Effect: "NoSchedule"}} ) <ins> var ( nodeNotReady = []v1.Taint{{ Key:       metav1.TaintNodeNotReady, Effect:    v1.TaintEffectNoExecute, TimeAdded: metav1.Now(), }} nodeUnreachable = []v1.Taint{{ Key:       metav1.TaintNodeUnreachable, Effect:    v1.TaintEffectNoExecute, TimeAdded: metav1.Now(), }} ) </ins> func getKey(ds *extensions.DaemonSet, t *testing.T) string { if key, err := controller.KeyFunc(ds); err != nil { t.Errorf("Unexpected error getting key for ds %v: %v", ds.Name, err)

syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0) } <ins> // DaemonSet should launch a pod on a not ready node with taint notReady:NoExecute. func TestNotReadyNodeDaemonLaunchesPod(t *testing.T) { manager, podControl, _ := newTestController() node := newNode("tainted", nil) setNodeTaint(node, nodeNotReady) node.Status.Conditions = []v1.NodeCondition{ {Type: v1.NodeReady, Status: v1.ConditionFalse}, } manager.nodeStore.Add(node) ds := newDaemonSet("simple") manager.dsStore.Add(ds) syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0) } // DaemonSet should launch a pod on an unreachable node with taint unreachable:NoExecute. func TestUnreachableNodeDaemonLaunchesPod(t *testing.T) { manager, podControl, _ := newTestController() node := newNode("tainted", nil) setNodeTaint(node, nodeUnreachable) node.Status.Conditions = []v1.NodeCondition{ {Type: v1.NodeReady, Status: v1.ConditionUnknown}, } manager.nodeStore.Add(node) ds := newDaemonSet("simple") manager.dsStore.Add(ds) syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0) } </ins> // DaemonSet should launch a pod on an untainted node when the pod has tolerations. func TestNodeDaemonLaunchesToleratePod(t *testing.T) { manager, podControl, _ := newTestController()