Dynamic Resource Scheduler (DRS) — Динамический планировщик ресурсов

Описание архитектуры DRS

KeyStack DRS (Dynamic Resource Scheduler, динамический планировщик ресурсов) — сервис, который осуществляет перераспределение нагрузки гипервизоров (вычислительных узлов) внутри облака с целью повышения эффективности использования ресурсов.

DRS состоит из API-сервиса drs, интерфейсов GUI и CLI для него, а также хранилища метрик Prometheus. Сервис drs запускается в кластере Control, отслеживает нагрузку на гипервизорах (кластер Compute) и при необходимости мигрирует виртуальные машины (ВМ) с сильно загруженного вычислительного узла на более свободные. Для работы DRS регион KeyStack должен включать не менее двух гипервизоров.

DRS взаимодействует с сервисами Prometheus и Nova API, для миграции ВМ использует механизм live-миграции libvirt.

Основные операции конфигурирования и управления сервисом DRS можно выполнять двумя способами:

  • через интерфейс командной строки DRS CLI;

  • в меню DRS Портала администрирования KeyStack (Admin UI).

Основные функции DRS

  • Автоматическое перемещение виртуальных машин с перегруженных гипервизоров на менее нагруженные, что обеспечивает более равномерное использование ресурсов.

  • Равномерное распределение CPU, ОЗУ, сетевой нагрузки между гипервизорами путём миграции виртуальных машин.

  • Создание рекомендаций для миграций виртуальных машин в процессе выполнения оптимизации, которая запускается в соответствии с заданием (job) по расписанию.

  • Возможность исключить отдельные виртуальные машины или проекты, в том числе по ряду параметров.

  • При балансировке нагрузки учитывается логика фильтров Nova, а также распределение по зонам доступности (availability zones) и группам серверов (server group).

  • Возможность одновременно выполнять несколько заданий с разными периодами запуска, разными конфигурациями и автоматическим запуском миграций.

  • Поддержка отправки уведомлений о состоянии миграций в Prometheus и Zabbix.

  • Возможность использовать авторизацию Keystone.

  • Работа в режиме High Availability.

Ключевые термины DRS

  • Конфигурация (config) — набор параметров для балансировки. Основным параметром является алгоритм. В зависимости от алгоритма определяется набор остальных параметров.

  • Задание (job) — использует определенную конфигурацию и периодически запускает оптимизации для балансировки нагрузки (в рамках указанной зоны доступности или на всем регионе).

  • Оптимизация (optimization) — один цикл работы задания.

  • Рекомендация (recommendation) — параметры для миграции ВМ между гипервизорами. Рекомендации генерируются в процессе выполнения оптимизации. Рекомендация содержит идентификатор виртуальной машины, данные об исходном и целевом гипервизорах, в том числе об их текущей и предполагаемой нагрузке. В зависимости от настроек задания, рекомендации могут применяться вручную или автоматически.

  • Миграция (migration) — живая миграция виртуальной машины, которая была запущена для применения определенной рекомендации.

Работа планировщика

Планировщик контролирует добавление, удаление, изменение заданий в расписании и их запуск. Одновременное выполнение оптимизаций не допускается.

API

API-интерфейс сервиса DRS поддерживает:

  • Получение информации об оптимизациях, рекомендациях и миграциях.

  • Создание, просмотр, редактирование, удаление конфигураций (config) и заданий (job) по запуску выбранного алгоритма.

  • Применение рекомендаций в ручном режиме (если в задании выключено автоматическое применение рекомендаций).

Алгоритмы DRS

Основные алгоритмы:

  • help_overloaded_hypervisors — помогает разгрузить перегруженные гипервизоры путём переноса с него виртуальных машин на менее нагруженные гипервизоры.

  • equal_hypervisors_load — равномерно распределяет нагрузку между гипервизорами путём распределения виртуальных машин на гипервизорах.

  • balance_network — распределяет нагрузку между гипервизорами путём сбалансированного распределения их сетевой нагрузки.

