Change:
DaemonSet should not respect node's field. It's because cluster operators often want system components to be running and ready before workloads run on a given node. OTOH, DaemonSet does respect NoSchedule taints. This behavior is broken by , because DaemonSet share some predicates code with default scheduler.
/assign
Added this to 1.10 milestone, because it's a regression introduced in 1.10.
can you (or a SIG lead) add status/approved-for-milestone please? I'll add the priority. /priority important-soon
how is this use case satisfied by the daemonset controller creating pods and depending on the scheduler to assign them to nodes? having the scheduler ignore the unschedulable field seems nonsensical
I'd like get this as limitation for alpha feature; when upgrade to beta, I'd like to use taint to replace un-scheduable, so DaemonSet pod can tolerate it on-demand.
Escalating to critical-urgent, since we are now in Code Freeze. Please update daily with status, thanks! /priority critical-urgent /remove-priority important-soon
In short term, scheduler can check of pods and ignore bit of nodes for DS pods. Long term, when TaintNodesByCondition is stable, we should replace bit by taint and have DS controller add toleration for the taint when creating pods.
That doesn't seem proper. Making pods behave differently depending on the type of their creating object is very counterintuitive. That seems more reasonable. I'm less certain about auto- tolerations
- indeed there's some work currently to move from to a taint based behaviour, tracked by

Discussion:
predicateName                                    string podsOnNode                                       []*v1.Pod nodeCondition                                    []v1.NodeCondition <ins> nodeUnschedulable                                bool </ins> ds                                               *apps.DaemonSet wantToRun, shouldSchedule, shouldContinueRunning bool err                                              error

shouldSchedule:        true, shouldContinueRunning: true, }, <ins> { predicateName: "ShouldRunDaemonPodOnUnscheduableNode", ds: &apps.DaemonSet{ Spec: apps.DaemonSetSpec{ Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel}, Template: v1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: simpleDaemonSetLabel, }, Spec: resourcePodSpec("", "50M", "0.5"), }, }, }, nodeUnschedulable:     true, wantToRun:             true, shouldSchedule:        true, shouldContinueRunning: true, }, </ins> } for i, c := range cases {

node := newNode("test-node", simpleDaemonSetLabel) node.Status.Conditions = append(node.Status.Conditions, c.nodeCondition...) node.Status.Allocatable = allocatableResources("100M", "1") <ins> node.Spec.Unschedulable = c.nodeUnschedulable </ins> manager, _, _, err := newTestController() if err != nil { t.Fatalf("error creating DaemonSets controller: %v", err)

NoDiskConflictPred = "NoDiskConflict" // PodToleratesNodeTaintsPred defines the name of predicate PodToleratesNodeTaints. PodToleratesNodeTaintsPred = "PodToleratesNodeTaints" <ins> // CheckNodeUnschedulablePred defines the name of predicate CheckNodeUnschedulablePredicate. CheckNodeUnschedulablePred = "CheckNodeUnschedulable" </ins> // PodToleratesNodeNoExecuteTaintsPred defines the name of predicate PodToleratesNodeNoExecuteTaints. PodToleratesNodeNoExecuteTaintsPred = "PodToleratesNodeNoExecuteTaints" // CheckNodeLabelPresencePred defines the name of predicate CheckNodeLabelPresence.

// The order is based on the restrictiveness & complexity of predicates. // Design doc: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/predicates-ordering.md var ( <del> predicatesOrdering = []string{CheckNodeConditionPred, </del> <ins> predicatesOrdering = []string{CheckNodeConditionPred, CheckNodeUnschedulablePred, </ins> GeneralPred, HostNamePred, PodFitsHostPortsPred, MatchNodeSelectorPred, PodFitsResourcesPred, NoDiskConflictPred, PodToleratesNodeTaintsPred, PodToleratesNodeNoExecuteTaintsPred, CheckNodeLabelPresencePred,

return nil, nil } <del> // PodToleratesNodeTaints checks if a pod tolerations can tolerate the node taints func PodToleratesNodeTaints(pod *v1.Pod, meta algorithm.PredicateMetadata, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) { </del> <ins> // CheckNodeUnschedulablePredicate checks if a pod can be scheduled on a node with Unschedulable spec. func CheckNodeUnschedulablePredicate(pod *v1.Pod, meta algorithm.PredicateMetadata, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) { </ins> if nodeInfo == nil || nodeInfo.Node() == nil { return false, []algorithm.PredicateFailureReason{ErrNodeUnknownCondition}, nil }

return false, []algorithm.PredicateFailureReason{ErrNodeUnschedulable}, nil } <ins> return true, nil, nil } // PodToleratesNodeTaints checks if a pod tolerations can tolerate the node taints func PodToleratesNodeTaints(pod *v1.Pod, meta algorithm.PredicateMetadata, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) { if nodeInfo == nil || nodeInfo.Node() == nil { return false, []algorithm.PredicateFailureReason{ErrNodeUnknownCondition}, nil } </ins> return podToleratesNodeTaints(pod, nodeInfo, func(t *v1.Taint) bool { // PodToleratesNodeTaints is only interested in NoSchedule and NoExecute taints. return t.Effect == v1.TaintEffectNoSchedule || t.Effect == v1.TaintEffectNoExecute

// if you just want remove specific provider, call func RemovePredicateKeyFromAlgoProvider() factory.RemovePredicateKeyFromAlgorithmProviderMap(predicates.CheckNodeConditionPred) <ins> // Fit is determined based on whether a node has Unschedulable spec factory.RegisterMandatoryFitPredicate(predicates.CheckNodeUnschedulablePred, predicates.CheckNodeUnschedulablePredicate) </ins> // Fit is determined based on whether a pod can tolerate all of the node's taints factory.RegisterMandatoryFitPredicate(predicates.PodToleratesNodeTaintsPred, predicates.PodToleratesNodeTaints) <del> // Insert Key "PodToleratesNodeTaints" To All Algorithm Provider </del> <ins> // Insert Key "PodToleratesNodeTaints" and "CheckNodeUnschedulable" To All Algorithm Provider </ins> // The key will insert to all providers which in algorithmProviderMap[] // if you just want insert to specific provider, call func InsertPredicateKeyToAlgoProvider() factory.InsertPredicateKeyToAlgorithmProviderMap(predicates.PodToleratesNodeTaintsPred) <ins> factory.InsertPredicateKeyToAlgorithmProviderMap(predicates.CheckNodeUnschedulablePred) </ins> glog.Warningf("TaintNodesByCondition is enabled, PodToleratesNodeTaints predicate is mandatory") }