DaemonSet

DaemonSet

DaemonSet визначає Podʼи, які надають локальні для вузлів можливості. Вони можуть бути фундаментальними для роботи вашого кластера, наприклад, допоміжним інструментом для роботи з мережею, або бути частиною надбудови.

DaemonSet гарантує, що всі (або деякі) вузли запускають копію Podʼа. Коли до кластера додаються вузли, на них додаються Podʼи. Коли вузли видаляються з кластера, ці Podʼи прибирає збір сміття. Видалення DaemonSet призведе до очищення створених ним Podʼів.

Типові варіанти використання DaemonSet:

  • запуск демона кластерного сховища на кожному вузлі
  • запуск демона збору логів на кожному вузлі
  • запуск демона моніторингу вузла на кожному вузлі

У простому випадку один DaemonSet, який охоплює всі вузли, може використовуватися для кожного типу демона. Складніше налаштування може використовувати кілька DaemonSets для одного типу демона, але з різними прапорцями та/або різними запитами памʼяті та CPU для різних типів обладнання.

Створення специфікації DaemonSet

Створення DaemonSet

Ви можете описати DaemonSet у файлі YAML. Наприклад, файл daemonset.yaml нижче описує DaemonSet, який запускає Docker-образ fluentd-elasticsearch:

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:
      tolerations:
      # these tolerations are to have the daemonset runnable on control plane nodes
      # remove them if your control plane nodes should not run pods
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v5.0.1
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
      # it may be desirable to set a high priority class to ensure that a DaemonSet Pod
      # preempts running Pods
      # priorityClassName: important
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

Створіть DaemonSet на основі файлу YAML:

kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml

Обовʼязкові поля

Як і з будь-якою іншою конфігурацією Kubernetes, DaemonSet потребує полів apiVersion, kind та metadata. Загальну інформацію щодо роботи з файлами конфігурації див. у розділах запуск stateless-застосунків та управління обʼєктами за допомогою kubectl.

Назва обʼєкта DaemonSet повинна бути дійсним імʼям DNS-піддомену.

DaemonSet також потребує розділу .spec.

Шаблон Podʼа

.spec.template — одне з обовʼязкових полів в .spec.

.spec.template — це шаблон Podʼа. Він має ту саму схему, що і Pod, за винятком того, що він вкладений і не має apiVersion або kind.

Окрім обовʼязкових полів для Podʼа, шаблон Podʼа в DaemonSet повинен вказувати відповідні мітки (див. селектор Podʼа).

Шаблон Podʼа в DaemonSet повинен мати RestartPolicy зі значенням Always або не вказувати її, тоді стандартним значенням буде Always.

Селектор Podʼа

Поле .spec.selector — це селектор Podʼа. Воно працює так само, як і .spec.selector в Job.

Ви повинні вказати селектор Podʼа, який відповідає міткам .spec.template. Крім того, після створення DaemonSet його .spec.selector не можна змінити. Зміна селектора Podʼа може призвести до ненавмисного залишення Podʼів сиротами, і це виявилося незрозумілим для користувачів.

.spec.selector — це обʼєкт, що складається з двох полів:

  • matchLabels — працює так само, як і .spec.selector у ReplicationController.
  • matchExpressions — дозволяє будувати складніші селектори, вказуючи ключ, список значень та оператор, який повʼязує ключ і значення.

Коли вказано обидва, результат обʼєднується логічною операцією AND.

.spec.selector повинен відповідати .spec.template.metadata.labels. Конфігурація, у якій ці два значення не збігаються, буде відхилена API.

Запуск Podʼів на вибраних вузлах

Якщо ви вказуєте .spec.template.spec.nodeSelector, тоді контролер DaemonSet буде створювати Podʼи на вузлах, які відповідають селектору вузла. Так само, якщо ви вказуєте .spec.template.spec.affinity, тоді контролер DaemonSet буде створювати Podʼи на вузлах, які відповідають цій спорідненості вузла. Якщо ви не вказали жодного з них, контролер DaemonSet буде створювати Podʼи на всіх вузлах.