Порядок работы:

  • Конфигурация задает параметры для оптимизации.

  • DRS определяет набор гипервизоров для переноса с них виртуальных машин в случае превышения определенного порога нагрузки (hard limit). Для алгоритма help_overloaded_hypervisors этот порог указывается пользователем в конфигурации. Для алгоритма equal_hypervisors_load порог вычисляется как сумма среднего значения текущей нагрузки всех гипервизоров и разрешённого превышения средней нагрузки (allowed_load_above_average). Если нагрузка гипервизора не меньше порога (например, 80% от всех ресурсов гипервизора), DRS пытается планировать миграции виртуальных машин с такого гипервизора.

  • При выборе целевого гипервизора для виртуальной машины учитываются предполагаемая нагрузка на целевом гипервизоре после миграции и свободные ресурсы гипервизора. Динамическая балансировка виртуальных машин в рамках определённой группы гипервизоров учитывает загрузку CPU гипервизора, памяти гипервизора и сетевых интерфейсов.

  • Если расчетная нагрузка целевого гипервизора ниже установленного порога — создается рекомендация. Если эта нагрузка выше порога, но ниже разрешенного лимита (target_hypervisor_soft_limit) — рекомендация также создается. В ином случае продолжается поиск целевого гипервизора.

  • DRS поддерживает ограничение по зонам доступности и группам серверов. При наличии группы c отрицательным сходством (anti-affinity group) DRS не предлагает миграции, из-за которой ВМ из одной такой группы оказались бы на одном гипервизоре. Если же несколько ВМ принадлежат к одной группе (affinity group), эти ВМ остаются на одном гипервизоре. Кроме того, в группы серверов можно добавлять и удалять ВМ непосредственно при работе гипервизоров.

  • Если расчетная нагрузка изначального гипервизора становится ниже порога после генерации очередной рекомендации — оптимизация для данного гипервизора прекращается.

  • Результат выполнения оптимизации — список рекомендаций по миграции виртуальных машин. Если ни один гипервизор не соответствует критериям, заданным в конфигурации, рекомендации не будут созданы.

Механизм вычисления нагрузки гипервизоров (hard/soft limit)

Для вычисления нагрузки используются метрики Prometheus, а именно среднее значение нагрузки за последние N минут (где N — это значение METRIC_RESOLUTION в конфигурации) по CPU, RAM, сети для каждого гипервизора. Данные из Prometheus умножаются на заданный коэффициент, который указан в конфигурации (параметры METRIC_WEIGHT_CPU, METRIC_WEIGHT_MEM, network_weight). Полученные значения складываются.

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

Настройка и управление DRS

Основные операции при работе с DRS:

Подробнее о каждой операции далее.

Подготовка файла конфигурации DRS

Для начала работы с DRS необходимо определить основные параметры DRS в файле конфигурации drs.ini. Для этого создайте файл drs.ini в каталоге config репозитория региона.

Пример файла конфигурации (замените все <VALUE> на подходящие значения):

[DEFAULT]

# Limit DRS to specific availability zone. It means that source and
# destination hypervisors for migrations are located in this specific
# availability zone (string value)
limit_drs_to_az = <None>

# Limit to exact CPU spec (boolean value)
limit_to_exact_cpu_spec = false

# Migration timeout in seconds (integer value)
migration_timeout = 1200

# VMs, projects, pci exclude enable (boolean value)
exclude_enable = false

# VMs, projects, pci exclude list (list value)
exclude_list =

# A list of Nova filter names that will be used for filtering hosts to
# calculate destination hypervisor during live migrations (list value)
enabled_nova_filters = AvailabilityZoneFilter,ComputeFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,AggregateInstanceExtraSpecsFilter

# Client key (string value)
client_key = <VALUE>

# Client certificate (string value)
client_cert = <VALUE>

[alerting]

# enable alerting (boolean value)
enable_alerting = false

# alert storage types enabled, ex: prometheus,zabbix (list value)
#alert_storage_types =

# prometheus alert managers urls (list value)
#prometheus_alert_urls = http://10.0.0.11:9093/api/v2/alerts

# zabbix alerts urls (list value)
#zabbix_alert_urls = 10.0.0.11

# event types to alert, ex: Balancing_failed (list value)
#enabled_alerts = Balancing_failed,Balancing_started


[api]

# Database URI (string value)
db_uri = <VALUE>

# API host (string value)
api_host = <VALUE>

# API port (integer value). Probably 8089

api_port = <VALUE>

# API debug mode (boolean value)
api_debug = false

# Disable Keystone auth middleware (boolean value)
disable_auth = true

# Enable API documentation. For Now supported Swagger and Redoc.Config
# option 'docs_prefix_url' specifies path prefix to both docs types
# (boolean value)
enable_docs = false

# URL prefix for documentation. It should be set without slashes, e.g.
# docs_prefix_url='docs', then you'll find swagger and redoc at
# docs/swagger and docs/redoc (string value)
#docs_prefix_url = docs

[openstack]

