Module 9 ยท Lesson 9.2
DaemonSets
One pod per node, automatically
Every controller you've met so far manages a count: a Deployment keeps N replicas running somewhere on the cluster, wherever the scheduler puts them. A DaemonSet manages coverage instead: exactly one matching pod on every node that qualifies, full stop โ no replica count to set, no scheduler decision about placement. Add a fourth node to the cluster, and the DaemonSet controller places a pod on it within moments, with zero action from you.
DaemonSet: coverage, not count
You've actually been looking at DaemonSets since Module 1 without naming
them: kube-proxy and kindnet/calico-node in kube-system are
DaemonSets. Run kubectl get daemonsets -n kube-system right now and
you'll see them โ one pod per node, which is exactly why every node has its
own kube-proxy and CNI agent instead of a shared pool of them somewhere.
Why coverage, not count
A DaemonSet is the right tool whenever something needs to exist on every
node rather than somewhere in the cluster โ a log collector reading
each node's local log files, a node-level metrics exporter, a storage or
networking agent. A Deployment with replicas: 3 on a 3-node cluster might
coincidentally land one pod per node today, but nothing guarantees that
stays true after a reschedule โ and it breaks immediately the moment you
add a fourth node. A DaemonSet's guarantee doesn't depend on luck.
Controlling coverage with node selectors and tolerations
By default a DaemonSet targets every node, but you can narrow that with a
nodeSelector (only nodes with matching labels) โ and you may need
tolerations to land on nodes with taints (taints are covered properly in
Module 10, but the short version: a taint on a node repels pods unless the
pod explicitly tolerates it โ the control-plane node in your cluster
carries one by default, which is why ordinary workloads don't land there).
Get a nodeSelector or toleration wrong and a DaemonSet silently covers
fewer nodes than you think โ no error, just quietly incomplete coverage,
the same "no error, just nothing happening" failure shape you saw with
Service selector mismatches in Module 4.
The infrastructure analogy
A DaemonSet is the Kubernetes-native version of a host-level agent you'd push via a configuration management tool to every box in a fleet โ a monitoring agent, a security scanner, a log shipper โ except enforcement is continuous: a node joins, it gets the agent; no cron-style sweep required.
In the lab, you'll deploy one and prove coverage by comparing pod count to node count directly, then diagnose a DaemonSet that's silently missing a node.
๐งช Lab: lab-19-daemonsets
Preview onlyGoal
Deploy a DaemonSet, prove its one-pod-per-node coverage directly against the real node count, then diagnose a DaemonSet that's silently covering zero nodes.
Tasks
- Apply the starting manifests:
kubectl apply -f manifests/ - Check coverage:
kubectl get daemonset node-agent -n lab-19-daemonsetsโ look atDESIRED. Compare it tokubectl get nodes --selector='!node-role.kubernetes.io/control-plane'(your 2 worker nodes โ the control-plane node has a default taint that keeps ordinary pods, including this DaemonSet's, off it). DESIREDis0, not2. There's no error, no event screaming at you โ just quietly wrong coverage. Find out why:kubectl get daemonset node-agent -n lab-19-daemonsets -o yaml | grep -A2 nodeSelector- Fix it in
manifests/daemonset.yaml(see the comment marking the bug), thenkubectl apply -f manifests/daemonset.yamlagain. - Confirm:
kubectl get daemonset node-agent -n lab-19-daemonsetsnow showsDESIRED: 2,CURRENT: 2,READY: 2โ one pod per worker node. kubectl get pods -n lab-19-daemonsets -o wideโ confirm the two pods landed on your two different worker nodes, not both on one.
Check
Run the check once coverage matches your worker node count.
This lab runs against a real local Kubernetes cluster with an automated grader โ clone the repo and run make start to do it for real.
๐ Quiz
1. What does a DaemonSet guarantee that a Deployment with replicas set to the current node count does not?
2. Which of these have you already seen running as DaemonSets since Module 1, without it being named explicitly?
3. A DaemonSet is supposed to run on every node, but `kubectl get pods -o wide` shows it missing from one worker. There's no error anywhere. What's the most likely cause?scenario
4. Why does your cluster's control-plane node not run ordinary application workloads by default?
5. Which workloads are a genuinely good fit for a DaemonSet? (select all that apply)
Progress isn't saved in this preview โ run the course locally to track completion and grade labs for real.