Deckhouse Kubernetes Platform (DKP) создаёт в кластере набор классов приоритета (PriorityClass) и назначает их своим компонентам. Приложения могут использовать эти классы через параметр priorityClassName. Планировщик (scheduler) учитывает приоритет пода: если ресурсов недостаточно, первыми вытесняются поды с более низким приоритетом.
Например, если подам нужен класс production-low, а ресурсов не хватает, планировщик сначала вытеснит поды с более низким классом приоритета — например, с develop, затем с cluster-low и так далее. Если priorityClassName не указан, под считается наименее приоритетным.
Доступные классы приоритета
В таблице перечислены классы приоритета, которые DKP создаёт в кластере, в порядке убывания приоритета (чем больше значение, тем выше приоритет). Выбирайте класс с учётом окружения и критичности нагрузки.
Не используйте классы приоритета system-node-critical, system-cluster-critical, cluster-medium, cluster-low, так как они зарезервированы для ключевых компонентов кластера.
| Класс приоритета | Описание | Значение |
|---|---|---|
system-node-critical |
Компоненты кластера, которые обязаны присутствовать на узле. Также полностью защищает от вытеснения kubelet’ом. Примеры: node-exporter, csi и другие. |
2000001000 |
system-cluster-critical |
Компоненты кластера, без которых его корректная работа невозможна. Этим классом приоритета обязательно помечаются MutatingWebhooks и Extension API servers. Также полностью защищает от вытеснения kubelet’ом. Примеры: kube-dns, kube-proxy, cni-flannel, cni-cilium и другие. |
2000000000 |
production-high |
Stateful-приложения, отсутствие которых в production-окружении приводит к полной недоступности сервиса или потере данных. Примеры: PostgreSQL, Memcached, Redis, MongoDB и другие. |
9000 |
cluster-medium |
Компоненты кластера, влияющие на мониторинг (алерты, диагностика) и автомасштабирование. Без мониторинга невозможно оценить масштабы происшествия, без автомасштабирования — предоставить приложениям необходимые ресурсы. Примеры: deckhouse, node-local-dns, grafana, upmeter и другие. |
7000 |
production-medium |
Основные stateless-приложения в production-окружении, которые отвечают за работу сервиса для посетителей. | 6000 |
deployment-machinery |
Компоненты кластера, используемые для сборки и развёртывания в кластер. | 5000 |
production-low |
Приложения в production-окружении (cron-задания, административные панели, batch-процессы), без которых можно обойтись некоторое время. Если batch или cron-задачи нельзя прерывать, их следует отнести к production-medium. |
4000 |
staging |
Staging-окружения для приложений. | 3000 |
cluster-low |
Компоненты кластера, без которых эксплуатация возможна, но которые желательны. Примеры: dashboard, cert-manager, prometheus и другие. |
2000 |
develop (по умолчанию) |
Develop-окружения для приложений. Класс по умолчанию, если не указан иной класс. | 1000 |
standby |
Класс не предназначен для приложений. Используется в системных целях для резервирования узлов. | -1 |
Создание дополнительных классов приоритета
Помимо классов, которые DKP создаёт в кластере, можно добавить дополнительный класс приоритета: задать имя и числовой приоритет.
Далее приведён пример создания класса приоритета critical-applications с приоритетом 8000. При использовании этого класса приоритета соответствующие поды будут вытеснены перед подами с классом приоритета production-high (и выше), но после подов с классом приоритета cluster-medium (и ниже).
Создайте файл critical-applications.yaml со следующим содержимым:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: critical-applications
value: 8000
globalDefault: false
description: "Приоритет для критичных приложений"
В манифесте ресурса PriorityClass используются следующие поля:
metadata.name— имя класса. Указывается в подах в параметреpriorityClassName.value— числовой приоритет. Чем выше значение, тем выше приоритет.globalDefault— определяет, будет ли этот класс использоваться по умолчанию для подов без явногоpriorityClassName.description— описание класса.
Будьте осторожны с параметром globalDefault: true. Если установить его для дополнительного класса, все поды в кластере без явного приоритета получат это значение, что может привести к непредсказуемому вытеснению системных компонентов.
Примените манифест в кластере:
d8 k apply -f critical-applications.yaml
Проверьте создание класса приоритета:
d8 k get priorityclass critical-applications
Пример вывода:
NAME VALUE GLOBAL-DEFAULT AGE PREEMPTIONPOLICY
critical-applications 8000 false 7s PreemptLowerPriority
Не создавайте дополнительные классы со значениями выше 1 000 000, чтобы не нарушить работу критически важных системных компонентов.
Механизм вытеснения
Принцип работы
Решение о вытеснении принимается планировщиком исключительно на основе числового значения приоритета. Тип рабочей нагрузки (Deployment, StatefulSet, DaemonSet или обычный под) не имеет значения — планировщик сравнивает только числа: под с большим значением приоритета может вытеснить под с меньшим, чтобы освободить ресурсы на узле.
При равных приоритетах вытеснение не происходит. Если новый под имеет такой же приоритет, как и существующие поды на узле, планировщик не будет вытеснять их — новый под останется в статусе Pending до появления свободных ресурсов.
Практические сценарии и пошаговые демонстрации смотрите в разделе «Использование классов приоритета».
Защита пода от вытеснения
Единственный способ защитить под от вытеснения — назначить ему достаточно высокий приоритет. Однако даже при высоком приоритете под будет вытеснен, если в кластере появится под с ещё более высоким приоритетом.
Для снижения рисков при вытеснении используется комбинация трёх механизмов. Эти механизмы универсальны и применимы к любым критичным приложениям:
- Указание класса с высоким приоритетом в параметре
priorityClassName— делает под менее вероятным кандидатом на вытеснение. - Использование PodDisruptionBudget (PDB) — ограничивает количество одновременно удаляемых реплик. При вытеснении PDB работает как рекомендация (в отличие от плановых работ, таких как drain узла, когда PDB является жёстким ограничением).
terminationGracePeriodSeconds— даёт приложению время на сброс буферов и закрытие соединений перед принудительным удалением. Это последняя линия обороны, гарантирующая целостность данных даже при нарушении PDB.
Без параметра terminationGracePeriodSeconds у пода мгновенное завершение работы может привести к потере данных, которые не были сохранены на диск, и, например, к повреждению базы данных.
Отличия классов приоритета от других механизмов управления ресурсами
Классы приоритета (PriorityClass) часто путают с другими механизмами управления ресурсами. Важно понимать их различия:
| Механизм | Назначение | Отличие от классов приоритета |
|---|---|---|
| ResourceQuota | Лимиты на потребление ресурсов в неймспейсе | Ограничивает суммарное потребление, не влияет на вытеснение подов. |
| LimitRange | Лимиты и запросы для подов по умолчанию | Задаёт минимальные и максимальные значения, не влияет на вытеснение. |
В отличие от этих механизмов, классы приоритета влияют именно на порядок вытеснения подов при нехватке ресурсов, а не на ограничение потребления.
Эксплуатация и диагностика
Если под с нужным классом приоритета не запускается, хотя в кластере в целом есть свободные ресурсы, проблема часто связана не с самим классом, а с размещением нагрузки.
Возможные причины на уровне кластера:
- Свободные CPU и память есть, но они распределены по разным узлам, и ни один узел не может принять под целиком даже после вытеснения.
- Нет подходящих кандидатов на вытеснение — на целевом узле все поды имеют равный или более высокий приоритет. Как проверить — в пользовательском разделе «Практическая проверка отсутствия подходящих подов».
- Нет подходящих узлов для размещения пода — например, из-за использования taints и tolerations.
- Достигнут лимит подов на узле (
Capacity.pods) — вытеснение не помогает: число подов на узле не уменьшается, вытесненный под заменяется новым.
Что можно сделать:
- Добавьте worker-узлы или перераспределите нагрузку, если свободные ресурсы распределены по разным узлам.
- Освободите место на перегруженном узле: удалите или перенесите менее критичные поды.
- Пересмотрите плотность DaemonSet и системных подов на узле.
- При необходимости назначьте приложению более высокий класс приоритета из раздела «Доступные классы приоритета».