k8s-rightsizer: -36% расходов на облако без боли

Проблема, которую никто не мог решить

Два года я наблюдал одну и ту же историю.

Наша компания запускает тысячи приложений на десятках кластеров Kubernetes. Расходы на облако росли. Все понимали, в чём проблема, и план её решения сводился к стандартному подходу сверху вниз: центральный комитет анализировал затраты, формировал рекомендации по оптимизации размеров ресурсов (rightsizing) и передавал их менеджерам приложений. Те передавали разработчикам. Разработчики в итоге применяли их — если было время, если не забывали, если вообще понимали, зачем это нужно.

Чаще всего — не применяли.

И честно говоря, я их не осуждаю. Они и так были перегружены. Менять настройки CPU и памяти воспринималось как отвлечение от настоящей работы. Никто не показывал им, как это влияет на счёт. Никто не связывал изменение размеров с экономией. Это было просто очередное задание, упавшее на стол сверху.

Мы пробовали Vertical Pod Autoscaler — результаты разочаровали. Пробовали коммерческий продукт (не буду называть его), но после четырёх месяцев непрерывных усилий отказались от него. Слишком сложный, слишком дорогой, слишком много постоянной поддержки при слишком малой отдаче.

Фундаментальная проблема заключалась в масштабе. При тысячах приложений и десятках кластеров никакой ручной или полуручной процесс не сдвинул бы ситуацию с мёртвой точки. Применишь горстку рекомендаций там-сям — и это капля в море. Стало совершенно очевидно: единственный способ добиться реальной экономии — пересмотреть ресурсы везде, сразу, кластер за кластером, автоматически.

Именно тогда я решил создать k8s-rightsizer.

Пасхальные каникулы, допотопный MacBook и безумная идея

Первую версию того, что стало k8s-rightsizer, я написал за четыре дня во время пасхальных каникул.

Моей рабочей машиной был MacBook Pro настолько старый, что Docker на нём уже не работает. Я использовал Podman — в репозитории есть следы этого, маленький след того, где всё началось.

Идея была простой: брать рекомендации по оптимизации ресурсов из внешнего источника через структурированный файл, автоматически применять их ко всем рабочим нагрузкам (workload) и смотреть, что получится.

Первая версия была сырой. Она применяла рекомендации контейнер за контейнером, только для нагрузок со стратегией rolling update. Я тестировал её локально на Minikube, затем на реальном кластере EKS примерно со 100 рекомендациями.

Инструмент работал три часа. 😱

Пока он работал, я периодически заглядывал в Teams. В это время разработчики активно работали с теми нагрузками. Я никому ничего не сказал. Я надеялся, что ничего не сломается.

Когда всё завершилось — тишина. Никаких алертов. Никаких жалоб. Никто ничего не заметил.

Потом я посмотрел на метрики кластера… казалось, семь нод исчезли.

Это я сделал? Я не был уверен. Лёг спать с этим вопросом.

На следующее утро

На следующий день первым делом я открыл дашборд кластера. Отфильтровал неймспейсы, которых касался. Запросы CPU и памяти сократились более чем вдвое по сравнению с предыдущим днём. Падение было чистым, заметным, неоспоримым.

Это был я.

Итерации: от прототипа к настоящему инструменту

Воодушевившись, я попробовал второй кластер. Около 200 рекомендаций. Инструмент работал более пяти часов. Были сбои. Были откаты.

Всё получилось — но не без тревоги.

Примерно через два дня после того второго запуска разработчики, работавшие с этим кластером, начали жаловаться. Что-то не работало. Сервисы вели себя неожиданно.

У меня всё оборвалось внутри. 😰 Неужели k8s-rightsizer задел нагрузки, которых не должен был трогать? Неужели я что-то сломал и не заметил?

Вечером нашли ответ. Операционная команда в то же самое время обновляла EKS, Istio и другую инфраструктуру.

Это был не я.

Облегчение было огромным — но этот эпизод сделал одну вещь кристально ясной: инструмент должен быть настолько безопасным, настолько осторожным, настолько прозрачным в том, что он трогает, чтобы подобные сомнения больше никогда не возникали. Это убеждение определило все последующие релизы.

Второй запуск также выявил три конкретные проблемы, которые нужно было решить:

1. Предварительные проверки (pre-checks). Перед тем как пытаться изменить размеры ресурсов, инструмент должен убеждаться, что нагрузка находится в нормальном состоянии. Применять рекомендации к деплойменту, который уже испытывает проблемы, — значит делать только хуже.

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

3. Параллелизм (concurrency). В кластерах с тысячами рекомендаций последовательный подход неприемлем. Нужны параллельные воркеры.

Следующие несколько выходных я потратил на реализацию этих трёх улучшений — по одному, в одиночку. Каждый релиз делал инструмент быстрее, безопаснее и надёжнее.

Настоящая проверка: 3000 приложений, 700 ядер CPU

Момент истины наступил в середине мая.

Я запустил k8s-rightsizer на первом крупном кластере — около 3000 нагрузок, примерно 2000 рекомендаций по оптимизации ресурсов. Цифры были впечатляющими ещё до начала работы: реальное потребление CPU составляло около 14 ядер. Запросы CPU — более 700 ядер.

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

При 9 параллельных воркерах инструмент завершил работу примерно за четыре часа. Запросы CPU сократились приблизительно на 50%. Почти через месяц они остаются на том же уровне.

Эта цифра не вернулась назад.

В результате среднедневная стоимость этого кластера снизилась на 36%.

Представление результатов комитету

Я представил результаты нашему центральному комитету по облачным затратам. Длинной презентации не понадобилось. Цифры говорили сами за себя.

До: 700 запрошенных ядер, 14 используемых. После: разрыв сократился вдвое — автоматически, за одну ночь, без единого прерывания сервисов.

Сегодня моя команда — единственная, которая стабильно выполняет rightsizing контейнеров в масштабе. Сейчас мы разворачиваем k8s-rightsizer ещё на 9 непродакшн-кластерах, а в планах — около 60 дополнительных.

Чему я научился

Узким местом было не знание, а исполнение.

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

Страх неудачи блокирует автоматизацию.

Rightsizing не происходил не из-за лени или непонимания. Причиной был риск. Никто не хотел быть тем, кто вызовет инцидент, изменив то, что работало нормально, без гарантии экономии. Механизм отката в k8s-rightsizer — не запоздалая мысль, а ключевая идея. Убери страх — и автоматизация становится возможной.

Масштаб меняет всё.

Применить 10 рекомендаций вручную — в какой-то момент что-то сэкономишь. Применить 2000 автоматически, по всему кластеру, за одну ночь — вот где экономия становится реальной и ощутимой.

k8s-rightsizer — проект с открытым исходным кодом

Всё, что я описал, сегодня доступно как проект с открытым исходным кодом под лицензией Apache 2.0.

k8s-rightsizer не привязан к конкретным инструментам: он не генерирует рекомендации самостоятельно, а принимает их из любого источника, который вы уже используете, — Kubecost, BMC Helix, Datadog, ваши собственные скрипты — через структурированный входной файл. Инструмент автоматически применяет их, отслеживает каждое развёртывание и немедленно откатывается при сбое.

Никакой привязки к вендору. Никаких постоянных усилий. Никакого страха.

Если вы работаете с крупным Kubernetes-окружением и узнаёте описанную проблему — буду рад пообщаться.

© 2026 meganuke