Як плануються Daemon Podʼи

DaemonSet можна використовувати для того, щоб усі придатні вузли запускали копію Podʼа. Контролер DaemonSet створює Pod для кожного придатного вузла та додає поле spec.affinity.nodeAffinity Podʼа для відповідності цільовому хосту. Після створення Podʼа зазвичай у дію вступає стандартний планувальник і привʼязує Pod до цільового хоста, встановлюючи поле .spec.nodeName. Якщо новий Pod не може поміститися на вузлі, стандартний планувальник може витіснити (виселити) деякі наявні Podʼи на основі пріоритету нового Podʼа.

Примітка:

Якщо важливо, щоб Pod DaemonSet запускався на кожному вузлі, часто бажано встановити .spec.template.spec.priorityClassName DaemonSet на PriorityClass з вищим пріоритетом, щоб гарантувати таке виселення.

Користувач може вказати інший планувальник для Podʼів DaemonSet, встановивши поле .spec.template.spec.schedulerName DaemonSet.

Початкова спорідненість вузла, вказана в полі .spec.template.spec.affinity.nodeAffinity (якщо вказано), береться до уваги контролером DaemonSet під час оцінювання придатних вузлів, але замінюється на спорідненість вузла, що відповідає імені придатного вузла, на створеному Podʼі.

nodeAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchFields:
      - key: metadata.name
        operator: In
        values:
        - target-host-name

Taints та tolerations

Контролер DaemonSet автоматично додає набір tolerations до Podʼів DaemonSet:

Tolerations для Podʼів DaemonSet
Ключ tolerationЕфектДеталі
node.kubernetes.io/not-readyNoExecutePodʼи DaemonSet можуть бути заплановані на вузли, які не є справними або готовими приймати Podʼи. Будь-які Podʼи DaemonSet, які працюють на таких вузлах, не будуть виселені.
node.kubernetes.io/unreachableNoExecutePodʼи DaemonSet можуть бути заплановані на вузли, які недоступні з контролера вузла. Будь-які Podʼи DaemonSet, які працюють на таких вузлах, не будуть виселені.
node.kubernetes.io/disk-pressureNoSchedulePodʼи DaemonSet можуть бути заплановані на вузли з тиском на диск.
node.kubernetes.io/memory-pressureNoSchedulePodʼи DaemonSet можуть бути заплановані на вузли з тиском на памʼять.
node.kubernetes.io/pid-pressureNoSchedulePodʼи DaemonSet можуть бути заплановані на вузли з тиском на процеси.
node.kubernetes.io/unschedulableNoSchedulePodʼи DaemonSet можуть бути заплановані на вузли, непридатні для планування.
node.kubernetes.io/network-unavailableNoScheduleДодається лише для Podʼів DaemonSet, які запитують мережу вузла, тобто для Podʼів із spec.hostNetwork: true. Такі Podʼи DaemonSet можуть бути заплановані на вузли із недоступною мережею.

Ви можете додавати власні tolerations до Podʼів DaemonSet, визначивши їх в шаблоні Podʼа DaemonSet.

Оскільки контролер DaemonSet автоматично встановлює toleration node.kubernetes.io/unschedulable:NoSchedule, Kubernetes може запускати Podʼи DaemonSet на вузлах, позначених як unschedulable.

Якщо ви використовуєте DaemonSet для надання важливої функції на рівні вузла, такої як мережа кластера, то корисно, що Kubernetes розміщує Podʼи DaemonSet на вузлах до того, як вони будуть готові. Наприклад, без цієї спеціальної toleration ви можете опинитися в тупиковій ситуації, коли вузол не позначений як готовий, тому що мережевий втулок не працює там, і в той самий час мережевий втулок не працює на цьому вузлі, оскільки вузол ще не готовий.

Взаємодія з Daemon Podʼами

