Что такое 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