Deployments и DaemonSet

Deployments и DaemonSet

В Kubernetes существует два основных (Deployment и DaemonSet) способа запуска приложений в зависимости от того, как они должны распределяться по кластеру. Разберем их на конкретных примерах.

Deployment

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

Ключевые возможности:

  • Масштабирование: Вы просто указываете количество реплик, и Kubernetes сам распределяет их по свободным нодам.
  • RollingUpdate (Обновление без простоя): Постепенно заменяет старые версии подов на новые.
  • Self-healing: Если под зависнет или нода упадет, Deployment автоматически перезапустит его на другом узле.

Пример манифеста (Rolling Update)

Здесь мы указываем стратегию, которая позволяет временно создать на 25% больше подов при обновлении, чтобы пользователи не заметили переключения версий.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%          # Сколько подов можно создать сверх нормы
      maxUnavailable: 25%    # Сколько подов могут быть недоступны в процессе
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2

DaemonSet

Сервисный контроль каждой ноды

В отличие от Deployment, который распределяет поды по кластеру в зависимости от доступных ресурсов, DaemonSet гарантирует, что копия конкретного пода будет запущена на каждой (или на строго определенных) ноде кластера.

Что такое DaemonSet?

DaemonSet — это специфический контроллер, задача которого — обеспечить присутствие «фонового» сервиса на всех узлах. Если вы добавляете в кластер новую ноду, Kubernetes автоматически разворачивает на ней под из DaemonSet. Если нода удаляется — под удаляется вместе с ней.

Типичные кейсы использования:

  • Сбор логов: запуск агентов вроде Fluent Bit или Logstash для агрегации системных журналов.
  • Мониторинг: запуск экспортеров метрик (Node Exporter, Collectd) для наблюдения за состоянием «железа».
  • Сетевые плагины: компоненты вроде Calico или Cilium, которые должны работать на каждом узле для обеспечения связности.

Пример манифеста DaemonSet

Обратите внимание, что в DaemonSet отсутствует поле replicas, так как количество копий всегда привязано к количеству нод в кластере.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi

Ограничение запуска на конкретных нодах

Если вам не нужно запускать DaemonSet на абсолютно всех узлах (например, только на нодах с SSD или в определенной зоне), вы можете использовать nodeSelector.

spec:
  template:
    spec:
      nodeSelector:
        ssd: "true"  # Под запустится только на нодах с этой меткой
        

Сравнение Deployment и DaemonSet в Kubernetes

В Kubernetes выбор контроллера определяет, как ваши приложения будут распределяться по узлам (нодам) кластера. Ниже приведено прямое сравнение двух самых популярных объектов.

Таблица основных различий

Характеристика Deployment DaemonSet
Количество подов Задается вручную через параметр replicas. Автоматически (по 1 поду на каждую ноду).
Размещение Планировщик (Scheduler) выбирает наименее загруженные ноды. Игнорирует стандартную логику планировщика, чтобы попасть на каждую ноду.
Назначение Бизнес-логика, API, веб-сайты, базы данных. Системные службы, агенты мониторинга и логирования.
Масштабирование Горизонтальное (вы сами меняете число реплик). Вертикальное (зависит только от количества нод в кластере).
Удаление ноды Поды переезжают на другие доступные ноды. Поды просто удаляются вместе с нодой.

Когда использовать Deployment?

Используйте Deployment, когда вам нужно запустить приложение, которое обслуживает пользователей. Вам не важно, на каком именно сервере работает код, главное — чтобы работало нужное количество копий.
Типичные примеры:

  • Веб-интерфейсы (React, Vue, Angular).
  • Бэкенд-сервисы (Node.js, Go, Python).
  • Микросервисы, обрабатывающие заказы или данные.

Когда использовать DaemonSet?

Используйте DaemonSet для инфраструктурных задач, которые должны выполняться на уровне "железа" каждого сервера. Если вы добавите в кластер 10 новых серверов, DaemonSet сам "докинет" туда нужные сервисы.
Типичные примеры:

  • Сбор логов: Fluentd, Fluent Bit, Logstash.
  • Мониторинг: Prometheus Node Exporter, Datadog Agent.
  • Сеть: Прокси-серверы или сетевые плагины (Kube-proxy, Calico).
Ресурсы рабочей нагрузки
Kubernetes предоставляет несколько встроенных API для декларативного управления рабочими нагрузками и их компонентами. В конечном счете, приложения работают в качестве контейнеров внутри подов, однако управление каждым подом по отдельности требует больших усилий. Например, если под выходит из строя, вам, вероятно, надо будет запустить новый под, чтобы заменить его. Kubernetes может сделать это за вас. С помощью Kubernetes API можно создавать объект рабочей нагрузки на более высоком уровне абстракции, чем под, а затем уже слой управления Kubernetes будет автоматически управлять подами, руководствуясь спецификацией этого объекта.