✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes DaemonSet Node Eligibility Management

Kubernetes DaemonSet ensures pods run on eligible nodes through node selectors, taints, and resource constraints, managing node eligibility dynamically within clusters.

Kubernetes DaemonSet Node Eligibility Management is the discipline of reasoning about, and correctly maintaining, the full set of criteria that determine whether a given node is a valid target for a DaemonSet's Pods at any given moment. Eligibility is the composite result of several independent evaluations — scheduling constraints (nodeSelector, node affinity), taint tolerance, node readiness and capacity, and node-level scheduling restrictions (cordoning) — and a node's eligibility can change dynamically as any one of these factors changes, without the DaemonSet's own spec being touched at all.

Where placement management concerns how to configure a DaemonSet's targeting rules, eligibility management concerns the ongoing state evaluation of "is this specific node currently a valid target," which is a question whose answer depends jointly on the DaemonSet's spec and the node's own evolving state.


The Eligibility Criteria

Scheduling Constraint Match

A node is eligible only if it satisfies every nodeSelector key-value pair and every required nodeAffinity expression configured on the DaemonSet. This is the most static of the eligibility criteria, since it changes only when either the DaemonSet's spec or the node's labels change.

Taint Toleration

A node carrying a taint the DaemonSet's Pod template does not tolerate is ineligible, regardless of how well it matches on labels. This criterion interacts with cluster lifecycle events specifically: newly provisioned nodes are commonly tainted until a readiness controller confirms they are fully initialized, meaning a node can be temporarily ineligible purely due to its provisioning state, independent of any daemon-specific configuration.

Node Readiness

The kubelet reports node conditions (Ready, MemoryPressure, DiskPressure, PIDPressure) that factor into whether new Pods, including DaemonSet Pods, can be scheduled onto a node. A node reporting Ready: False is not eligible for new Pod scheduling until it recovers, which is a dynamic, health-driven eligibility factor distinct from the DaemonSet's own configuration.

Cordoning

An operator explicitly marking a node unschedulable (kubectl cordon) removes it from eligibility for new Pods entirely, including DaemonSet Pods, while leaving any Pods already running there untouched. This is a deliberate, manual override used during planned maintenance, distinct from the automatic health-based readiness criteria.

kubectl cordon node-worker-07
kubectl get nodes node-worker-07 -o jsonpath='{.spec.unschedulable}'

How Eligibility Changes Propagate

New Node Onboarding

When a new node joins the cluster and eventually satisfies all eligibility criteria (matching labels, tolerable taints, Ready condition), the DaemonSet controller detects the newly eligible node during its next reconciliation pass and creates a Pod there automatically, without any manual intervention.

Node Decommissioning

Conversely, when a node is drained and removed from the cluster, its DaemonSet Pods are cleaned up as part of the node's removal — there is no separate step needed to "un-target" a node from a DaemonSet's perspective, since eligibility is evaluated against currently existing nodes, and a removed node simply no longer exists to evaluate.

Mid-Life Eligibility Changes

A node that was eligible and running a daemon Pod, but later becomes ineligible (a taint added, a label removed, cordoning applied), has its existing DaemonSet Pod removed by the controller once the DaemonSet's own reconciliation recognizes the mismatch, surfaced in .status.numberMisscheduled in the interim before the Pod is actually removed.


Diagnosing Eligibility Problems

Node-by-Node Evaluation

kubectl get node node-worker-07 -o jsonpath='{.metadata.labels}'
kubectl get node node-worker-07 -o jsonpath='{.spec.taints}'
kubectl get node node-worker-07 -o jsonpath='{.status.conditions}'

Systematically checking a specific node's labels, taints, and conditions against a DaemonSet's nodeSelector/affinity and tolerations is the standard diagnostic sequence when a node is unexpectedly missing daemon coverage, isolating which specific eligibility criterion is failing.

Distinguishing "Ineligible" from "Eligible but Failing"

A node that is eligible but whose daemon Pod is crash-looping is a different problem entirely from a node that is simply ineligible and has no Pod scheduled at all — the former requires inspecting the Pod's logs and events, while the latter requires re-examining the node's labels, taints, and conditions against the DaemonSet's scheduling constraints. Conflating the two leads to wasted debugging effort in the wrong direction.

kubectl get pods -l app=codartium-log-agent --field-selector spec.nodeName=node-worker-07

An empty result here (no Pod object at all for that node) points to an eligibility problem; a Pod object present but not Ready points instead to a runtime failure on an otherwise eligible node.


Example

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: codartium-eligibility-example
spec:
  selector:
    matchLabels:
      app: codartium-node-agent
  template:
    metadata:
      labels:
        app: codartium-node-agent
    spec:
      nodeSelector:
        kubernetes.io/os: linux
      tolerations:
        - operator: "Exists"
          effect: "NoSchedule"
      containers:
        - name: agent
          image: codartium/node-agent:latest