#
# From openstacklb
#

# OpenStack username (string value)
username = <VALUE>

# OpenStack password (string value)
password = <VALUE>

# OpenStack project name (string value)
project_name = <VALUE>

# OpenStack auth url (string value)
auth_url = <VALUE>

# OpenStack user domain name (string value)
domain_name = <VALUE>

# check OpenStack SSL certificates (boolean value)
verify = true

# OpenStack region name (string value)
region_name = <VALUE>

# Enable openstack debugging logs level (boolean value)
logging_enabled = false

# OpenStack interface (string value)
interface = <VALUE>

[prometheus]

# Prometheus username (string value)
prometheus_username = <VALUE>

# Prometheus password (string value)
prometheus_password = <VALUE>

# Prometheus query url (uri value)
query_url = <VALUE>

# Prometheus retry count (integer value)
retry_count = 3

# Prometheus metric resolution in minutes (integer value)
metric_resolution = 5

# Prometheus timeout in seconds (integer value)
prometheus_timeout = 10

[scheduler]

# (string value)
scheduler_log_level = INFO

scheduler_check_period=60

Использование DRS через CLI

Если вы планируете управлять модулем DRS через консольный клиент для работы с DRS API, установите DRS CLI. Для этого введите команду:

$ pip install python_drs_client -i http://<nexus-ip>:<nexus-port>/nexus/repository/pypi-all/simple -v --trusted-host <nexus-ip>

Создание конфигураций DRS (DRS Config)

Конфигурация DRS определяет алгоритм работы и основные параметры.

Пример создания конфигурации DRS:

$ source ~/openrc
$ drs config create --name config_1 --algorithm help_overloaded_hypervisors --base_config '{"METRIC_RESOLUTION": 2, "METRIC_WEIGHT_CPU": 1.0, "MOVE_SYN_THRESHOLD": 75}'

Здесь:

  • config_1 — имя конфигурации;

  • help_overloaded_hypervisors — алгоритм DRS;

  • METRIC_RESOLUTION = 2 — время (в минутах), за которое будут учтены данные о нагрузках на гипервизор, значение должно быть не меньше 2;

  • METRIC_WEIGHT_CPU = 1 — коэффициент, определяющий вес получаемых данных о нагрузке на CPU гипервизора;

  • MOVE_SYN_THRESHOLD = 75 — порог нагрузки (в процентах), который определяет перегруженность гипервизора.

Ожидаемый вывод:

+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------+
| Field                | Value                                                                                                                                        |
+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------+
| name                 | config_1                                                                                                                                     |
| algorithm            | help_overloaded_hypervisors                                                                                                                  |
| exclude_enable       | True                                                                                                                                         |
| exclude_list         | server,project,pci                                                                                                                           |
| base_config          | {'METRIC_RESOLUTION': 2, 'METRIC_WEIGHT_CPU': 1.0, 'METRIC_WEIGHT_MEM': 0.0, 'MOVE_SYN_THRESHOLD': 75, 'TARGET_HYPERVISOR_SOFT_LIMIT': None} |
| id                   | 3                                                                                                                                            |
| uuid                 | 19a96358-83a5-4047-9910-b1e80a1689d4                                                                                                         |
| created_user_id      | e326737fa7d847c08ee5252fa77ad139                                                                                                             |
| created_at           | Mon, 09 Sep 2024 09:18:26 GMT                                                                                                                |
| last_updated_user_id | None                                                                                                                                         |
| updated_at           | None                                                                                                                                         |
+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------+

Создание заданий DRS (DRS Job)

Создание задания необходимо для запуска работы DRS. Формат команды создания задания:

$ drs job create [-h] [-f {json,shell,table,value,yaml}] [-c COLUMN] [--noindent] [--prefix PREFIX]
                   [--max-width <integer>] [--fit-width] [--print-empty] [--name <name>]
                   [--config_id <config_id>] [--autorun_recommendations <autorun_recommendations>]
                   [--period <period>] [--status <status>] [--offset <offset>]
                   [--availability_zone <availability_zone>]

Пример создания задания DRS:

$ source ~/openrc
$ drs job create --name job_1 --period 180 --status "enabled" --autorun_recommendations true --config_id 3

Здесь:

  • job_1 — имя задания;

  • <config_id> — ID конфигурации;

  • period = 180 — периодичность оценки состояния нагрузки на гипервизор (в секундах), значение period должно превышать METRIC_RESOLUTION из конфигурации;

  • status = "enabled" — статус (запущено);

  • autorun_recommendations = true — автоматически применять выработанные рекомендации.

