---
title: Descheduler для Kubernetes
slug: kubernetes-descheduler
canonical: https://shady2k.ru/posts/kubernetes-descheduler/
date: 2025-01-15
kind: article
author: human
lang: ru
summary: Как Descheduler сам выравнивает поды по нодам, когда после отключения
  света кластер поднимается вразнобой.
tags:
  - homelab
  - kubernetes
---

Как вы уже знаете, в своей домашней лаборатории я использую кластер Kubernetes, развернутый на Talos Linux. Периодически у меня отключают электроэнергию, ИБП не спасают при длительном отключении. Я настроил правила, которые завершают работу всех нод Proxmox при отключении более 6 минут. После восстановления узлы кластера запускаются, но запускаются в разное время, что приводит к неравномерному распределению нагрузки: некоторые узлы перегружены, в то время как другие простаивают.

Scheduling в Kubernetes — это процесс назначения ожидающих подов к узлам, выполняемый компонентом под названием kube-scheduler. Решения планировщика о том, можно ли и где разместить под, определяются его настраиваемой политикой, состоящей из набора правил, называемых предикатами и приоритетами. Эти решения зависят от состояния кластера Kubernetes в момент появления нового пода для планирования.

Поскольку кластеры Kubernetes очень динамичны и их состояние меняется со временем, может возникнуть необходимость переместить уже работающие поды на другие узлы по различным причинам:

- Некоторые узлы простаивают или перегружены
- Первоначальное решение о размещении пода больше не актуально, так как на узлы были добавлены или удалены метки или "taints", и требования affinity пода к узлу больше не выполняются
- Некоторые узлы вышли из строя, и их поды были перемещены на другие узлы
- В кластер добавлены новые узлы

В результате в кластере могут оказаться поды, размещенные не там, где хотелось. Такую балансировку Kubernetes сам делать не умеет и мне приходилось вручную балансировать нагрузку. Как вы понимаете — это не наш метод, я хочу, чтобы Kubernetes все делал сам.

Для решения этой проблемы я установил Descheduler — компонент Kubernetes, предназначенный для перераспределения подов между узлами с целью выравнивания нагрузки и повышения эффективности использования ресурсов. Descheduler анализирует текущую загрузку узлов и перемещает поды с перегруженных узлов на менее загруженные, обеспечивая более равномерное распределение нагрузки в кластере. Descheduler, основываясь на своей политике, находит такие поды, которые можно переместить, и вытесняет их (evict). Descheduler сам не планирует замену вытесненных подов, а полагается на стандартный планировщик для этого.

## Установка Descheduler с помощью Helm

Для установки Descheduler я использовал Helm-чарт, доступный в официальном репозитории.

```bash
helm repo add descheduler https://kubernetes-sigs.github.io/descheduler/
helm upgrade descheduler descheduler/descheduler \
  --install \
  --kubeconfig ./kubeconfig \
  --namespace kube-system \
  --version 0.31.0
```

По умолчанию Descheduler устанавливается в виде CronJob, который запускается каждые две минуты для анализа и эвакуации подов. Перед установкой можно настроить параметры, такие как расписание запуска и политики вытеснения подов, в файле `values.yaml`, но я оставил значения по умолчанию.

## Настройка политик Descheduler

Descheduler использует файл политики (`DeschedulerPolicy`), в котором определяются стратегии для эвакуации подов. В моем случае я оставил стратегии по умолчанию. В Descheduler по умолчанию включены следующие политики, каждая из которых выполняет определённые функции для оптимизации работы кластера Kubernetes:

1.  **Удаление дублирующихся подов (RemoveDuplicates):** эта политика выявляет и удаляет поды, которые были случайно созданы в нескольких экземплярах, что помогает освободить ресурсы и предотвратить избыточное использование.
2.  **Удаление подов с чрезмерным количеством перезапусков (RemovePodsHavingTooManyRestarts):** эта политика нацелена на поды, которые перезапускались более 100 раз, включая перезапуски инициализационных контейнеров. Такие поды могут указывать на проблемы в приложении, и их удаление способствует стабильности кластера.
3.  **Удаление подов, нарушающих привязку к узлам (RemovePodsViolatingNodeAffinity):** эта политика удаляет поды, которые больше не соответствуют требованиям привязки к узлам, например, если узлы были помечены или изменены, и поды больше не удовлетворяют этим условиям.
4.  **Удаление подов, нарушающих ограничения (taints) узлов (RemovePodsViolatingNodeTaints):** эта политика нацелена на поды, размещённые на узлах с ограничениями (taints), которые несовместимы с толерантностями подов, что может привести к неправильному функционированию приложений.
5.  **Удаление подов, нарушающих правила раздельного существования (affinity) между подами (RemovePodsViolatingInterPodAntiAffinity):** эта политика удаляет поды, которые нарушают правила раздельного существования между подами, обеспечивая, чтобы поды, которые не должны размещаться вместе, были разделены.
6.  **Удаление подов, нарушающих ограничения распределения по топологии (RemovePodsViolatingTopologySpreadConstraint):** эта политика удаляет поды, которые не соответствуют ограничениям распределения по топологии, помогая равномерно распределить поды по различным зонам отказа или другим топологическим доменам.
7.  **Низкая загрузка узлов (LowNodeUtilization):** эта политика определяет узлы с использованием ресурсов ниже 20% по CPU, памяти и количеству подов и перемещает поды на более загруженные узлы, чтобы освободить недогруженные узлы для возможного масштабирования вниз.

## Мониторинг и обновление Descheduler

После установки рекомендуется последить за логами CronJob Descheduler для оценки его работы. У меня все прошло хорошо, проблем не возникло.

## Итоги

Я очень доволен! Descheduler спас меня от ручной работы, теперь мой кластер сам себя чинит и балансирует и мне не нужно проверять все ли в порядке. А больше ничего и не требуется.

## Источники

[GitHub - kubernetes-sigs/descheduler: Descheduler for Kubernetes](https://github.com/kubernetes-sigs/descheduler)

[descheduler 0.32.1 · helm/descheduler](https://artifacthub.io/packages/helm/descheduler/descheduler)

[Вытеснение, инициированное через API](https://kubernetes.io/ru/docs/concepts/scheduling-eviction/api-eviction/)

---
