MAATRIX / Блог / Выделенные серверы / Выделенный сервер для CI/CD: сколько ядер нужно GitLab Runner и Jenkins

Выделенный сервер для CI/CD: сколько ядер нужно GitLab Runner и Jenkins

MAATRIX · Выделенные серверы · Статья 7 из 48

Самая дорогая строка в журнале сборки иногда выглядит совершенно безобидно: «Ожидание свободного исполнителя». Компилятор ещё не запущен, тесты ничего не проверяют, зато разработчик уже переключился на другую задачу. Когда очередь повторяется после каждого изменения, команда начинает платить за инфраструктуру собственным вниманием.

Выделенный сервер для CI/CD помогает сделать сборки предсказуемыми. Но покупать его по правилу «чем больше ядер, тем короче очередь» рискованно. Сборочная ферма состоит из разных операций, и некоторые из них прекрасно умеют ждать сеть всем процессорным коллективом. Подберём конфигурацию для self-hosted GitLab Runner или Jenkins через устройство самого конвейера.

Подберите конфигурацию для своего проекта

Характеристики, стоимость и условия подготовки выделенных серверов MAATRIX в России и США.

Выбрать выделенный сервер

У сборки два времени, и улучшать нужно оба

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

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

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

Другой проект действительно компилирует большой объём кода и умеет распределять работу. Здесь ядра востребованы, пока не заканчиваются память и пропускная способность диска. Наконец, набор интеграционных тестов может запускать базу данных и несколько сервисов: для него число заданий в очереди мало что говорит без понимания веса каждого окружения.

Соберите три-четыре типовых профиля: лёгкая проверка, обычная сборка, тяжёлые тесты, выпуск релиза. Такой паспорт полезнее общего запроса «нам нужен сервер для двадцати разработчиков». Двадцать человек могут отправлять изменения по очереди, а могут дружно завершить работу за пять минут до демонстрации.

Ядра внутри задания и задания между собой

У параллелизма есть два уровня. Первый — сколько работ одновременно запускает CI. Второй — сколько потоков создаёт каждая работа. Если разрешить десять сборок и каждой предложить использовать все доступные процессоры, получится не увеличение мощности, а соревнование за одни и те же ресурсы.

У GitLab Runner параметр concurrent ограничивает общее число одновременно выполняемых заданий, а limit может ограничивать конкретный runner. Параметр request_concurrency относится к одновременным запросам новых заданий и не заменяет лимит исполнения. Эти различия объясняет официальная документация GitLab Runner.

Условный начальный расчёт можно сделать так: определить доступную для сборок память после расходов системы и служб, затем разделить её на измеренный пик одного задания. Получится верхняя оценка по памяти. Её ещё нужно ограничить процессором, диском и допустимой длительностью работ. Если оценки разных ресурсов дают разные числа, безопасный старт определяет более тесное ограничение.

Например, если после служебных расходов вы сознательно оставили заданиям 48 ГБ, а типичная тяжёлая работа потребляет до 10 ГБ, пять таких работ одновременно уже не помещаются в заданный бюджет. Это учебный пример арифметики, а не готовая настройка для любого проекта. В действительности нужен запас на изменчивость потребления и дочерние процессы.

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

Какую машину взять под собственную сборочную ферму

ТарифЯдраПамятьНакопителиАренда в месяц
ANKH6, Ryzen 7600X64 ГБ DDR51 ТБ NVMe$329
PYLON16, Ryzen 7950X64 ГБ DDR51 ТБ NVMe$429
NECROPOLIS48, EPYC 7642128 ГБ DDR42 × 1 ТБ NVMe$529
CARTOUCHE, Россия28, два E5-2680 v4128 ГБ DDR42 × 600 ГБ SSD$295

Первые три конфигурации расположены в США. Цены и комплектации взяты из рассматриваемого прайса, без предположений о включённых лицензиях и сопровождении.

ANKH уместен как кандидат для небольшой очереди и умеренного числа тяжёлых запусков. PYLON за дополнительные $100 даёт больше ядер при том же объёме RAM. Это интересный переход, когда компиляция и независимые тесты действительно способны использовать процессор, а память пока не ограничивает параллельность.