Пример команды для создания задания DRS и получения его ID:

$ drs_config_id=$(drs config create --name config_1 --algorithm help_overloaded_hypervisors --base_config '{"METRIC_RESOLUTION": 2, "METRIC_WEIGHT_CPU": 1.0, "MOVE_SYN_THRESHOLD": 75}'|grep -E "\sid\s"| awk '{print $4}')

Ожидаемый вывод:

+-------------------------+--------------------------------------+
| Field                   | Value                                |
+-------------------------+--------------------------------------+
| name                    | job_1                                |
| config_id               | 3                                    |
| autorun_recommendations | True                                 |
| period                  | 180                                  |
| status                  | enabled                              |
| id                      | 3                                    |
| uuid                    | 2c196030-c665-4125-8bc5-250958bed791 |
| created_at              | Mon, 09 Sep 2024 09:47:51 GMT        |
| updated_at              | None                                 |
| created_user_id         | e326737fa7d847c08ee5252fa77ad139     |
| last_updated_user_id    | None                                 |
+-------------------------+--------------------------------------+

Просмотр оптимизаций и рекомендаций

Чтобы получить список оптимизаций, введите команду:

$ drs optimization list

Посмотрите статусы оптимизаций в выводе команды:

| 21 | f2c3bbea-7a57-4b1d-929b-d29e1780cbd4 | {"id": 1, "uuid": "e2ddc24b-fb5c-46b8-8363-419f604343e9",
"name": "config_1", "base_config": {"METRIC_RESOLUTION": 2, "METRIC_WEIGHT_MEM": 0.0,
"METRIC_WEIGHT_CPU": 1.0, "MOVE_SYN_THRESHOLD": 65, "MOVE_SYN_DIFF_AFTER": 0}, "exclude_enable": "false",
"exclude_list": "", "created_user_id": null, "created_at": "2023-10-16T14:52:07", "last_updated_user_id":
null, "updated_at": "2023-10-16T15:38:21"}   | 0       | Mon, 16 Oct 2023 15:43:19 GMT | None
|      1 | recommendations created |
...

Присутствие recommendations created в этом выводе означает, что были сгенерированы рекомендации.

Запуск рекомендаций

Чтобы получить рекомендацию, введите команду:

$ drs recommendation list --optimization_id 3

При проведении оптимизации будут сформированы рекомендации, как в примере ниже:

| id | uuid                                 | instance_uuid                        | instance_name | source_node | destination_node | expected_scoring_diff | optimization_id | created_at                    |

+----+--------------------------------------+--------------------------------------+---------------+-------------+------------------+-----------------------+-----------------+-------------------------------+

|  1 | 463d664e-4522-41a8-b524-b0c1968af520 | 38214574-603b-4501-8e69-83b16e87056c | server_3      | cmpt-1      | cmpt-2           | None                  |               3 | Tue, 17 Oct 2023 13:54:14 GMT |

Просмотр миграций

Чтобы запустить миграцию, введите команду:

$ drs migration start 1

Ожидаемый вывод:

+-------------------+--------------------------------------+
| Field             | Value                                |
+-------------------+--------------------------------------+
| recommendation_id | 1                                    |
| id                | 1                                    |
| uuid              | b7cba790-eff7-4ef3-9bf7-f2213d204770 |
| user_id           | None                                 |
| status            | created in db                        |
| error_details     | None                                 |
| started_at        | Tue, 17 Oct 2023 14:01:10 GMT        |
| updated_at        | None                                 |
+-------------------+--------------------------------------+

Чтобы узнать статус миграции, введите команду:

$ drs migration show 1

Ожидаемый вывод:

+-------------------+--------------------------------------+
| Field             | Value                                |
+-------------------+--------------------------------------+
| recommendation_id | 1                                    |
| id                | 1                                    |
| uuid              | 52950686-cbc6-43d0-8f34-cee2ec114eb5 |
| user_id           | None                                 |
| status            | completed                            |
| error_details     | None                                 |
| started_at        | Mon, 24 Jul 2023 19:08:14 GMT        |
| updated_at        | Mon, 24 Jul 2023 19:09:08 GMT        |
+-------------------+--------------------------------------+

Очистка базы данных DRS от старых объектов

Attention

Операция удаления базы данных DRS необратима. Вследствие удаления БД DRS будут удалены все конфигурации, задания, оптимизации и рекомендации.

Формат команды очистки данных DRS:

