# DaemonSet

> DaemonSet определяет Поды, предоставляющие локальные для узла возможности. Они могут быть критически важны для работы кластера, например, в роли вспомогательного сетевого инструмента или как часть дополнения.

---

LLMS index: [llms.txt](/llms.txt)

---

<!-- overview -->

_DaemonSet_ гарантирует, что на всех (или некоторых) узлах запущена копия Пода. При добавлении узлов в кластер Поды автоматически добавляются на них. При удалении узлов из кластера эти Поды удаляются сборщиком мусора. Удаление DaemonSet приведёт к удалению всех созданных им Подов.

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

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

В простом случае для каждого типа демона используется один DaemonSet, охватывающий все узлы.
В более сложных конфигурациях может использоваться несколько DaemonSet для одного типа демона, но с разными флагами и/или разными запросами памяти и CPU для различных типов оборудования.

<!-- body -->

## Написание спецификации DaemonSet

### Создание DaemonSet

DaemonSet можно описать в YAML-файле. Например, файл `daemonset.yaml` ниже описывает DaemonSet, запускающий Docker-образ fluentd-elasticsearch:























<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/controllers/daemonset.yaml" download="controllers/daemonset.yaml"><code>controllers/daemonset.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('controllers-daemonset-yaml')" title="Copy controllers/daemonset.yaml to clipboard"></img></div>
    <div class="includecode" id="controllers-daemonset-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">apps/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">DaemonSet</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">fluentd-elasticsearch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l">kube-system</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">k8s-app</span><span class="p">:</span><span class="w"> </span><span class="l">fluentd-logging</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">selector</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">matchLabels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">fluentd-elasticsearch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">template</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">fluentd-elasticsearch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">tolerations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># these tolerations are to have the daemonset runnable on control plane nodes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># remove them if your control plane nodes should not run pods</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">node-role.kubernetes.io/control-plane</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">operator</span><span class="p">:</span><span class="w"> </span><span class="l">Exists</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">effect</span><span class="p">:</span><span class="w"> </span><span class="l">NoSchedule</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">node-role.kubernetes.io/master</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">operator</span><span class="p">:</span><span class="w"> </span><span class="l">Exists</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">effect</span><span class="p">:</span><span class="w"> </span><span class="l">NoSchedule</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">containers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">fluentd-elasticsearch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">quay.io/fluentd_elasticsearch/fluentd:v5.0.1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">resources</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">limits</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">memory</span><span class="p">:</span><span class="w"> </span><span class="l">200Mi</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">requests</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">cpu</span><span class="p">:</span><span class="w"> </span><span class="l">100m</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">memory</span><span class="p">:</span><span class="w"> </span><span class="l">200Mi</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">volumeMounts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">varlog</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="l">/var/log</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># it may be desirable to set a high priority class to ensure that a DaemonSet Pod</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># preempts running Pods</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># priorityClassName: important</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">terminationGracePeriodSeconds</span><span class="p">:</span><span class="w"> </span><span class="m">30</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">varlog</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostPath</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/var/log</span><span class="w">
</span></span></span></code></pre></div></div>
</div>

Создание DaemonSet на основе YAML-файла:

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

### Обязательные поля

Как и для любой другой конфигурации Kubernetes, DaemonSet требует наличия полей `apiVersion`, `kind` и `metadata`. Общую информацию о работе с конфигурационными файлами см. в разделах
[запуск stateless-приложений](/docs/tasks/run-application/run-stateless-application-deployment/)
и [управление объектами с помощью kubectl](/ru/docs/concepts/overview/working-with-objects/object-management/).

