Managed K8S в Yandex Cloud — экономим без потери производительности

Всем привет! Продолжаю делиться наработками по Yandex Cloud, которые мы успешно реализовали в Спортсе”. Ранее я писал о Gitlab-раннерах и fleet-плагине, а также об утилите ycqouter. В этой статье расскажу о том, как значительно сократить расходы на manage k8s путем внедрения "прерываемых" нод без потери производительности и головной боли.

Как и большинство компаний мы активно используем kubernetes, а поскольку находимся в Облаке, то для удобства перешли на management k8s. После полного переезда именно куб стал основной статьей расхода в биллинге Яндекс Облако. Поэтому стало актуально найти способ снизить стоимость без потери в производительности.

Первый подход к решению проблемы

Самое очевидное решение лежало на поверхности – использовать "прерываемые" виртуальные машины, которые стоят до 70% дешевле. Но как мы знаем, их отличает один нюанс – они обязательно выключаются раз в сутки. Эта особенность казалась не критичной, ведь в managed k8s ноды запускаются в рамках instance group, а они умеют самостоятельно запускать "прерываемые" ВМ. Казалось бы, радость близко, но все разбилось о реальность.

После первых попыток мы выяснили, что если создать instance group из прерываемых машин, то в какой-то момент они всей толпой уходят в "отключку", а это влечет за собой сбои в работе кластера целиком. Получается, что в момент, когда большая часть нод уходит в офлайн, множество подов не могут разместиться из-за нехватки ресурсов. В дополнение к этому появляется большое количество подов в статусе Unknown и Pending. Это связано с тем, что "прерываемые" виртуальные машины выключаются без предупреждения и k8s не успевает корректно пересоздать поды на других нодах.

Переход к своему оператору

Мы попробовали несколько подходов с использованием стандартных средств Облака, но ничего не давало нужной стабильности. В итоге мы решили взять на себя остановку и пересоздание "прерываемых" нод. Результатом работы стал k8s-оператор, который и позволил нам перейти на "прерываемые" виртуальные машины и не нести потери в производительности.

Общий принцип работы достаточно прост, но при этом максимально надежен.

  1. Оператор отслеживает все ноды и собирает те, которые имеют определенные лейблы, в нашем случае yandex.cloud/preemptible: "true" и составляет список.

  2. Следующим шагом выбирает ноду, которую нужно вывести из нагрузки, основываясь на трех параметрах:
    Максимальное время жизни (21 час)
    Минимальное время жизни (12 часов)
    Окно обслуживания (с 00:00 до 07:00)

    В самом простом сценарии мы выводим ноду, которая живет больше 21 часа. Однако это может вылиться в то, что в рабочее время большое количество нод будут перезапускаться. Поэтому было добавлено "окно обслуживания" – с его помощью ночью мы пересоздаем большую часть кластера в относительно спокойное время.

  3. После того как мы определились с нодой, которая должна следующей уйти из кластера, мы навешиваем на нее cordon. Таким образом на нее больше не будут планироваться новые поды. Далее оператор начинает выселять(evicted) все поды по очереди и ждать, когда нода станет совсем пустой (за исключением служебной нагрузки).

  4. Все остальное мы отдаем на откуп Cluster autoscaling – он видит, что нода больше не используется и удаляет ее, а при необходимости создает новую, свежую ноду.

Кстати, побочным и очень приятным эффектом является уплотнение кластера. В процессе evicted подов cluster scheduler распределяет поды по нодам и только после этого создает новые.

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

Ограничения и рекомендации

Есть несколько важных моментов, которые стоит учитывать:

Результат

И конечно всем интересно, а сколько же можно сэкономить с таким подходом. Приведем небольшую табличку до и после.

До использования оператора:

Характеристики

Прерываемая

Количество

Цена

NodeGroup 1

vCPU 8, RAM 16

No

15

169 125

NodeGroup 2

vCPU 24, RAM 48

No

1

33 794

202 919

После использования оператора:

Характеристики

Прерываемая

Количество

Цена

NodeGroup 1

vCPU 8, RAM 16

No

3

33 825

NodeGroup 2

vCPU 8, RAM 16

Yes

15

43 155

NodeGroup 2

vCPU 24, RAM 48

No

1

33 794

110 774

