Автоскалирование игровых серверов при помощи Custom Pod Autoscaler
Ищем замену HPA и VPA.
Преимущества использования системы оркестрации контейнеров — удобство их развертывания, обновления и масштабирования. И одним из наиболее популярных таких инструментов является Kubernetes.
Многие знают, что Kubernetes имеет встроенный механизм для автоскалирования подов — Horizontal Pod Autoscaling (HPA). Но что, если надо принимать решение с учетом множества факторов: суммы метрик, зависимости от количества готовых контейнеров, процента или доли доступных/недоступных подов или даже времени суток? А если эти показатели важны для нас все вместе?
Мы в студии Whalekit смогли решить эту задачу. И отличным решением для этого стал Custom Pod Autoscaler (CPA).
CPA — инструмент, который позволяет настраивать логику принятия решения с использованием любых доступных метрик. С минимальными знаниями любого языка программирования можно организовать настолько функциональную и гибкую модель автоскалирования, насколько позволяет вам ваша фантазия.
Немного о преимуществах автоскалирования и существующих решениях
Если вы платите за используемые вычислительные мощности или делите сервера с другими проектами, важно потреблять именно столько, сколько действительно требует приложение или проект в целом ровно в данный момент. Автоскалирование позволяет создавать новые копии приложения в зависимости от заданных параметров — например, потребляемых ресурсов, количества пользователей, RPS или времени суток. Реализация такого подхода обеспечивает наиболее оптимальное соотношение запаса прочности вашего сервиса и его стоимости.
При поиске решения мы выделили для себя следующие наиболее важные в разработке критерии:
- Гибкость — инструмент, который позволял бы реализовать любую логику работы в зависимости от условий, входных данных и даже времени суток.
- Легкость настройки — решение должно быть простым и понятным. Инженер с любым уровнем навыков программирования должен иметь возможность разобраться в происходящем и произвести отладку.
- Надежность — решение должно стабильно работать на высоких нагрузках, а в случае сбоя — быстро восстанавливаться.
Из тех решений, что мы рассматривали:
- Встроенный механизм в Kubernetes — Horizontal Pod Autoscaler. И хоть HPA довольно прост в настройке, но не самый гибкий;
- Keda — расширяет функционал HPA, добавляет много полезных возможностей, например — AI-based predictive, но все это существенно усложняет процесс внедрения и настройки;
- Vertical Pod Autoscaler — как и другие механизмы вертикального масштабирования, нам он не подходил из-за особенности архитектуры приложения.
А остановились мы в итоге, как и было сказано, на CPA, и вот почему.
Custom Pod Autoscaler и его особенности
CPA — это фреймворк, который позволяет описать требуемую логику работы на всех популярных языках программирования. Подробности о его установке можно посмотреть на странице с документацией, там же можно найти базовые примеры по настройке.
Вся суть работы основана на двух основных этапах:
- Scrape metrics;
- Evaluation.
Они описываются в файле config.yaml. Я буду использовать Python для описания логики, но вам ничего не мешает использовать любой доступный способ, в том числе привычный язык программирования. Достаточно просто указать на исполняемый файл для загрузки окружения.
Первый этап — это сбор метрик. Откуда и как их собирать, вы вольны выбирать сами. Можно обращаться к API Prometheus, Zabbix, Munin, HTTP Request — хоть из файла читайте. Каких-либо ограничений здесь нет.
Мы занимаемся разработкой игр для мобильных устройств, поэтому в качестве примера приведу скрипт, который собирает информацию о сессионных игровых серверах. Их состояния могут быть следующими:
- Busy — сервер занят, на нем идет игра;
- Ready — сервер полностью готов принять игру;
- Initializing — сервер находится в состоянии загрузки.
Вычисленные значения на основании этих состояний:
- Available — сумма занятых и доступных серверов;
- Busy containers — процент занятых игровых серверов.
Первое, что нам нужно, — это получить информацию о текущем состоянии Deployments. Тут я просто обращаюсь к Prometheus за необходимыми мне данными с учетом окружения и версии. В проде у нас может быть несколько окружений одновременно.
Самое интересное — это второй этап: оценка метрик и принятие решения об автоскалировании вверх или вниз (upscale и downscale). Тут можно производить любые арифметические операции с данными или метриками, добавить условия о состоянии соседних или зависимых подов (контейнеров), времени суток и количестве пользователей. Причем вам не надо выбирать: все эти параметры могут быть важны вместе именно в вашем случае, и можно написать модель, которая будет идеально подходить вам с учетом метрик и параметров.
Для меня важны шесть параметров, которые могут быть уникальны для каждого окружения или версии игровых серверов, поэтому я получаю их из env-переменных:
- Min/max threshold — минимальные и максимальные значения срабатывания автосканирования. Часто выставлены как 70 и 90, соответственно. Таким образом мы получаем некий коридор. Если наша метрика находится в нем, CPA не будет делать ничего. Если же значение превысит maxThreshold, будут подняты еще сервера, а если станет ниже minThreshold, убраны лишние.
- Min/max replicas — минимальное и максимальное количество реплик. Может быть полезно в разных ситуациях — например, при ограничении ресурсов в кластере.
- ScaleUp/ScaleDown — количество подов, которое мы прибавляем или убираем. Позволяет гибко задавать динамику изменения подов в кластере. Обычно мы хотим, чтобы кластер активно увеличивался (scaleUp указываем +10) и плавно уменьшался (scaleDown –3).
Интересная особенность, что все общение и передача данных происходит внутри CPA через stdout в формате JSON. Поэтому в скриптах вы можете видеть:
Это избавляет от сложных механизмов и протоколов обмена информации внутри сервиса и упрощает отладку. Думаю, многие найдут такой подход спорным, но лично мне понравилось.
На этом этапе у нас уже есть значение с требуемым количеством реплик, которое надо просто передать в нужный нам деплоймент. Для этого создаем ресурс в кластере, который и будет следить за состоянием Deployments и выставлять значение target replicas:
Вот так у нас выглядит график работы за неделю:
Здесь зеленая линия — это количество занятых серверов, оранжевая — доступно всего. Соответственно, разница между ними — это и есть запас прочности, который у нас есть на случай резкого прилива игроков.
Еще можно заметить желтую линию — это сервера, находящиеся в состоянии Initializing. Обычно такое происходит при первой загрузке пода или после завершения игровой сессии.
Вывод
Автоскалирование, какой и любой другой автоматизированный процесс, бывает сложен в изучении, настройки и внедрении. А современные инструменты позволяют сильно облегчить эти процессы.
Мы выбрали для себя Custom Pod Autoscaler и продолжаем активно его использовать. Он дает нам возможность настроить все так, как мы хотим. Если это можно описать с помощью кода, то оно будет работать.