NECROPOLIS предлагает уже 128 ГБ и 48 ядер. Его стоит проверять на большом потоке независимых работ, особенно если 64 ГБ мешают запускать нужное число окружений. Но отдельно взятая последовательная стадия может чувствовать себя лучше на другой процессорной платформе. Сравнение по сумме ядер не определяет длительность конкретного релиза.

CARTOUCHE позволяет рассмотреть размещение в России и вместительную ферму на более старых Xeon. Он особенно интересен как вариант консолидации задач, которым важнее общая ёмкость, чем рекорд одного потока. Проверять нужно сами сборки и скорость обмена с вашими репозиториями. Страна сервера не гарантирует близость к каждому реестру пакетов: зависимости могут приходить из разных мест.

Если контур уже работает на VPS, сначала сравните новый тариф с его реальной стоимостью и ожиданием в очереди. Универсальной точки окупаемости без этих данных нет. Отдельные ориентиры по устройству среды есть в статье о ресурсах VPS для разработчика и CI/CD.

Кэш экономит минуты, но требует порядка

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

Продумайте связь ключа с файлом зависимостей, версией инструментария, архитектурой и параметрами сборки. Разделяйте доверенные ветки и внешние изменения там, где содержимое кэша может влиять на результат. Кэш ускоряет работу, но не должен становиться скрытым источником невоспроизводимости.

Артефакты имеют другую роль. Это результаты, которые нужно передать дальше или сохранить: пакет, отчёт тестов, образ, отладочные символы. У них должны быть владелец и срок хранения. Не стоит надеяться, что папка исполнителя сама со временем разберётся, какие файлы важны. Она скорее закончит свободное место в самый торжественный момент релиза.

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

У NECROPOLIS два накопителя допускают разные схемы использования, но сами по себе не означают готового RAID. Зеркало уменьшает доступную ёмкость относительно суммы дисков. Отдельный диск под временную работу может снизить конкуренцию, но не гарантирует прироста без измерений. Выбирайте схему под задачу и учитывайте, какие данные можно быстро получить заново.

Исполнитель получает код, а вместе с ним полномочия

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

Внутренний релизный конвейер, изменения от внешних участников и экспериментальные ветки не обязаны иметь одинаковый доступ к секретам и сети. Учётные данные публикации выдавайте только тем этапам, которым они нужны. У временных ключей должен быть ограниченный срок и узкие права. Журналы проверяйте на случайное раскрытие переменных и токенов.

Привилегированный контейнер и доступ к сокету Docker могут предоставить заданию значительно больше контроля над хостом, чем ожидает автор конвейера. GitLab отдельно описывает риски privileged-режима в документации Docker executor. Для недоверенного кода разумнее использовать изолированные, по возможности одноразовые окружения с подходящей границей безопасности.

Контроллер Jenkins и исполнители тоже выполняют разные роли. Контроллер хранит конфигурацию и управляет работой; сборки лучше передавать агентам. Рекомендации по изоляции контроллера собраны в руководстве Jenkins. Покупка одного большого сервера не обязывает запускать на его основной системе всё без разделения.

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

Проверка фермы выглядит как обычный рабочий день

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

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

Добавьте к тесту скачивание и отправку реальных по размеру артефактов. Канал 1 Гбит/с описывает подключение сервера, а весь маршрут зависит также от противоположной стороны. Обозначение UNLIMITED не обещает, что внешний реестр будет отдавать данные с той же скоростью.

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

В результате у вас появится понятное решение. PYLON подходит для проверки вычислительно насыщенного конвейера, NECROPOLIS — для большого числа независимых работ с высоким расходом памяти, ANKH — для умеренной фермы, CARTOUCHE — для сценария с российским размещением и приемлемой скоростью старой платформы. Выбор подтверждает количество полезно завершённых работ и время до результата.

Хорошая сборочная ферма не обязана всё время показывать сто процентов загрузки. Её задача — возвращать разработчику ответ тогда, когда он ещё помнит, зачем изменил ту самую строку.

Подберите конфигурацию для своего проекта

Характеристики, стоимость и условия подготовки выделенных серверов MAATRIX в России и США.

Сравнить конфигурации в США

Все материалы о выделенных серверах

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →