✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Daemon Workload Scope

Kubernetes Daemon Workload Scope defines where and how daemon sets run across nodes, ensuring critical services operate reliably across the cluster.

Kubernetes Daemon Workload Scope is the definition of what a DaemonSet is responsible for within a cluster: ensuring that exactly one copy of a specific Pod runs on every node (or on every node matching a selected subset) that satisfies its scheduling constraints, for as long as that node remains part of the cluster. Scope, in this context, refers both to which nodes a DaemonSet's Pods actually land on and to the class of workloads that are appropriately modeled as daemons in the first place — node-level infrastructure and agents rather than application-level services.

Unlike a Deployment, whose replica count is a number chosen by an operator to satisfy an expected load, a DaemonSet's replica count is derived entirely from cluster topology: it is always "one per eligible node," growing and shrinking automatically as nodes join or leave the cluster, without the DaemonSet's own spec ever specifying a count directly.


What Falls Within Daemon Scope

Node-Level Infrastructure Agents

The canonical daemon workload is infrastructure software that must be present on every node to do its job: log collection agents (Fluent Bit, Vector) that need to read every node's container logs, node monitoring agents (node-exporter) that need to read every node's local metrics, and network plugin components (CNI agents) that configure networking rules on every node they run on.

Storage and Security Daemons

Storage plugin components (CSI node plugins) that mount volumes on the specific node they run on, and security or compliance agents (runtime security scanners, admission-adjacent node agents) that need visibility into every node's running containers, are both squarely within daemon scope, since their function is inherently tied to being present everywhere workloads might run.

Cluster-Wide Utility Services with Per-Node Locality

Some utility workloads are daemons not because they must literally run on every node for infrastructure reasons, but because their value depends on per-node locality — a local caching proxy that intercepts traffic before it leaves the node, reducing cross-node network calls for co-located Pods, is a daemon workload by virtue of needing to be physically close to its consumers rather than by any strict infrastructure requirement.


What Falls Outside Daemon Scope

Application Services with Independent Scaling Needs

A stateless web application or API service does not belong in daemon scope even if it happens to need multiple replicas, because its correct replica count is a function of expected load, not a function of node count — a cluster with 50 nodes does not need 50 replicas of a lightly used internal API, which is exactly what a DaemonSet would enforce.

Workloads Requiring Ordered Identity

Workloads needing stable network identity, ordered startup, or persistent per-instance storage (a clustered database, a message broker with per-instance state) fall to StatefulSets rather than DaemonSets, since DaemonSet Pods are not ordered, do not have stable identities beyond their node association, and are not designed for peer-aware startup sequencing.

Finite, Run-to-Completion Work

Batch processing, migrations, and other finite tasks fall to Jobs and CronJobs rather than DaemonSets — a DaemonSet's Pods are expected to run indefinitely on their node, restarting if they exit, which is the opposite of the finite completion semantics a batch task needs.


Scoping Which Nodes a DaemonSet Targets

All Nodes by Default

Without a nodeSelector or affinity rule, a DaemonSet's Pods are scheduled onto every node in the cluster that does not have a taint the Pod lacks a matching toleration for, including, by default, control-plane nodes tainted against ordinary workloads — DaemonSets commonly add explicit tolerations for control-plane taints specifically because infrastructure agents (like a log collector) often need to run there too.

Narrowing Scope with nodeSelector or Affinity

nodeSelector and nodeAffinity restrict a DaemonSet to a labeled subset of nodes — for example, running a GPU monitoring agent only on nodes labeled gpu: "true", rather than attempting to schedule (and fail to schedule usefully) onto every node in the cluster.

spec:
  template:
    spec:
      nodeSelector:
        gpu: "true"
      tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: "NoSchedule"

Boundary Cases

A Daemon That Should Not Run Everywhere

An operator might mistakenly deploy a workload as a DaemonSet expecting it to run on "most" nodes, without realizing that a DaemonSet without node selectors targets every eligible node unconditionally; scoping mistakes here typically manifest as unexpected resource consumption cluster-wide, discovered only once total memory or CPU usage per node is reviewed.

A Per-Node Requirement Handled by a Deployment with Anti-Affinity Instead

Attempting to approximate "roughly one Pod per node" using a Deployment with pod anti-affinity rules is a common anti-pattern that DaemonSet scope is specifically meant to replace — anti-affinity-based approximations do not automatically track node membership changes as reliably or simply as a DaemonSet, which is purpose-built for exactly this guarantee.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: codartium-log-agent
spec:
  selector:
    matchLabels:
      app: codartium-log-agent
  template:
    metadata:
      labels:
        app: codartium-log-agent
    spec:
      containers:
        - name: log-agent
          image: codartium/log-agent:latest