Имя объекта DaemonSet должно быть допустимым
[DNS-именем поддомена](/ru/docs/concepts/overview/working-with-objects/names/#имена-поддоменов-dns).

DaemonSet также требует наличия секции
[`.spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).

### Шаблон Пода

Поле `.spec.template` является одним из обязательных полей в `.spec`.

Поле `.spec.template` представляет собой [шаблон Пода](/ru/docs/concepts/workloads/pods/#pod-templates).
Оно имеет точно такую же схему, как и <a class='glossary-tooltip' title='Самый маленький и простой объект в Kubernetes. Под — это набор запущенных контейнеров в кластере.' data-bs-toggle='tooltip' data-bs-placement='top' href='/ru/docs/concepts/workloads/pods/pod-overview/' target='_blank' aria-label='Под'>Под</a>,
за исключением того, что является вложенным и не имеет полей `apiVersion` и `kind`.

Помимо обязательных полей для Пода, шаблон Пода в DaemonSet должен указывать соответствующие
метки (см. [селектор Подов](#селектор-подов)).

Шаблон Пода в DaemonSet должен иметь [`RestartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy),
равную `Always`, или не указывать её, что по умолчанию означает `Always`.

### Селектор Подов

Поле `.spec.selector` является селектором Подов. Оно работает так же, как `.spec.selector`
у [Job](/docs/concepts/workloads/controllers/job/).

Необходимо указать селектор Подов, который соответствует меткам в
`.spec.template`.
Также, после создания DaemonSet,
его `.spec.selector` не может быть изменён. Изменение селектора Подов может привести к
непреднамеренному осиротению Подов, что может запутать пользователей.

Поле `.spec.selector` представляет собой объект, состоящий из двух полей:

* `matchLabels` — работает так же, как `.spec.selector` у
  [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/).
* `matchExpressions` — позволяет создавать более сложные селекторы, указывая ключ,
  список значений и оператор, связывающий ключ и значения.

Когда указаны оба поля, результат объединяется по логическому И (AND).

Поле `.spec.selector` должно соответствовать `.spec.template.metadata.labels`.
Конфигурация с несовпадающими значениями будет отклонена API.

### Запуск Подов на выбранных узлах

Если указано поле `.spec.template.spec.nodeSelector`, контроллер DaemonSet будет
создавать Поды на узлах, соответствующих этому [селектору узлов](/ru/docs/concepts/scheduling-eviction/assign-pod-node/).
Аналогично, если указано поле `.spec.template.spec.affinity`,
контроллер DaemonSet будет создавать Поды на узлах, соответствующих этим
[правилам совместного существования (node affinity)](/ru/docs/concepts/scheduling-eviction/assign-pod-node/).
Если ни одно из полей не указано, контроллер DaemonSet будет создавать Поды на всех узлах.

## Как планируются Поды демонов

DaemonSet может использоваться для обеспечения того, чтобы все подходящие узлы запускали копию Пода.
Контроллер DaemonSet создаёт Под для каждого подходящего узла и добавляет поле
`spec.affinity.nodeAffinity` в Под для соответствия целевому хосту. После
создания Пода обычно управление берёт на себя планировщик по умолчанию, который
привязывает Под к целевому хосту, устанавливая поле `.spec.nodeName`. Если новый
Под не помещается на узле, планировщик по умолчанию может вытеснить (evict) некоторые из
существующих Подов на основе
[приоритета](/docs/concepts/scheduling-eviction/pod-priority-preemption/#pod-priority)
нового Пода.


<div class="alert alert-info" role="note"><h4 class="alert-heading">Примечание:</h4>Если важно, чтобы Под DaemonSet'а запускался на каждом узле, обычно желательно
установить <code>.spec.template.spec.priorityClassName</code> для DaemonSet в
<a href="/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass">PriorityClass</a>
с более высоким приоритетом, чтобы гарантировать это вытеснение.</div>


Пользователь может указать другой планировщик для Подов DaemonSet'а,
установив поле `.spec.template.spec.schedulerName` у DaemonSet.

Исходная привязка к узлам, указанная в поле
`.spec.template.spec.affinity.nodeAffinity` (если указана), учитывается
контроллером DaemonSet при оценке подходящих узлов,
но заменяется в созданном Поде на привязку к узлу, соответствующую имени
подходящего узла.

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


### Ограничения (taints) и допуски (tolerations)

Контроллер DaemonSet автоматически добавляет набор <a class='glossary-tooltip' title='A core object consisting of three required properties: key, value, and effect. Tolerations enable the scheduling of pods on nodes or node groups that have a matching taint.' data-bs-toggle='tooltip' data-bs-placement='top' href='/ru/docs/concepts/scheduling-eviction/taint-and-toleration/' target='_blank' aria-label='допусков (tolerations)'>допусков (tolerations)</a> к Подам DaemonSet'а:



 





<table><caption style="display: none;">Допуски для Подов DaemonSet</caption>
	<thead>
			<tr>
					<th>Ключ допуска</th>
					<th>Эффект</th>
					<th>Описание</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><a href="/docs/reference/labels-annotations-taints/#node-kubernetes-io-not-ready"><code>node.kubernetes.io/not-ready</code></a></td>
					<td><code>NoExecute</code></td>
					<td>Поды DaemonSet могут планироваться на узлы, которые не готовы или не могут принимать поды. Любые поды DaemonSet, работающие на таких узлах, не будут вытеснены.</td>
			</tr>
			<tr>
					<td><a href="/docs/reference/labels-annotations-taints/#node-kubernetes-io-unreachable"><code>node.kubernetes.io/unreachable</code></a></td>
					<td><code>NoExecute</code></td>
					<td>Поды DaemonSet могут планироваться на узлы, недоступные для контроллера узлов. Любые поды DaemonSet, работающие на таких узлах, не будут вытеснены.</td>
			</tr>
			<tr>
					<td><a href="/docs/reference/labels-annotations-taints/#node-kubernetes-io-disk-pressure"><code>node.kubernetes.io/disk-pressure</code></a></td>
					<td><code>NoSchedule</code></td>
					<td>Поды DaemonSet могут планироваться на узлы с проблемами нехватки дискового пространства.</td>
			</tr>
			<tr>
					<td><a href="/docs/reference/labels-annotations-taints/#node-kubernetes-io-memory-pressure"><code>node.kubernetes.io/memory-pressure</code></a></td>
					<td><code>NoSchedule</code></td>
					<td>Поды DaemonSet могут планироваться на узлы с проблемами нехватки памяти.</td>
			</tr>
			<tr>
					<td><a href="/docs/reference/labels-annotations-taints/#node-kubernetes-io-pid-pressure"><code>node.kubernetes.io/pid-pressure</code></a></td>
					<td><code>NoSchedule</code></td>
					<td>Поды DaemonSet могут планироваться на узлы с проблемами нехватки идентификаторов процессов (PID).</td>
			</tr>
			<tr>
					<td><a href="/docs/reference/labels-annotations-taints/#node-kubernetes-io-unschedulable"><code>node.kubernetes.io/unschedulable</code></a></td>
					<td><code>NoSchedule</code></td>
					<td>Поды DaemonSet могут планироваться на узлы, помеченные как непланируемые.</td>
			</tr>
			<tr>
					<td><a href="/docs/reference/labels-annotations-taints/#node-kubernetes-io-network-unavailable"><code>node.kubernetes.io/network-unavailable</code></a></td>
					<td><code>NoSchedule</code></td>
					<td><strong>Добавляется только для Подов DaemonSet, запрашивающих сеть хоста</strong>, т.е. Подов с <code>spec.hostNetwork: true</code>. Такие Поды DaemonSet могут планироваться на узлы с недоступной сетью.</td>
			</tr>
	</tbody>
</table>


Вы также можете добавить собственные допуски (tolerations) к Подам DaemonSet'а,
определив их в шаблоне Пода DaemonSet'a.

Поскольку контроллер DaemonSet автоматически устанавливает допуск
`node.kubernetes.io/unschedulable:NoSchedule`,
Kubernetes может запускать Поды DaemonSet'а на узлах, помеченных как _непланируемые_.

Если вы используете DaemonSet для предоставления важной функции уровня узла, такой как
[сеть в кластере](/ru/docs/concepts/cluster-administration/networking/),
будет полезным, если Kubernetes разместит Поды DaemonSet'а на узлах до того, как они будут готовы.
Например, без этого специального допуска вы можете оказаться в тупиковой ситуации,
когда узел не помечен как готовый, потому что сетевой плагин там не запущен,
и в то же время сетевой плагин не запущен на этом узле, потому что узел ещё не готов.

## Взаимодействие с Подами демонов

Некоторые возможные паттерны взаимодействия с Подами в DaemonSet'е:

- **Push**: Поды в DaemonSet'е настроены на отправку обновлений в другой сервис, например,
  в базу данных статистики. У них нет клиентов.
- **IP узла и известный порт**: Поды в DaemonSet могут использовать `hostPort`, чтобы быть
  доступными по IP-адресам узлов.
  Клиенты каким-либо образом знают список IP-адресов узлов и знают порт благодаря предварительному соглашению.
  - **DNS**: Создайте [headless-сервис](/docs/concepts/services-networking/service/#headless-services)
  с тем же селектором Подов, а затем обнаруживайте DaemonSet'ы, используя ресурс `endpoints`
  или получая несколько A-записей из DNS.
- **Service**: Создайте сервис с тем же селектором Подов и используйте сервис для доступа к
  демону на случайном узле. Используйте [политику внутреннего трафика сервиса (Service Internal Traffic Policy)](/docs/concepts/services-networking/service-traffic-policy/)
  для ограничения Подами на том же узле.

## Обновление DaemonSet

При изменении меток узлов DaemonSet оперативно добавит Поды на узлы, которые теперь соответствуют условиям, и удалит
Поды с узлов, которые больше не соответствуют.

Вы можете изменять Поды, созданные DaemonSet'ом. Однако Поды не позволяют обновлять все
поля. Кроме того, контроллер DaemonSet будет использовать исходный шаблон при следующем
создании узла (даже с тем же именем).

Вы можете удалить DaemonSet. Если указать `--cascade=orphan` с `kubectl`, то Поды
останутся на узлах. Если впоследствии создать новый DaemonSet с тем же селектором,
новый DaemonSet примет существующие Поды. Если какие-либо Поды требуют замены, DaemonSet заменит
их в соответствии со своей `updateStrategy`.

Вы можете [выполнить плавное обновление (rolling update)](/docs/tasks/manage-daemon/update-daemon-set/) DaemonSet'а.

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

### Init-скрипты

Безусловно, можно запускать процессы-демоны напрямую на узле (например, используя
`init`, `upstartd` или `systemd`). Это вполне допустимо. Однако есть несколько преимуществ
запуска таких процессов через DaemonSet:

- Возможность мониторинга и управления логами демонов так же, как и приложений.
- Один и тот же язык конфигурации и инструменты (например, шаблоны Подов, `kubectl`) для демонов и приложений.
- Запуск демонов в контейнерах с ограничениями ресурсов повышает изоляцию между демонами и
  контейнерами приложений. Однако этого также можно достичь, запуская демоны в контейнере, но не в Поде.

### Обычные Поды (Bare Pods)

Можно создавать Поды напрямую, указывая конкретный узел для запуска. Однако
DaemonSet заменяет Поды, которые были удалены или завершены по любой причине, например, в случае
сбоя узла или из-за последствий таких операций по обслуживанию узла, как обновление ядра. По этой причине следует
использовать DaemonSet вместо создания отдельных Подов.

### Статические Поды

Можно создавать Поды, записывая файл в определённый каталог, отслеживаемый Kubelet. Такие Поды
называются [статическими Подами](/docs/tasks/configure-pod-container/static-pod/).
В отличие от DaemonSet, статическими Подами нельзя управлять с помощью kubectl
или других клиентов Kubernetes API. Статические Поды не зависят от apiserver, что делает их полезными
в сценариях первичной загрузки кластера. Также статические Поды могут быть объявлены устаревшими в будущем.

### Deployment'ы

DaemonSet'ы похожи на [Deployment'ы](/docs/concepts/workloads/controllers/deployment/) тем, что
оба создают Поды, и эти Поды содержат процессы, которые не должны завершаться (например, веб-серверы,
серверы хранения).

Используйте Deployment для stateless-сервисов, таких как фронтенд-приложения, где важнее масштабировать вверх и вниз
количества реплик и развёртывать обновления, чем контролировать то, на каком именно хосте

запускается Под. Используйте DaemonSet, когда важно, чтобы копия Пода всегда работала на
всех или определённых хостах, если DaemonSet предоставляет функциональность уровня узла, позволяющую другим Подам корректно работать на этом конкретном узле.

Например, [сетевые плагины](/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) часто включают компонент, работающий как DaemonSet. Компонент DaemonSet обеспечивает работу кластерной сети на узле, где он запущен.

## Что дальше

* Узнайте больше о [Подах](/ru/docs/concepts/workloads/pods):
  * Узнайте о [статических Подах](/docs/tasks/configure-pod-container/static-pod/), которые полезны для запуска компонентов
    <a class='glossary-tooltip' title='Уровень оркестрации контейнеров, предоставляющий API и интерфейсы для определения, развёртывания и управления жизненным циклом контейнеров.' data-bs-toggle='tooltip' data-bs-placement='top' href='/ru/docs/reference/glossary/?all=true#term-control-plane' target='_blank' aria-label='управляющего слоя (control plane)'>управляющего слоя (control plane)</a> Kubernetes.
* Узнайте, как использовать DaemonSet'ы:
  * [Выполнение плавного обновления (rolling update) DaemonSet](/docs/tasks/manage-daemon/update-daemon-set/).
  * [Выполнение отката DaemonSet](/docs/tasks/manage-daemon/rollback-daemon-set/)
    (например, если развёртывание прошло не так, как ожидалось).
* Узнайте, [как Kubernetes назначает Поды на узлы](/ru/docs/concepts/scheduling-eviction/assign-pod-node/).
* Узнайте о [плагинах устройств](/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/) и
  [дополнениях](/ru/docs/concepts/cluster-administration/addons/), которые часто работают как DaemonSet'ы.
* `DaemonSet` является ресурсом верхнего уровня в Kubernetes REST API.
  Прочитайте определение объекта 







<a href=""></a>,
  чтобы понять API для DaemonSet'ов.
