ADG Оставить заявку
Блог DevOps 5 мин чтения

Migrated с GitLab CI на Gitflic CI + Werf 2: что сломалось, что дописали, как держит нагрузку

Перенесли последний pipeline с GitLab CI на Gitflic CI и Werf 2.x. Рассказываем, где пришлось дописывать, чего не хватает и как инструмент ведёт себя при 50+ параллельных пайплайнах.

Контекст момента

Российские CI/CD-платформы Gitflic CI и Werf 2.x набирают корпоративные инсталляции в 2026

Миграция с GitLab CI на GitFlic CI у нас растянулась на несколько месяцев - не потому что сложно технически, а потому что мы двигались аккуратно: сначала некритичные репозитории, потом staging-пайплайны, и только в апреле - последний продовый pipeline. Сейчас всё на Gitflic CI + Werf 2.x, и можно говорить по делу.

Почему вообще двигались

Вопрос не стоит. Контур с требованиями по безопасности, корпоративные требования, реестры - всё это давно решили. Причина другая: GitLab Self-Managed у нас стал источником оперативной нагрузки, которую не хочется тащить. Gitflic CI в части инфраструктуры проще, и runner-агенты работают на нашей же платформе без лишних зависимостей.

Werf 2.x как инструмент сборки и деплоя в Kubernetes мы использовали поверх GitLab CI ещё год назад, так что Werf нам не новый. Новым был Gitflic CI как оркестратор.

Что из GitLab CI не перенеслось прямо

Needs и DAG-зависимости. В GitLab CI можно было через needs: строить произвольный граф стадий: job B запускается, как только готов job A, не дожидаясь остальных jobs той же стадии. В Gitflic CI на момент переноса - линейные стадии. Можно делать несколько стадий с параллельными jobs внутри, но needs:-граф с перекрёстными зависимостями не работает. Пришлось перестроить три pipeline, где была нетривиальная DAG-логика. Всё решаемо, но руки приложить надо.

Rules с complex conditions. rules: в GitLab CI - мощный инструмент: if, changes, exists, when в любых комбинациях. В Gitflic CI аналог есть, но выразительность меньше. Конкретно нам не хватило changes: с glob-паттернами - условный запуск job только при изменении файлов в определённых директориях. Написали небольшой скрипт-обёртку, который на первой стадии проверяет diff и выставляет переменные окружения, а дальнейшие стадии на них ориентируются. Некрасиво, но работает.

Environments и deployment tracking. В GitLab была интеграция Environments - можно было видеть, что задеплоено в какой кластер, откатывать из UI. Gitflic CI этого нет. Мы переложили эту функцию на Werf + ArgoCD: Werf деплоит через GitOps, видимость деплоев - в ArgoCD. В итоге даже удобнее, потому что у ArgoCD гранулярность лучше.

Где дописывали

Кэширование слоёв. Werf 2.x умеет кэшировать Docker-слои в registry - это работает хорошо. Но кэш зависимостей (npm node_modules, Python virtualenv, Go mod cache) нужно было организовать самим. В GitLab CI был встроенный cache с бэкендами S3/GCS. В Gitflic CI cache тоже есть, но в нашей конфигурации с self-hosted runner-ами он работал нестабильно - иногда не восстанавливался, иногда писался частично. В итоге переключились на явное хранение кэша в отдельном registry-артефакте через Werf, что оказалось надёжнее и прозрачнее.

Нотификации. GitLab CI имел встроенную интеграцию с Mattermost/Telegram через webhook. В Gitflic CI - через переменные окружения и кастомный job в конце pipeline. Написали общий .gitflic-ci-notify.yml как include-шаблон, который подключается во все репозитории через Gitflic CI Templates. Примерно час работы, теперь не думаем об этом.

Секреты. У нас Vault как хранилище секретов. В GitLab CI была нативная интеграция через secrets: блок. В Gitflic CI - нет. Решили через vault-agent sidecar в runner-поде: runner при запуске получает секреты из Vault через AppRole, кладёт в переменные окружения. Схема не уникальная, работает стабильно.

Как держит 50+ параллельных пайплайнов

Честный ответ - держит, но с оговорками.

Runner-агенты у нас Kubernetes executor - pods создаются по требованию. При пике в рабочие часы (а у нас две активные команды, которые пушат одновременно) число параллельных pods доходило до 60-70. Здесь выявилась проблема с resource requests: по умолчанию Gitflic runner-pod запрашивает скромные ресурсы, но реальное потребление при сборке Java-сервисов выше. Начали получать OOMKill. Решение стандартное - явные limits в runner config, но пришлось подобрать эмпирически.

Сам Gitflic CI под нагрузкой не падал. Очередь пайплайнов обрабатывается корректно, приоритизации нет (в GitLab CI тоже не было из коробки), но и заметного накопления очереди не видели.

Одна неприятность: при одновременном старте большого числа jobs Gitflic CI иногда медленно отвечает на запросы статуса от runner-агентов. Агент polling-ит статус раз в несколько секунд, и при высокой нагрузке этот polling давал таймауты, которые runner интерпретировал как ошибку. Пришлось увеличить timeout в конфигурации runner. Не критично, но неприятно - и судя по нашему обращению в поддержку, проблема известна.

Итог

Gitflic CI - рабочий инструмент, не игрушка. Основные сценарии покрыты. Но GitLab CI всё ещё богаче в деталях: DAG-зависимости, rules с conditions, Environments - всё это либо отсутствует, либо требует дописывания. Если pipeline простой - переход почти без трений. Если сложный - закладывайте время на адаптацию.

Werf 2.x в этой схеме - стабильная основа. Он делает то, что обещает: собирает, кэширует слои в registry, деплоит в Kubernetes через GitOps. Претензий к нему нет.

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

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.