DaemonSets Explained
A DaemonSet ensures that exactly one copy of a pod runs on every node matching its selector — and automatically adds a pod when a new node joins the cluster, or removes it when a node leaves. This makes DaemonSets the standard tool for node-level infrastructure: log shippers like Fluent Bit, metrics agents like node-exporter, and networking components like kube-proxy or a CNI plugin such as Calico.
Cricket analogy: Like every stadium in an IPL season having exactly one designated pitch curator assigned automatically — when a new venue is added to the schedule, a curator is assigned there too, without anyone manually requesting it per venue.
Node Selection and Scheduling
By default a DaemonSet targets every node, but nodeSelector or node affinity rules can restrict it to a subset, such as only GPU nodes for an NVIDIA device plugin. Since Kubernetes 1.17, DaemonSet pods are scheduled by the standard kube-scheduler using NodeAffinity, so to run on tainted nodes — including control-plane nodes — you must add matching tolerations, just as any other pod would.
Cricket analogy: Like a support staff role, say a spin-bowling coach, being assigned only to venues with turning pitches rather than every ground on tour — a selector restricts the assignment to a specific subset of matching venues.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluent-bit
namespace: logging
spec:
selector:
matchLabels:
app: fluent-bit
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
app: fluent-bit
spec:
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
containers:
- name: fluent-bit
image: fluent/fluent-bit:3.1
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
hostPath:
path: /var/logUpdate Strategies: RollingUpdate vs OnDelete
DaemonSets support two update strategies. RollingUpdate, the default, replaces pods node by node according to maxUnavailable, similar in spirit to a Deployment rollout. OnDelete instead does nothing automatically — a new pod is only created on a node after you manually delete the existing pod there — giving you full manual control over the pace and order of a rollout for infrastructure that needs careful, coordinated updates.
Cricket analogy: Like automatic ground-staff rotation between matches (RollingUpdate) versus a groundskeeper who only gets replaced when the board specifically fires them (OnDelete) — one is automatic and paced, the other requires a deliberate manual trigger per venue.
Use OnDelete for critical, order-sensitive infrastructure like a CNI plugin or a storage driver, where you want to update one node, verify cluster networking or storage still works, and only then proceed to the next node manually or via a scripted, monitored loop.
DaemonSets and Node Maintenance
DaemonSet pods are intentionally ignored by the standard eviction API used during kubectl drain — draining a node does not remove DaemonSet pods by default, since they are tied to the node itself and will simply be recreated there. You typically need --ignore-daemonsets when draining, and PodDisruptionBudgets generally don't apply meaningfully to DaemonSet pods the way they do to Deployment or StatefulSet replicas.
Cricket analogy: Like the stadium's fixed floodlight towers staying in place even when the ground is closed for pitch relaying — they're part of the venue's permanent infrastructure, not part of the roster that gets 'benched' during maintenance.
Forgetting --ignore-daemonsets during kubectl drain will cause the drain command to fail or hang, since DaemonSet-managed pods cannot be evicted through the normal API in the way ReplicaSet-managed pods can.
- A DaemonSet guarantees exactly one pod per matching node and auto-adjusts as nodes join or leave.
- nodeSelector and node affinity restrict a DaemonSet to a subset of nodes, e.g. GPU nodes.
- Tolerations are required to schedule DaemonSet pods onto tainted nodes, including control-plane nodes.
- RollingUpdate replaces DaemonSet pods node-by-node automatically, bounded by maxUnavailable.
- OnDelete gives full manual control, only replacing a pod after you delete it on that node.
- DaemonSet pods are excluded from normal eviction; use --ignore-daemonsets during kubectl drain.
- Typical use cases: log shippers, metrics agents, CNI plugins, and storage/network daemons.
Practice what you learned
1. What is the defining guarantee of a DaemonSet?
2. What must you add to a DaemonSet's pod spec to run it on tainted control-plane nodes?
3. What is the key difference between RollingUpdate and OnDelete strategies for a DaemonSet?
4. Why does kubectl drain typically require the --ignore-daemonsets flag?
5. Which of these is a typical DaemonSet use case?
Was this page helpful?
You May Also Like
Deployments In Depth
How Kubernetes Deployments manage ReplicaSets to deliver declarative rolling updates, rollbacks, and self-healing for stateless workloads.
Pod Disruption Budgets
How PodDisruptionBudgets protect application availability during voluntary disruptions like node drains, upgrades, and cluster autoscaler actions.
StatefulSets Explained
How StatefulSets provide stable network identities, ordered lifecycle guarantees, and persistent per-pod storage for stateful applications.