Как видно, мы сократили расходы на кластер почти на 50%, что очень хорошо с учетом того, что у нас далеко не один такой кластер. Но и на этом мы останавливаться не собираемся. В планах есть улучшения, например, автоматическая перебалансировка и подбор нод (аля-karpenter). Если у вас есть похожие наработки, то поделитесь ими в комментариях, интересно сравнить подходы.

@GoooodBoy
17.12.2025 19:04 UTC
Первоисточник

Комментарии

@zVlad909
17.12.2025 18:18 UTC
-3

Меня умиляет стремление иметь много виртуальных машин и много узлов (node - узел, утолщение) и стручков (pod - стручок, кокон, подвеска). Слово cordon можно писать и кирилицей - кордон, есть такое слово в русском языке.

Хотелось бы услышать объянение этого стремления от практикующего специалиста. .

@0x00FA7A55
17.12.2025 18:46 UTC
+1

Казалось бы, что лучше один стручок, но как у коня, но всё-таки когда их N+1, как-то поспокойнее. А то вдруг не поднимется, или чего хуже, упадёт в самый неподходящий момент.

мимо практикующий специалист

17.12.2025 21:19 UTC
0

А что Вы думаете об издержках управления всей этой многоузловой и многостручковой конфигурацией?

Подскажу,: это не бесплатно.

А в целом ответ Ваш принимается. Да на таких ненадежных платформах как х86 и облако единственный выход это создавать софтверную избыточность и пытаться ее поддерживать через неизбежные издержки. Когда выигрываешь в одном обязательно проигрываешь в чем то другом.

В гарантированных прибылях при этом остаются только поставщики базового обеспечения (Кубернетес) и облачных сервисов.

@HWTH
18.12.2025 11:22 UTC
0

Спасибо за статью. После прочтения появилось несколько вопросов:
1. Яндекс выключает прерываемую ноду не только раз в сутки, но и по своему усмотрению, когда потребуются ресурсы. Выключает он посылая сигнал shutdown на ноду, без предварительного уведомления. Вы как-то пытались победить?
2. Что вы будете делать, если в зоне закончатся ресурсы для прерываемых нод?

@GoooodBoy
18.12.2025 11:26 UTC
0
  1. Да, прерываемая ВМ может быть выключена в любое время, по этому пока используем в тестовых кластерах. Но за несколько месяцев использования еще не было ситуации чтобы это повлияло на работу кластера. И да, сигнал посылается и его даже можно отследить, то он отправляется за 30 секунд до отключения, так что толком ничего успеть не получится.

  2. Такая ситуация тоже возможна, но пока ниразу не сталкивались. Для обработки подобных сценариев дорабатываем оператор, чтобы он за раз не кордонил больше одной ноды и следил, чтобы новые ноды появляись во время. Возможно в будущем продумаем возможность переводить нагрузку на обычные ноды в случаи невозможности создать прерываемую.

06.01.2026 06:40 UTC
0

Доброго дня. Подскажите, пожалуйста, а со стороны ОС не пробовали отловить сигнал от OS на shutdown, чисто если повыдумывать, можно отправить какой-нибудь rest на момент отключения ноды, который может бы и сообщил мастеру куба о выводе ноды из кластера или также посылать в ваш оркестратор информацию, чтобы он уже начинал конфигурировать по иному ваше окружение?

06.01.2026 09:45 UTC
0

Выше писал, что Яндекс Облако посылает сигнал за 30 секунд до выключения ВМ, этого времени недостаточно чтобы что-то успеть сделать. По этому эту идею в начале откинули.

@freelook27
18.12.2025 17:39 UTC
0

спасибо за статью! хорошая идея. мы настроили бота, который выключает все наши тестовые managed сервисы на ночь и на выходные, с интеграцией в mattermost, чтобы в случае чего, если тестировщику надо поработать, чтобы он отменил остановку или запустил все сервисы одной командой.

@GoooodBoy
18.12.2025 18:52 UTC
0

Да, мы тоже такой подход используем для ВМ разработчиков и части инфровых ВМ.

@Mimimi
07.04.2026 09:24 UTC
0

Добрый день,

Не планируете ли вы выпустить оператор в open-source или в платном виде в yandex cloud marketplace?

@GoooodBoy
07.04.2026 10:42 UTC
+1

Добрый день. Пока не планируем выпускать в мир. Просто не хватает сил, чтобы довести оператор до публичного вида.