Раннеры GitLab: spot-инстансы против резервированных ВМ для занятых команд
Раннеры GitLab: spot-инстансы против резервированных ВМ для занятых команд. Сравните время ожидания, промахи кеша, шаги восстановления и сценарии, где подходит каждый вариант.

Почему этот выбор важен для команд, которые пишут код весь день
Команды, которые выкатывают код весь день, почти сразу чувствуют проблемы с раннерами. Сборка, которая стартует на 6 минут позже, может съесть больше времени, чем сборка, которая выполняется на 30 секунд дольше. Люди останавливаются, ждут ответ, переключаются между вкладками, теряют контекст и возвращаются позже. Эта задержка растягивается на ревью, мержи, хотфиксы и подготовку релизов.
Большинство команд замечает время ожидания раньше, чем чистую скорость сборки. Причина простая: медленная задача все еще кажется терпимой, если она стартует сразу. Задача, которая стоит в очереди, ощущается как сломанная, даже если сама сборка идет быстро. Если десять разработчиков отправляют изменения в течение дня, мелкие задержки превращаются в часы потерянного времени и релиз, который постоянно сдвигается.
Поэтому выбор между spot-инстансами и резервированными ВМ важнее для занятых команд, чем для редких сборок. Spot-мощность на бумаге выглядит дешево, но риск прерывания проявляется в самый неудобный момент: полная очередь перед обедом, отмененная задача во время релиза или холодный раннер, которому нужно снова скачать все с нуля. Резервированные ВМ обычно стоят дороже в час, но зато дают более стабильный старт и меньше сюрпризов.
Промахи кеша только усугубляют ситуацию. Когда раннер исчезает, он часто уносит с собой и локальный кеш. Тогда обычный пайплайн начинает заново скачивать зависимости, пересобирать слои и создавать артефакты, которые уже существовали час назад. Задача, которая должна занять 4 минуты, растягивается на 12, а в коде при этом ничего не изменилось.
Реальная цена — это не только счет от облака. Команды платят еще и временем на восстановление. Кому-то нужно перезапускать задачи, проверять логи, повторно запускать упавшие этапы и разбираться, связана ли ошибка с кодом или с раннером. Для команды, которая работает весь день, эта дополнительная рутина может полностью съесть выгоду от более дешевых вычислений.
Хорошее решение балансирует цену, стабильное время ожидания в очереди и то, сколько ручной разборки ваша команда готова терпеть, когда задачи падают на полпути.
Чем spot-инстансы и резервированные ВМ отличаются на практике
Spot-инстансы экономят деньги, потому что облачный провайдер продает лишнюю емкость со скидкой. Но есть важная оговорка: провайдер может забрать машину почти без предупреждения. Сборка может остановиться посреди скачивания Docker-образа, прогона тестов или загрузки артефактов. Если команда пишет код весь день, такие прерывания быстро отражаются и на очереди, и на повторных запусках.
Резервированные ВМ стоят дороже, зато они доступны. Ваш раннер не должен появляться и исчезать каждый раз, когда меняется нагрузка. Это делает рабочий день спокойнее, особенно когда разработчики ожидают, что сборка стартует сразу после коммита.
Задержка запуска и поведение кеша
Новый spot-раннер часто стартует с нуля. Он загружается, ставит инструменты, скачивает базовые образы, восстанавливает кеш и только потом начинает задачу. Даже если автоскейлинг работает хорошо, первые минуты все равно накапливаются. Десять коротких задач на холодных машинах могут ощущаться медленнее, чем две длинные задачи на стабильной ВМ.
Резервированные ВМ обычно дольше сохраняют локальное состояние. Слои Docker, пакеты и результаты сборки часто остаются на диске между задачами. Это значит меньше промахов кеша и меньше полных загрузок. Когда один и тот же проект собирается много раз в день, прогретый кеш экономит больше времени, чем ожидает большинство команд.
Прерванные задачи вредят кешу тоже. Если spot-машина исчезает до загрузки нового кеша, следующая задача может снова его не найти и повторить ту же работу. Одна авария может замедлить несколько следующих сборок.
Что команды замечают первым делом
Большинство команд видит один и тот же сценарий. Spot-раннеры на бумаге кажутся дешевыми, но в часы пик ощущаются неровно. Резервированные ВМ воспринимаются предсказуемо, потому что они быстрее стартуют и реже ломаются. Восстановление на стабильных машинах тоже проще, потому что логи, временные файлы и локальные артефакты все еще на месте, когда кто-то разбирает ошибку.
Spot-инстансы для CI все еще могут быть уместны. Они хорошо подходят для пакетных задач, ночных запусков и больших наборов тестов, которые можно повторить без сильной боли. Резервированные ВМ для CI лучше подходят для ровного дневного потока, релизных пайплайнов и команд, которые теряют реальное время, пока разработчики ждут.
Поэтому этот выбор редко сводится только к цене. Речь идет о том, что для вашей команды важнее: меньшая стоимость с большим числом перебоев или более стабильные сборки с меньшим количеством сюрпризов.
Что измерить перед выбором
Цена — это самая простая часть. Труднее понять, где именно команда теряет время, когда пайплайны идут весь день.
Если сравнивать только ежемесячную стоимость вычислений, можно выбрать более дешевый вариант и при этом замедлить всех остальных. Раннер, который стоит меньше, но добавляет по пять минут ожидания перед каждой сборкой, может сжечь больше инженерного времени, чем сэкономит.
Перед выбором отслеживайте несколько показателей и разделяйте их по часам и по этапам пайплайна. Считайте среднее время ожидания в очереди по каждому часу рабочего дня, чтобы видеть обычный дневной паттерн. Смотрите p95 времени ожидания в самые загруженные часы, потому что средние значения скрывают самые болезненные случаи. Считайте попадания и промахи кеша для больших задач, особенно при установке зависимостей, повторном использовании слоев Docker и в крупных тестовых наборах. Отмечайте, как часто инженеры запускают упавшие задачи заново. И отдельно разделяйте этапы сборки, тестов и деплоя, потому что они ломаются по разным причинам и по-разному реагируют на прерывания.
Простой пример показывает, почему это важно. Допустим, команда пишет код весь день, а среднее время ожидания выглядит нормальным — 40 секунд. Звучит безобидно. Но с 10 утра до 2 дня p95 подскакивает до 6 минут, потому что новые spot-инстансы не успевают быстро появляться. Одновременно большие задачи сборки чаще теряют кеш, поэтому каждый повторный запуск снова качает зависимости. Среднее значение скрывает обе проблемы.
Стоит также отмечать причину падения задач. Разделяйте выключение раннера, задержку старта, промах кеша, тайм-аут при скачивании по сети и реальный сбой теста. Если все смешать в одну кучу, spot-инстансы могут выглядеть хуже, чем есть на самом деле, а резервированные ВМ — чище, чем они есть.
Командам, которые весь день гоняют CI, обычно хватает одной недели чистых данных. Этого часто достаточно, чтобы увидеть, откуда идет боль: от всплесков очереди, холодного кеша или пересборок после прерванных задач.
Реалистичный пример на занятой команде
Продуктовая команда из семи человек выкатывает код с утра до вечера. Они весь день отправляют мелкие исправления, правки интерфейса, обновления тестов и короткие изменения бэкенда. Большинство пайплайнов начинается с быстрой сборки приложения и тестовой задачи, которая занимает около 4 минут, если раннер уже готов.
Несколько раз в день кто-то еще запускает более долгую задачу по сборке контейнерного образа, и она идет 12–15 минут. Эти длинные задачи важны, потому что они занимают раннер намного дольше, чем небольшие сборки приложения.
На резервированных ВМ день ощущается приятно скучным. Два раннера остаются прогретыми, кеш хранится локально, и большинство задач стартует через 20–40 секунд. Разработчик отправляет небольшое изменение, переключается на другую задачу и возвращается уже к завершенному пайплайну.
К обеду команда уже прогнала десятки задач. Время ожидания остается низким, потому что машины уже на месте. Даже если двое отправляют изменения одновременно, ожидание обычно остается коротким.
На spot-инстансах у той же команды день выходит менее ровным. Рано утром все выглядит хорошо, потому что дешевую емкость легко получить. Около 11 утра трое разработчиков отправляют изменения в течение десяти минут, а затем длинная сборка образа забирает единственный прогретый раннер. Две небольшие сборки приложения стоят в очереди 6 минут.
Само по себе это не звучит катастрофой. Но один человек ждет мерж, другой откладывает ревью, а третий отправляет следующий фикс до того, как первый пайплайн успевает завершиться. Мелкие задержки начинают наслаиваться.
После обеда один раннер поднимается на свежей spot-ВМ. Сборке приложения все еще нужно только 4 минуты, но кеша уже нет, поэтому загрузка зависимостей добавляет еще 3. Один промах кеша GitLab легко пережить. Четыре промаха за день могут добавить 12 лишних минут, и это еще до учета очереди.
Потом приходит дорогая задержка. 14-минутная сборка образа теряет spot-ВМ на 11-й минуте. Команда перезапускает задачу, ждет другой раннер и снова скачивает слои на новой машине. Одна авария может стоить 15–20 минут.
К концу дня команда может выкатить тот же код на обеих схемах. Разница в том, как ощущается день. Резервированные ВМ стоят дороже, но работа продолжает двигаться. Spot-инстансы могут экономить деньги, однако занятые команды часто возвращают часть этой экономии в виде ожидания в очереди, промахов кеша и повторных запусков.
Как протестировать оба варианта шаг за шагом
Когда команды сравнивают раннеры GitLab: spot-инстансы против резервированных ВМ, честный тест должен быть скучным. Возьмите один активный проект, заморозьте пайплайн и меняйте только тип раннера. Если во время теста вы правите задачи, ключи кеша или базовые образы, результаты инфраструктуры смешаются с изменениями в самом пайплайне.
Выберите репозиторий, который собирается весь день, а не побочный проект, где несколько задач запускаются только во второй половине дня. Вам нужен обычный командный трафик, обычные merge request'ы и привычный набор из быстрых сборок и более тяжелых задач. Тихая неделя скрывает проблемы с очередью.
Как провести честный тест
Запустите spot-раннеры на одну полную рабочую неделю, а затем резервированные ВМ — на следующую полную рабочую неделю. Держите размер машины, регион, теги раннера и правила кеша как можно ближе друг к другу. Если вы используете самостоятельно размещаемые раннеры GitLab, оставьте тем же и backend кеша, и registry.
Постарайтесь выбрать две обычные недели. Не тестируйте spot-раннеры во время релизного рывка, а резервированные ВМ — в спокойный период. Если нагрузка сильно меняется, повторите тест позже и сравните оба раунда.
В обе недели записывайте каждый день одни и те же вещи: среднее время ожидания в очереди, самые большие всплески очереди в пиковые часы, процент промахов кеша на крупных задачах, время восстановления после прерванной задачи, число ручных повторов и сбои, вызванные инфраструктурой, а не кодом.
Считайте не только скорость, но и восстановление
Быстрый раннер бесполезен, если он исчезает посреди сборки. Каждый раз, когда spot-инстанс падает, фиксируйте, что было дальше. GitLab сам повторил задачу? Кому-то пришлось очищать зависший раннер, перезапускать пайплайн или заново собирать кеш? Считайте минуты до того момента, когда команда снова может работать нормально.
Используйте один простой журнал для обеих недель. Таблицы достаточно. Записывайте время, имя задачи, был кеш использован или нет и сколько люди ждали. Короткие заметки помогают лучше, чем идеальные дашборды.
В конце сравните стоимость с потерянным временем. Более дешевый раннер все равно может обойтись дороже, если разработчики по 20 минут ждут по три-четыре раза в день. Обычно именно на этом разница становится очевидной.
Что делать, если задача падает посреди сборки
Когда сборка умирает на полпути, скорость важнее идеальной чистоты. Занятые команды теряют время дважды: сначала на упавшей задаче, потом на очереди, которая растет за ней.
Начните с одного вопроса: раннер остановился до или после шагов загрузки кеша и артефактов? Это подсказывает, можно ли быстро восстановиться или нужен полный пересбор.
Если задача успела пройти этапы компиляции, загрузить артефакты, а потом потеряла раннер на более позднем шаге, часто можно повторить только упавшие этапы, а не весь пайплайн.
Первая проверка
Быстрая проверка экономит много лишних вычислений. Посмотрите последние успешные строки лога. Убедитесь, что для упавшего пайплайна есть артефакты. Проверьте, был ли кеш загружен или только восстановлен. Затем поймите, исчез раннер или упала сама задача.
Если артефакты все еще есть, перезапускайте только упавший этап тестов, упаковки или деплоя. Команды часто повторно запускают все по привычке. Это дорого и поднимает время ожидания в очереди для остальных.
С промахами кеша нужен другой подход. После крупного промаха не стоит надеяться, что случайные кеши веток сами все исправят. Пересоберите кеш с одной известной ветки, обычно main или отдельной сборочной ветки, а потом пусть новые задачи тянут его из этого чистого базового состояния. Это работает лучше, чем если десять разработчиков создают десять чуть разных кешей параллельно.
Держите один стабильный резервированный раннер онлайн для срочных релизов, даже если большая часть парка использует spot-инстансы. Много их не нужно. Одна надежная машина может выдержать хотфикс, патч для клиента или release candidate, пока более дешевые раннеры восстанавливаются.
Кто отвечает за инцидент
В рабочее время один человек должен отвечать за проблемы с раннерами. Он проверяет логи, отменяет дублирующиеся повторы и решает, стоит ли переключиться на стабильный раннер. Без явного владельца три человека начинают ковырять один и тот же сломанный пайплайн и делают очередь еще хуже.
Спокойный процесс восстановления лучше героической отладки. Для команд, которые работают весь день, это обычно значит выборочные повторные запуски, чистую пересборку кеша и один раннер, которому вы доверяете, когда время поджимает.
Частые ошибки, которые искажают результат
Команды часто сравнивают раннеры GitLab: spot-инстансы против резервированных ВМ на тесте, который выглядит честным на бумаге, но на практике получается неровным. Маленькие изменения во время теста могут так исказить цифры, что вы придете к неверному варианту.
Одна из частых ошибок — менять размер машины между неделями теста. Если spot-раннер на этой неделе использует 8 vCPU, а резервированная ВМ на следующей неделе — 4, вы больше не сравниваете модели ценообразования. Вы сравниваете разные уровни мощности. Более быстрая машина скроет проблемы очереди, сократит время задачи и сделает загрузку кеша менее болезненной.
Изменения кеша тоже портят много тестов. Если кто-то меняет ключи кеша, пути кеша или правила хранения в середине теста, промахи кеша GitLab растут по причинам, которые не связаны ни со spot-прерываниями, ни с резервированной емкостью. Команда может решить, что именно spot-инстансы замедлили сборки, хотя настоящая проблема — новый ключ кеша, из-за которого каждая задача заново пересобирает зависимости.
Среднее время сборки тоже скрывает то, что разработчики чувствуют на самом деле. Задача, которая обычно заканчивается за 6 минут, но иногда ждет 12 минут в очереди, на графике средних значений все еще будет выглядеть нормально. Занятым командам стоит смотреть на p95 времени ожидания, процент попаданий в кеш и частоту повторных запусков после прерывания. Эти числа показывают неровные края.
Холодные старты после тихих периодов тоже искажают результат. Пул раннеров может выглядеть отлично в загруженный день и все равно ощущаться медленным в 8:30 утра, когда первый push приходит после спокойной ночи. Spot-раннерам часто нужно время, чтобы загрузиться, зарегистрироваться, скачать образы и прогреть кеш. Если не учитывать эти часы в обзоре, вы пропустите реальную ежедневную боль.
Самая дорогая ошибка — ставить релизные задачи на самый дешевый тип раннера только потому, что это снижает стоимость в минуту. Релизным пайплайнам, миграциям базы данных, шагам подписи и задачам деплоя нужна скучная надежность. Если spot-интервал оборвет релиз, восстановление может обойтись дороже, чем недели экономии.
Честное сравнение сохраняет несколько вещей неизменными: один и тот же размер машины и образ, одни и те же ключи кеша и правила артефактов, одинаковый набор задач, включая утренние холодные старты, и раздельный учет обычных задач и релизных задач. Если во время теста вы все время что-то меняете, результат покажет только шум.
Короткая проверка перед решением
Перед тем как выбирать между spot-инстансами и резервированными ВМ для раннеров GitLab, посмотрите на последние две недели пайплайнов, а не на один особенно удачный день. Команды, которые работают весь день, часто обвиняют цену в первую очередь, но реальная проблема обычно связана со временем и поведением кеша.
Начните с паттернов очереди. Если очередь растет примерно в одни и те же часы каждый будний день, нагрузка у вас предсказуемая. Тогда чаще выигрывают резервированные ВМ, потому что они уже стоят на месте, когда разработчики отправляют код в 9 утра, после обеда или ближе к концу дня.
Затем откройте несколько медленных задач и посмотрите, куда уходят минуты. Если большая часть времени уходит на скачивание зависимостей, загрузку образов и этапы подготовки, spot-мощность может вредить сильнее, чем кажется. Каждая новая машина стартует с нуля, а холодные машины чаще промахиваются по кешу.
Прогретые слои Docker могут сильно изменить картину. Если ваши сборки зависят от больших базовых образов или тяжелых инструментальных цепочек, стабильная ВМ часто экономит несколько минут на каждом запуске. Если задачи у вас маленькие, без состояния и завершаются быстро, spot-раннеры переносятся проще.
Работа над релизами требует более строгого подхода. Задайте простой вопрос: может ли команда пережить упавшую задачу во время релиза и просто запустить ее заново без стресса? Если ответ нет, держите релизные пайплайны на резервированных машинах, даже если остальная команда пользуется spot-инстансами. Прерывание обычной ветки раздражает. Прерывание хотфикса — гораздо хуже.
Один стабильный резервный раннер часто закрывает самые неприятные случаи. Ему не нужно тянуть все пайплайны. Ему достаточно места под кеш и достаточной мощности, чтобы забрать срочные задачи, когда spot-раннеры исчезают или слишком часто стартуют с нуля.
Простое правило помогает. Если главная боль — это время ожидания в очереди, обычно выигрывают резервированные ВМ. Если больше всего мешают простои и ваши задачи легко повторяются, spot-раннеры могут подойти. Если вы находитесь посередине, используйте оба варианта: spot для обычных сборок, один резервированный раннер для релизов, защищенных веток и всего, что команда не может позволить себе запускать заново.
Что делать дальше
Не начинайте со всех репозиториев сразу. Выберите сначала самый загруженный пайплайн — тот, который работает весь день и раздражает людей, когда замедляется. Так вы быстро получите реальные данные, особенно по времени ожидания, промахам кеша и тому, как часто упавшей задаче нужна ручная чистка.
Практичное разделение подходит многим командам. Сначала отправляйте прерываемые тестовые задачи на spot-раннеры. Резервированные ВМ оставляйте для релизных задач, сборок образов и всего, что зависит от прогретого кеша или должно завершиться строго по графику. Если spot-инстанс исчезает во время нестабильного интеграционного теста, вы теряете несколько минут. Если он исчезает во время релизной сборки, вы теряете доверие.
Держите эксперимент коротким и строгим. Переведите только один загруженный пайплайн на одну-две недели. Unit-тесты, linting и необязательные проверки отправляйте на spot-раннеры. Деплои, релизы по тегам и сборки с тяжелым кешем оставляйте на резервированных ВМ. Отслеживайте время ожидания, частоту повторов, процент попаданий в кеш и время восстановления. Записывайте каждый ручной шаг, который люди делают после прерванной задачи.
Итог должен свестись к одному правилу, которое вся команда сможет запомнить. Формулировка может быть такой: «Spot-раннеры — для задач, которые можно повторить. Резервированные ВМ — для задач, которые нельзя задерживать, и для задач со стабильным кешем». Если инженерам все еще приходится гадать, значит схема слишком запутана.
Восстановление важнее, чем думает большинство команд. Дешевый раннер не такой уж дешевый, если разработчик тратит 20 минут на снятие блокировок, прогрев кеша или перезапуск сломанного деплоя. Занятые команды чувствуют эту цену каждый день.
Если вам нужен внешний разбор, Oleg Sotnikov на oleg.is может оценить вашу схему раннеров, план кеша и процесс восстановления после сбоев как Fractional CTO. Такой обзор помогает, когда команда уже протестировала оба варианта, но цифры все еще выглядят шумными. Иногда нескольких изменений в правилах раннеров, структуре кеша или группировке задач достаточно, чтобы сократить ожидание без заметного роста расходов.
Часто задаваемые вопросы
Что лучше выбрать занятой команде: spot-раннеры или резервированные ВМ?
Для команд, которые гоняют пайплайны весь день, чаще выигрывают резервированные ВМ. Они быстрее стартуют, держат кеш прогретым и уменьшают число повторов. Spot-раннеры подходят, если важнее сэкономить и команда готова мириться с перебоями.
Когда spot-инстансы имеют смысл для GitLab CI?
Spot-раннеры хорошо подходят для задач, которые не жалко повторить. Ночные сборки, необязательные тестовые наборы и фоновая сборка часто отлично там работают. Хуже они подходят для релизов, хотфиксов и сборок с тяжелым кешем.
Почему время ожидания в очереди важнее, чем чистая скорость сборки?
Потому что ожидание люди чувствуют раньше, чем саму медленную сборку. Сборка, которая стартует сразу, обычно воспринимается нормально, даже если идет чуть дольше. А сборка, которая стоит в очереди, ломает поток работы, задерживает ревью и тормозит мержи.
Как промахи кеша меняют выбор по цене?
Промах кеша превращает обычную задачу в более тяжелую. Раннеру приходится заново скачивать зависимости, пересобирать слои и воссоздавать файлы, которые уже были раньше. Эта лишняя работа может полностью съесть выгоду от более дешевого compute.
Что нужно измерить перед выбором?
Смотрите на время ожидания в очереди по часам, p95 в пиковые периоды, процент попаданий в кеш на крупных задачах, число ручных повторов и время восстановления после сбоя. Разделите сборку, тесты и деплой, чтобы понять, где именно начинается проблема.
Сколько времени нужно тестировать spot- и reserved-раннеры?
Запускайте каждую схему на полный рабочий week на одном и том же активном проекте. Держите размер машины, регион, правила кеша и набор задач как можно ближе. Если нагрузка сильно меняется, повторите тест позже и сравните оба раунда.
Стоит ли запускать релизные пайплайны на spot-раннерах?
Нет, не по умолчанию. Релизным пайплайнам нужны стабильный старт и минимум сюрпризов. Если релиз не может ждать повторного запуска, лучше оставить его на резервированном раннере.
Как выглядит практичная смешанная схема?
Простой вариант работает у многих команд. Отправляйте прерываемые тесты и необязательные задачи на spot-раннеры, а один резервированный раннер держите для релизов, защищенных веток, сборок образов и срочных исправлений. Так вы снижаете расходы, не делая весь день неровным.
Как восстанавливаться, если задача упала посреди сборки?
Сначала проверьте, умер ли раннер до или после загрузки кеша и артефактов. Если артефакты уже есть, перезапускайте только упавший этап. Если сломался кеш, пересоберите его с одной стабильной ветки, а не позволяйте многим веткам одновременно создавать разные кеши.
Когда стоит обратиться за внешней помощью с настройкой раннеров?
Приглашайте внешнюю помощь, когда данные теста выглядят шумными или команда все время спорит о раннерах. Свежий взгляд на правила раннеров, схему кеша и группировку задач часто помогает быстрее, чем новые догадки.