A DaemonSet runs one copy of a Pod on every eligible node, adding one when a node joins and removing it when the node leaves. The scheduler still places the Pods, through node affinity the controller adds per node, so taints apply: kind 14,561 's control-plane node carries node-role.kubernetes.io/control-plane:NoSchedule, and only Pods that tolerate it land there. kind's kube-proxy and kindnet DaemonSets (kind) tolerate all:
kubectl apply -f - >/dev/null <<'EOF'
apiVersion: apps/v1
kind: DaemonSet
metadata: { name: node-report }
spec:
selector: { matchLabels: { app: node-report } }
template:
metadata: { labels: { app: node-report } }
spec:
containers:
- { name: c, image: "localhost:33500/booknest-web:1.3", command: [sleep, "3600"] }
EOF
kubectl rollout status daemonset/node-report >/dev/null
kubectl get pods -l app=node-report -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName
T='[{"key": "node-role.kubernetes.io/control-plane", "effect": "NoSchedule"}]'
kubectl patch ds node-report -p "{\"spec\":{\"template\":{\"spec\":{\"tolerations\":$T}}}}"
kubectl rollout status daemonset/node-report >/dev/null
kubectl get pods -l app=node-report -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName
kubectl delete daemonset node-reportNAME NODE node-report-9qv26 l3-booknest-worker daemonset.apps/node-report patched NAME NODE node-report-dp6xs l3-booknest-worker node-report-t2pkv l3-booknest-control-plane daemonset.apps "node-report" deleted from booknest namespace
The toleration extended coverage from the worker to both nodes; nodeSelector narrows it, say to GPU nodes. Updates roll node by node (maxUnavailable 1) or wait for OnDelete. Automatic tolerations for not-ready, disk-pressure and unschedulable keep these Pods on cordoned or struggling nodes.