Деякі можливі шаблони для взаємодії з Podʼами у DaemonSet:

  • Push: Podʼи в DaemonSet налаштовані надсилати оновлення до іншого сервісу, такого як база даних статистики. У них немає клієнтів.
  • NodeIP та відомий порт: Podʼи в DaemonSet можуть використовувати hostPort, щоб до них можна було звертатися за IP-адресами вузлів. Клієнти якимось чином знають список IP-адрес вузлів, а порт знають за домовленістю.
  • DNS: Створіть headless сервіс із тим самим селектором Podʼа, а потім виявіть DaemonSets, використовуючи ресурс endpoints або отримайте кілька записів A з DNS.
  • Service: Створіть Service із тим самим селектором Podʼа та використовуйте його для звернення до демона на випадковому вузлі. Використовуйте Політику внутрішнього трафіку Service, щоб обмежитися Podʼами на тому самому вузлі.

Оновлення DaemonSet

Якщо мітки вузлів змінюються, DaemonSet негайно додає Podʼи на вузли, які тепер відповідають умовам, і видаляє Podʼи з вузлів, які більше їм не відповідають.

Ви можете змінювати Podʼи, які створює DaemonSet. Проте Podʼи не дозволяють оновлювати всі поля. Крім того, контролер DaemonSet буде використовувати початковий шаблон під час наступного створення вузла (навіть з тим самим імʼям).

Ви можете видалити DaemonSet. Якщо ви вказали --cascade=orphan з kubectl, тоді Podʼи залишаться на вузлах. Якщо ви потім створите новий DaemonSet з тим самим селектором, новий DaemonSet перейме наявні Podʼи. Якщо потрібно замінити які-небудь Podʼи, DaemonSet їх замінює згідно з його updateStrategy.

Ви можете виконати поетапне оновлення DaemonSet.

Альтернативи DaemonSet

Скрипти ініціалізації

Звичайно, можна запускати процеси демонів, безпосередньо стартуючи їх на вузлі (наприклад, за допомогою init, upstartd або systemd). Це абсолютно прийнятно. Однак є кілька переваг запуску таких процесів через DaemonSet:

  • Можливість моніторингу та управління логами для демонів так само як і для застосунків.
  • Однакова мова конфігурації та інструменти (наприклад, шаблони Podʼа, kubectl) для демонів та застосунків.
  • Запуск демонів у контейнерах з обмеженням ресурсів підвищує ізоляцію між демонами та контейнерами застосунків. Однак цього також можна досягти, запускаючи демонів у контейнері, але не в Podʼі.

Окремі Podʼи

Можна створювати Podʼи безпосередньо, вказуючи певний вузол для запуску. Проте DaemonSet замінює Podʼи, які видаляються або завершуються з будь-якої причини, такої як збій вузла або обслуговування вузла з перериванням роботи, наприклад, оновлення ядра. З цієї причини слід використовувати DaemonSet замість створення окремих Podʼів.

Статичні Podʼи

Можна створювати Podʼи, записавши файл у певну теку, за якою стежить kubelet. Їх називають статичними Podʼами. На відміну від DaemonSet, статичними Podʼами не можна управляти за допомогою kubectl або інших клієнтів API Kubernetes. Статичні Podʼи не залежать від apiserver, що робить їх корисними в разі початкового налаштування кластера. Також статичні Podʼи можуть бути визнані застарілими в майбутньому.

Deployments

DaemonSets схожі на Deployments тим, що обидва створюють Podʼи, і ці Podʼи мають процеси, завершення яких не очікується (наприклад, вебсервери, сервери зберігання).

Використовуйте Deployment для stateless-сервісів, таких як фронтенди, де збільшення та зменшення кількості реплік і розгортання оновлень важливіші за контроль над тим, на якому саме хості працює Pod. Використовуйте DaemonSet, коли важливо, щоб копія Podʼа завжди працювала на всіх або певних хостах, якщо DaemonSet надає функціональність рівня вузла, яка дозволяє іншим Podʼам правильно працювати на цьому конкретному вузлі.

Наприклад, мережеві втулки часто включають компонент, який працює як DaemonSet. Цей компонент DaemonSet гарантує, що вузол, де він працює, має справну мережу кластера.

Що далі

Змінено October 31, 2026 at 3:03 PM PST: [uk] Use «тека» for file system directories (9fcc1e1e59)