DaemonSet — удобный способ гарантировать, что нужный под запустится на каждом узле кластера. В этой статье разберём, когда и как использовать DaemonSet, какие есть подводные камни и какие приёмы помогают управлять развертыванием надёжно и предсказуемо.
Что такое DaemonSet и зачем он нужен
DaemonSet — это объект Kubernetes, который обеспечивает создание копии пода на каждом подходящем узле кластера. В отличие от Deployment, который масштабируется количеством реплик, DaemonSet ориентирован на «по одному на узел» и служит для задач, тесно связанных с инфраструктурой.
Типичные примеры — агент мониторинга, сборщик логов, сетевой плагин и службы безопасности, которые должны присутствовать локально. Такой подход упрощает доступ к node-level ресурсам — сетевым интерфейсам, файловой системе узла и метаданным хоста.
Поведение DaemonSet в кластере
Когда вы создаёте DaemonSet, контроллер наблюдает за списком нод и создаёт под на каждой ноде, соответствующей селекторам и допускающей запуск. Новые узлы автоматически получают под, а при удалении ноды соответствующие поды удаляются вместе с ней.
Важно понимать, что Kubernetes не гарантирует синхронного запуска на всех узлах одновременно. Кроме того, DaemonSet наследует политики обновления и ограничения пода: если узел помечен как unschedulable, новый под на нём не появится до изменения статуса.
Типичные сценарии использования
DaemonSet хорошо подходит для сервисов, которые работают локально и требуют доступа к ресурсам узла. Ниже перечислены самые распространённые случаи.
- Сбор логов и метрик: Fluentd, Filebeat, node-exporter.
- Сетевые компоненты: CNI-плагины, прокси с hostNetwork.
- Инструменты безопасности: агенты IDS/IPS, сканеры целостности.
- Утилиты обслуживания: резервное копирование узлов, прокси для доступа к локальным устройствам.
Я сам несколько раз разворачивал Fluentd через DaemonSet в продакшене: однажды пришлось учитывать, что у некоторых узлов ограничено disk I/O. Приходилось ставить request/limit и отдельные nodeSelector, чтобы отправлять более «тяжёлые» агенты только на узлы с нужными характеристиками.
Пример простого DaemonSet
Ниже — упрощённый пример манифеста, который создаёт под с минимальными правами для сбора логов. Код служит иллюстрацией структуры и основных полей.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: my-log-agent
spec:
selector:
matchLabels:
name: my-log-agent
template:
metadata:
labels:
name: my-log-agent
spec:
serviceAccountName: log-agent-sa
containers:
- name: agent
image: myregistry/log-agent:1.0
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
hostPath:
path: /var/log
type: Directory
Важные моменты: hostPath позволяет агенту читать логи с узла, serviceAccount даёт внешние права, а селектор matchLabels связывает DaemonSet с подами. В реальной ситуации добавьте securityContext и ресурсы для контроля безопасности и потребления.
Стратегии обновления и управление релизами
DaemonSet поддерживает поле updateStrategy, которое задаёт поведение при обновлении образа. Возможны режимы RollingUpdate и OnDelete. В RollingUpdate можно ограничить скорость обновления через maxUnavailable, чтобы не перегрузить инструментарий или сеть.
При использовании RollingUpdate контролируйте совместимость версии агента: если новая версия требует изменения hostPath или права, учтите откат. Я рекомендую сначала тестировать на отдельной группе узлов через nodeSelector, а затем переключать весь DaemonSet.
Как управлять распределением по узлам
По умолчанию поды создаются на всех nодах, но это поведение можно корректировать с помощью nodeSelector, nodeAffinity и tolerations. Они позволяют исключать узлы с особыми ролями или запускать агенты только там, где есть нужные ресурсы.
Применение taints и tolerations помогает предотвратить запуск системных подов на нодах с критическими задачами или выделенными ролями. Часто удобно пометить узлы с high-IO и направлять тяжёлые агрегаторы туда, оставив lightweight-агенты на остальных.
Частые ошибки и способы их решения
При работе с DaemonSet можно столкнуться с несколькими повторяющимися проблемами: контейнеры не стартуют из-за прав доступа, конфликты портов на хосте при hostPort, и проблемы с SELinux или AppArmor при использовании hostPath.
Ниже — краткая таблица с распространёнными проблемами и мерами по их устранению.
| Проблема | Причина | Решение |
|---|---|---|
| Поды не запускаются на некоторых нодах | taint/taint mismatch или нода unschedulable | Добавить tolerations или снять taint; проверить статусы нод |
| Конфликт портов | нескольким подам нужен тот же hostPort | перенести на hostNetwork или назначить разные порты; использовать DaemonSet только там, где порты свободны |
| Проблемы с доступом к файловой системе | SELinux/AppArmor, неправильный hostPath type | проверить контекст безопасности, использовать securityContext и правильные типы hostPath |
Безопасность и ограничения прав
Поды DaemonSet часто требуют повышенных прав для доступа к хосту, и это создаёт риск. Не торопитесь давать привилегии: сначала попробуйте минимальный набор прав и сервисный аккаунт с конкретными разрешениями.
Используйте securityContext для ограничения возможностей контейнера, например запрещайте привилегированные режимы, если в них нет объективной необходимости. Там, где нужен доступ к ядру или NET_ADMIN, документируйте причины и минимизируйте объем прав.
Наблюдение и отладка
Для контроля статуса DaemonSet полезны команды kubectl get daemonset и kubectl describe daemonset. Они показывают, сколько подов должно быть и сколько фактически готово. Для проверки конкретного узла используйте kubectl get pods -o wide и фильтр по ноде.
Логи подов остаются основным источником информации о проблемах запуска. Если агент не видит локальные ресурсы, сначала проверьте монтирование volume и затем права доступа на хосте. В нескольких случаях мне помогло сравнение окружения успешного и неуспешного узла через ssh и просмотр /var/log/syslog.
Практическая проверка перед вводом в эксплуатацию
Перед масштабированием на весь кластер выполните серию тестов: разверните DaemonSet на тестовой группе нод, проверьте обновление через RollingUpdate, имитируйте отказ узла и оцените восстановление. Это уменьшит вероятность сюрпризов в продакшене.
Важно также отслеживать потребление ресурсов и сетевой трафик. Агент, работающий на каждом узле, может в сумме создать значительную нагрузку. Наглядное правило — измерить baseline и учесть его при планировании ресурсов кластера.
Внедрение и масштабирование: практический план
Реальная последовательность внедрения может выглядеть так: подготовка образа с минимальными правами, тестирование на выделенных нодах, настройка updateStrategy и мониторинга, запуск на всех узлах с последующей ревизией метрик. Такой подход снижает риск ошибок и позволяет быстро откатиться при необходимости.
Когда всё отлажено, автоматизируйте процесс через CI/CD: сборка образов, проверка манифестов и применение в несколько этапов. Это гарантирует предсказуемость и помогает избежать ручных действий, которые обычно приводят к ошибкам в конфигурации.

