Что такое DaemonSet и где он используется?

Что такое DaemonSet

DaemonSet — это объект контроллера в Kubernetes, который гарантирует запуск одной (или заданного количества) копии пода на каждом (или на выбранных) узле кластера. Его задача — обеспечить наличие однотипного фонового агента на всех нужных нодах, чтобы не управлять руками отдельными подами на каждой машине.

Как работает (поведение и жизненный цикл)

  • Когда создаётся DaemonSet, контроллер наблюдает за списком узлов и создаёт под на каждой ноде, которая удовлетворяет правилам (labels, taints/tolerations, nodeSelector, nodeAffinity).

  • При добавлении нового узла DaemonSet автоматически создаст на нём под.

  • При удалении узла соответствующий под тоже удалится.

  • При удалении самого DaemonSet — все связанные поды удаляются (в зависимости от политики удаления).

  • Обновления подов управляются стратегией обновления DaemonSet: есть режимы RollingUpdate (постепенное обновление) и OnDelete (контроллер не меняет поды пока их не удалят вручную).

Чем DaemonSet отличается от Deployment/StatefulSet/ReplicaSet

  • Deployment/ReplicaSet ориентированы на количество реплик (scale) в кластере; реплики могут быть расположены на любых узлах.

  • DaemonSet ориентирован на покрытие нод — гарантирует запуск пода на каждой/выбранной ноде, а не на конкретном количестве экземпляров.

  • StatefulSet нужен для упорядоченных, с устойчивым сетевым/дисковым идентификатором подов; DaemonSet — для однотипных агентских задач без сохранения состояния.

Типичные опции и важные поля конфигурации

  • nodeSelector / nodeAffinity — ограничить набор нод, на которых создаются поды.

  • tolerations — позволить запускать поды на tainted нодах (например, master/control-plane).

  • hostNetwork, hostPID, hostIPC — дать подам доступ к сетевому стеку/пространству имён хоста (часто нужно для сетевых и мониторинговых агентов).

  • hostPath и другие volume-mounts — доступ к файловой системе хоста (логи, /var/lib/kubelet и т.д.).

  • securityContext / privileged — часто требуются для сетевых плагинов или low-level агентов.

  • Strategy (RollingUpdate, OnDelete) и параметры параллельного обновления (например, maxUnavailable для RollingUpdate).

Где и зачем используется (реальные кейсы)

  • Логирование: Fluentd, Filebeat — собирают логи с файловой системы каждого узла.

  • Мониторинг и метрики: node-exporter, collectd — пробираются по метрикам хоста.

  • Сетевые плагины и CNI-агенты: Calico, Flannel, Weave — часто разворачиваются как DaemonSet для установки сетевой логики на каждую ноду.

  • kube-proxy, network-proxies, service mesh sidecars для L4-решений.

  • Сбор и Forward системных метрик, security/IDS-агенты, резервное копирование локальных дисков, снапшот-агенты для узлов.

  • Edge/IoT сценарии: агенты, которые должны работать на каждом граничном устройстве.

Практические советы и подводные камни

  • Убедитесь в корректных readinessProbe/livenessProbe — DaemonSet-под уязвим в плане обновлений, и отсутствие проверок может привести к отправке трафика в некорректные экземпляры.

  • Аккуратно используйте hostNetwork и privileged — повышенные права увеличивают риск.

  • Если нужно запускать agent только на подмножестве нод, правильно используйте nodeSelector/nodeAffinity и tolerations.

  • При массовом обновлении учитывайте влияние на нагрузку: RollingUpdate с контролем maxUnavailable предотвращает одновременный сбой агентских подов на всех нодах.

  • Для доступа к поду снаружи узла чаще применяют hostPort или hostNetwork — обычные ClusterIP-сервисы не предназначены для прямой адресации per-node агента.

Пример упрощённого манифеста DaemonSet

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
hostNetwork: true
tolerations:
\- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
containers:
\- name: node-exporter
image: prom/node-exporter:latest
args: \["--path.procfs=/host/proc", "--path.sysfs=/host/sys"\]
volumeMounts:
\- name: proc
mountPath: /host/proc
readOnly: true
\- name: sys
mountPath: /host/sys
readOnly: true
volumes:
\- name: proc
hostPath:
path: /proc
\- name: sys
hostPath:
path: /sys