CI pipeline speed — до/после AD-570 + вклад раннера buildbox
Тикет: AD-596 · Период данных: 2026-07-15 … 2026-07-18
Источник: GitLab pipelines API проекта 81171473 (agadron/aero-forge), ветка develop и MR-пайплайны.
Выборка: 258 develop-пайплайнов + 315 MR-пайплайнов; per-job тайминги и раннеры из /pipelines/{id}/jobs.
Числа — из реальных пайплайнов (медианы, не оценки). Метрики:
durationджобы = чистое время
выполнения;queued_duration= ожидание раннера; wall-clock пайплайна =finished_at − created_at.
0. Точки отсчёта (мержи в develop)
| Изменение | Тикет | Мерж в develop (UTC) |
|---|---|---|
| Скорость: ci-base в registry, DAG-needs, compileall, pytest-xdist | AD-570 | 2026-07-16 20:22 |
| Interruptible (устаревший цикл гасится) | AD-568 | 2026-07-16 20:32 |
| Шаблоны джоб (include: local) | AD-567 | 2026-07-16 21:00 |
| build-once/deploy-many через локальный registry | AD-526 | 2026-07-16 22:04 |
| Второй раннер buildbox + registry (IaC) | AD-569 | 2026-07-16 22:12 |
| ci-base хэш-тег против стухшего кэша | AD-599 | 2026-07-16 23:02 |
| JS-юнит-тесты в пайплайне (node в ci-base) | AD-624 | 2026-07-17 15:31 |
Фазы анализа: A — до AD-570 (baseline); B — только AD-570 (до registry-нагрузки на build-images);
C — после registry (AD-526); D — steady-state после JS-тестов (AD-624).
1. Итог одной строкой
- AD-570 сделал ровно то, на что был нацелен:
build84.5 → 6.3 с (×13),test142 → 48–52 с (×2.7–3.7)
за счёт ci-base (предустановленные зависимости,pip installбольше не гоняется) +compileall+pytest-xdist. - MR-пайплайн ускорился втрое: медиана wall-clock 243 → 72 с (−70 %).
- Но стенка develop-пайплайна упала слабее, чем джобы: узкое место сместилось с
testна
build-images+scan, которые крутятся на единственном shell-раннере nas и в DAG стоят на
критическом пути.build-imagesвдобавок вырос 81 → 187 с из-за пуша в registry (AD-526). - buildbox дал реальную кросс-пайплайновую параллельность для
build/test(86 одновременных запусков
на двух docker-раннерах; очередь build/test в ночной серии ≈1–2 с). Ноbuild/testбольше не на
критическом пути, поэтому на end-to-end время buildbox влияет ограниченно. - Ночной затык — не resource_group deploy (ожидание ~2 с), а один shell-раннер: он последовательно
прогоняетbuild-images→scan→deploy→healthcheck, и следующий пайплайн ждёт на первой же джобе
(ci-base-tag). В ночь 15 из 44 пайплайнов ждали раннер >60 с (макс 9.6 мин), суммарно 67 мин очереди.
2. Develop: стенка пайплайна (wall-clock, только успешные с деплоем)
| Фаза | Окно | n | Медиана | p25 | p75 | Изм. к baseline |
|---|---|---|---|---|---|---|
| A baseline (до AD-570) | 07-15 … 07-16 20:22 | 143 | 369.6 с (~6.2 мин) | 122.6 | 441.8 | — |
| B только AD-570 | 20:22 … 22:04 | 17 | 258.2 с (~4.3 мин) | 200.5 | 304.7 | −30 % |
| C + registry (AD-526) | 22:04 … 07-17 15:31 | 21 | 306.0 с (~5.1 мин) | 258.6 | 388.1 | −17 % |
| D steady-state (+JS-тесты) | 07-17 15:31 … | 44 | 346.3 с (~5.8 мин) | 322.3 | 467.9 | −6 % |
Максимум лучшего результата дал момент B (сразу после AD-570, до того как build-images потяжелел от
пуша в registry). Далее часть выигрыша «съели» registry-push в build-images (AD-526) и JS-тесты в test (AD-624).
3. Разбивка по джобам (develop, медиана duration, с)
| Джоба | Раннер | A: до AD-570 | B: AD-570 | D: steady-state | Что изменилось |
|---|---|---|---|---|---|
ci-base-tag |
shell-nas | — | — | 4.5 | AD-599: sha256 файлов зависимостей → хэш-тег (dotenv) |
build |
docker (nas/bbox) | 84.5 | 6.2 | 6.3 | ×13 — ci-base (deps готовы) + compileall один процесс |
test |
docker (nas/bbox) | 142.4 | 38.6 | 52.0 | ×2.7 — pytest-xdist + ci-base; +JS-тесты (AD-624) добавили ~13 с |
build-images |
shell-nas | 80.8 | 79.1 | 186.9 | ×2.3 медленнее — пуш прод-образов в registry (AD-526) |
scan |
shell-nas | 62.8 | 61.9 | 71.2 | без изменений (Trivy-гейт, AD-487) |
deploy |
shell-nas | 19.6 | 10.3 | 10.4 | ×1.9 быстрее — --no-build (образы уже собраны, AD-487) |
healthcheck |
shell-nas | 3.4 | 3.4 | 3.4 | без изменений |
Критический путь после AD-570 (DAG-needs)
ci-base-tag(4.5) → build(6.3) → ┬ test(52) ────────────────┐
└ build-images(187) → scan(71) ┘ → deploy(10) → healthcheck(3.4)
└────────── 258 с ──────────┘
критический путь ≈ 4.5 + 6.3 + max(52, 258) + 10 + 3.4 ≈ 282 с
test (52 с) заканчивается задолго до build-images+scan (258 с). Узкое место — build-images+scan
на единственном shell-раннере, а не то, что ускорял AD-570, и не то, что параллелит buildbox.
4. MR-пайплайны: до/после AD-570
| Метрика | до AD-570 | после AD-570 | Изм. |
|---|---|---|---|
| wall-clock (медиана) | 243.4 с (~4.1 мин) | 71.9 с (~1.2 мин) | −70 % / ×3.4 |
| wall-clock p25 | 216.7 | 59.4 | |
build (медиана) |
84.3 с | 6.3 с | ×13 |
test (медиана) |
138.8 с | 48.3 с | ×2.9 |
Хвост p75=218 с — пайплайны, где менялись requirements*/Dockerfile.ci и пересобирался ci-base
(джоба ci-base на shell-раннере). Целевые ~40 с достигаются, когда зависимости не менялись
(критический путь build+test ≈ 55 с + очередь).
5. Вклад раннера buildbox (AD-569)
Два docker-раннера обслуживают build/test (tag docker-build): docker-nas (tartarus) и
buildbox (andrey-ms7e06, 16c/32G). Все остальные джобы (ci-base*, build-images, scan, deploy,
healthcheck) — на одном shell-раннере nas (buildbox их не берёт).
Доля джоб на buildbox (после выхода buildbox в 22:12 07-16):
| Пайплайн | build (nas / buildbox) |
test (nas / buildbox) |
|---|---|---|
| develop | 64 % / 36 % | 61 % / 39 % |
| MR | 51 % / 49 % | 42 % / 58 % |
- 86 случаев, когда
build/testшли на nas-docker и buildbox одновременно — подтверждённая
кросс-пайплайновая параллельность. Раннер удвоил docker-ёмкость. - В ночной серии (44 пайплайна за 6 ч) очередь
build/testосталась ~1.0–1.4 с — без buildbox эти
джобы вставали бы в очередь к единственному docker-раннеру. - Загрузка раннеров в ночь: shell-nas 49 %, nas-docker 7 %, buildbox 6 %. То есть у docker-раннеров
(в т.ч. buildbox) огромный запас, а упирается всё в shell-раннер.
Вывод: buildbox устранил очередь на build/test, но так как они уже не на критическом пути,
на время релиза он влияет мало. Его потенциал (docker + доступ к registry, простаивает на 94 %) стоит
направить на build-images/scan.
6. Ночная загрузка (07-17 20:00 … 07-18 02:00, 44 пайплайна)
Серия ~18 мержей в develop за ~2 часа (21:11 → 22:57) — «поезд» релизов.
| Что | Значение |
|---|---|
| Пайплайнов в окне | 44 (34 success, 8 canceled interruptible, 1 failed, 1 running) |
Ожидание deploy resource_group production |
медиана 1.7 с, макс 12.2 с, >30 с: 0, суммарно 1.1 мин |
Ожидание раннера (первая джоба ci-base-tag, shell) |
медиана 2.7 с, p75 183 с, макс 576 с (9.6 мин) |
| Пайплайнов, ждавших раннер >60 с | 15 из 44 (>120 с: 13; >300 с: 4) |
| Суммарная очередь за раннером | 67 мин за ночь |
| Загрузка shell-раннера | 49 %, из них build-images = 115 мин (65 %) |
Deploy-сериализация (resource_group) НЕ тормозит релиз — deploy быстрый (~10 с), ожидания почти нет.
Тормозит единственный shell-раннер: пока он гонит build-images(187 с)+scan(71 с)+deploy+healthcheck
предыдущего пайплайна, следующий стоит на ci-base-tag. Отсюда очередь до 9.6 мин — при том, что buildbox
и nas-docker простаивают на >90 %.
7. Interruptible (AD-568)
- После включения (07-16 20:32) 15 устаревших develop-циклов автоматически погашены новым коммитом.
- Гасятся рано (interruptible на
ci-base-tag/ci-base/build): все 15 суммарно съели лишь 6.9 мин
раннер-времени (≈0.5 мин на пайплайн вместо полного цикла ~5 мин). - Экономия ≈ 15 × (build-images 187 + scan 71 + deploy 10) ≈ 67 мин shell-раннер-времени, которое иначе
ушло бы на заведомо устаревшие сборки образов и деплои. Плюс — 15 лишних прод-деплоев не случилось. - MR-пайплайнов interruptible за период не отменял (0) — MR-циклы короткие.
8. Рекомендации (по влиянию на скорость)
-
[Высокий] Снять
build-imagesс критического пути — это главный затык сейчас.
Два направления, дополняющие друг друга:
- build-once/deploy-many по факту (AD-526):build-images
сейчас каждый мерж пересобирает иaero-web, иcad(187 с медиана). Тянуть готовый образ по
tree-hash сабдерева сервиса, если оно не менялось → чаще всегоbuild-imagesсхлопывается почти в ноль.
- Разнестиbuild-images/scanна buildbox (docker + доступ к registry, простой 94 %). Сейчас они
привязаны к shell-раннеру nas вместе сdeploy; на nas должны остаться толькоdeploy/healthcheck
(пишут в/opt/cortex). Это убирает и ночную очередьci-base-tag. -
[Средний] Параллелить
build-imagesпо сервисам (aero-web‖cad) на двух раннерах — режет самую
тяжёлую джобу критического пути вдвое. -
[Низкий] resource_group ordering (AD-601): по данным ночи
ожидание deploy ~2 с — сейчас не узкое место. Смена наnewest_firstполезна как страховка на будущее
(когда деплои начнут наслаиваться), но приоритет ниже пунктов 1–2. -
[Отдельно, не про скорость] Zero-downtime (AD-571):
--force-recreateдаёт ~5 с недоступности прода на каждый мерж — вопрос надёжности, не скорости пайплайна;
держать отдельным reliability-треком.
Приложение: методология
- Пайплайны:
GET /projects/81171473/pipelines?ref=develop&updated_after=2026-07-15T00:00:00Z(+пагинация),
MR — тот же запрос сsource=merge_request_event. - По каждому:
GET /pipelines/{id}(duration,queued_duration,created_at,started_at,finished_at,
status) иGET /pipelines/{id}/jobs(по стадиям:duration,queued_duration,runner.description). - Раннеры:
docker-nas (tartarus)иbuildbox (andrey-ms7e06, 16c/32G)— docker (build/test);
пустойdescription— shell-раннер nas (ci-base*/build-images/scan/deploy/healthcheck). - Токен GitLab взят из
git remote get-url origin(в отчёте/логах не печатался).