• Ensures one Pod copy on every (matching) node
  • New node joins → Pod scheduled automatically; node removed → Pods garbage-collected
  • No spec.replicas: replica count = number of eligible nodes
  • Typical use: node-level agents (Fluentd, Prometheus node-exporter, CNI plugins, kube-proxy)

DaemonSet YAML

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: log-agent
spec:
  selector:
    matchLabels:
      app: log-agent
  template:
    metadata:
      labels:
        app: log-agent
    spec:
      tolerations:
      - operator: Exists              # tolerate all taints: runs on every node
      containers:
      - name: fluentd
        image: fluent/fluentd:v1.14
        volumeMounts:
        - name: varlog
          mountPath: /var/log
          readOnly: true
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

Scheduling controls

FieldPurpose
spec.nodeSelectorRun only on nodes with matching labels
spec.affinity.nodeAffinityComplex node selection
spec.tolerationsAllow scheduling onto tainted nodes

Update strategy

spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1

kubectl

kubectl create daemonset log-agent --image=fluent/fluentd:v1.14
kubectl get ds                          # DESIRED = CURRENT = READY = node count
kubectl rollout status daemonset/log-agent

Exam gotchas

  • DaemonSet Pods often need tolerations to run on control-plane or tainted nodes
  • kubectl get ds: DESIRED should equal number of matching nodes
  • DaemonSet selector immutable
  • "Run on every node" → DaemonSet, not Deployment with high replica count