$ openstacklb-manage db purge [-h] (--all | --before <YYYY-MM-DD [HH:mm:ss]>)
options:
  -h, --help            show this help message and exit
  --all                 Clear all optimizations
  --before <YYYY-MM-DD [HH:mm:ss]>
                        Clear optimizations older than date

Использование DRS через Admin UI

Вся основная информация о DRS, такая как нагрузка на гипервизоры, оптимизации и рекомендации, доступна в разделе DRS > Board Портала администратора.

DRS Board в Портале администратора

DRS Board в Портале администратора

Управляйте конфигурациями DRS в разделе DRS > Configs.

Список конфигураций DRS

Список конфигураций DRS

Чтобы создать новую конфигурацию, нажмите кнопку Создать Config. В открывшемся окне выберите алгоритм. Заполните необходимые поля и нажмите Создать.

Создание конфигурации DRS

Создание конфигурации DRS

Управляйте заданиями DRS в разделе DRS > Jobs.

Список заданий DRS

Список заданий DRS

Чтобы создать новое задание, нажмите кнопку Создать Job. Заполните обязательные поля и нажмите Создать.

Создание задания DRS

Создание задания DRS

Всю информацию по оптимизациям (ID оптимизации, ID связанного задания, время создания и статус) можно посмотреть в разделе DRS > Optimizations.

Нажмите кнопку Посмотреть рекомендации для выбранной оптимизации в строке таблицы, чтобы посмотреть связанные рекомендации.

Чтобы увидеть оптимизации для определенного задания, используйте фильтр Job над таблицей.

Список оптимизаций

Список оптимизаций

В разделе DRS > Recommendations вы можете работать с рекомендациями DRS — смотреть все детали и запускать миграции.

Чтобы запустить миграцию по отдельной рекомендации, нажмите кнопку start_migration в соответствующей строке таблицы.

Рекомендации DRS

Рекомендации DRS

Всю информацию по миграциям (ID миграции, ID связанной рекомендации, время запуска и статус) можно найти в разделе DRS > Migrations.

Информация по миграциям

Информация по миграциям

Примеры использования DRS с иллюстрациями

Пример для алгоритма help_overloaded_hypervisors

Заданные параметры конфигурации:

  • METRIC_WEIGHT_CPU = 0.5

  • METRIC_WEIGHT_MEM = 0.5

  • METRIC_RESOLUTION = 5

  • MOVE_SYN_THRESHOLD = 80

  • MOVE_SYN_DIFF_AFTER = 10

Метрики гипервизоров (числа показывают процентное использование ресурсов определенного типа гипервизора):

Hypervisor

RAM

CPU

HV1

100

60

HV2

100

80

HV3

70

30

HV4

30

50

Вычисленная отсортированная синтетическая нагрузка гипервизоров:

Hypervisor

Score

HV2

90

HV1

80

HV3

50

HV4

40

Нагрузка на гипервизорах 1 и 2 не меньше заданного порога, и гипервизоры считаются перегруженными. После проведения оптимизации нагрузка на гипервизорах:

Hypervisor

Score

HV1

70

HV2

70

HV3

60

HV4

60

Пример для алгоритма equal_hypervisors_load

Заданные параметры конфигурации:

  • cpu_weight = 1.0

  • ram_weight = 0.0

  • network_weight = 0.0

  • metrics_time_duration_in_minutes = 5

  • allowed_load_above_average = 0

Метрики гипервизоров (числа показывают процентное использование ресурсов определенного типа гипервизора):

Hypervisor

CPU

HV1

100

HV2

60

HV3

80

HV4

50

Изначальная нагрузка на гипервизорах:

Изначальная нагрузка на стенде

Изначальная нагрузка на стенде

Вычисленная отсортированная синтетическая нагрузка гипервизоров:

Hypervisor

Score

HV1

100

HV3

80

HV2

60

HV4

40

Средняя нагрузка составляет 70 ((100 + 80 + 60 + 40) / 4). Гипервизор нуждается в разгрузке, если его нагрузка не меньше суммы средней нагрузки и allowed_load_above_average. В данном случае порог составляет 70 (70 + 0). Гипервизоры 1 и 2 будут разгружаться.

Изменение параметров нагрузки гипервизоров

Изменение параметров нагрузки гипервизоров

После проведения оптимизации нагрузка на гипервизорах:

Hypervisor

Score

HV1

70

HV2

70

HV3

70

HV4

70

Результат балансировки гипервизоров

Результат балансировки гипервизоров