Что такое CI/CD
CI/CD (Continuous Integration, Continuous Delivery, Continuous Deployment) — это непрерывная интеграция и поставка. С термином сталкиваются IT-специалисты из разных сфер:
- frontend,
- backend,
- тестировщики и инженеры по качеству,
- DevOps,
- продакт-менеджеры,
- бизнес-аналитики или системные аналитики.
CI/CD — это подход, в рамках которого процесс разработки выстраивается так, чтобы можно было регулярно добавлять в проект код с необходимой функциональностью и автоматически собирать, тестировать и развертывать.
Такая методология разработки пришла на смену существовавшим ранее: императивным, структурным, модульным.
Как процесс от «задачи в работу» до «новой версии для пользователя» происходил раньше (опишем условно, на самом деле работы гораздо больше — миграции, настройка переменных окружения):
- Разработчики вручную писали и добавляли в ветку код.
- Руками запускали тесты.
- Разворачивали вручную на сервере.
Релизы были крупнее и трудозатратнее. Соответственно, реже.
Благодаря CI/CD ничего не нужно делать вручную. Процесс сборки, тестирования и развертывания на разном окружении автоматизирован.
Создается так называемый пайплайн (pipeline) — конвейер из нескольких этапов, которые выполняются один за другим.
Упрощенно непрерывную интеграцию и доставку можно сравнить с заказом в интернет-магазине:
- Пользователь делает заказ. В интернет-магазине начинается этап Continuous Integration: собирают, комплектуют и упаковывают товар, проверяют остатки.
- Заказ приходит в пункт самовывоза. На стадии Continuous Delivery товар доставлен.
- Покупатель разворачивает упаковку. Начинается этап Continuous Deployment: товар доставлен и развернут, пользователь проверяет его и оставляет отзыв.
Можно настроить пайплайн таким образом, что при пуше (git push) кода в определенную ветку автоматически триггерится процесс сборки приложения. В случае успеха он запускает тесты. Если они прошли, продукт разворачивается на определенном окружении, а иногда — сразу доставляется пользователю. Напомним, что чаще всего используются окружение разработчика (dev, development), тестирования и инсценирования (staging, stage) и пользовательское (production, prod, live).
Чем отличается Continuous Delivery от Continuous Deployment?
При Continuous Delivery («доставка») этап выкатки кода на продуктовую среду (конечным пользователям) происходит только после подтверждения человеком. Например, релиз-инженером. Часто этот способ называют «доставкой по кнопке». Чтобы новый релиз ушел на продуктовую среду, разработчик должен запустить этот процесс. Буквально — нажать на кнопку.
Continuous Deployment («развертывание», «деплой», «деплоймент») подразумевает автоматический пайплайн. Разработчик запушил код в репозиторий — и через некоторое время новая функциональность уже доставлена конечному пользователю.
Основные отличия:
- continuous integration — разработка в отдельных ветках; после нее изменения вливаются в основную (центральный репозиторий). Сборка и тестирование запускаются автоматически;
- continuous delivery — процесс CI автоматизирован, как и процесс сборки и развертывания релиза в различных окружениях. Деплой в прод происходит вручную;
- continuous deployment — автоматизировано все: CI, сборка релиза и деплой в продакшен.
По сути, эти процессы можно представить как матрешку: чтобы доставить продукт пользователям, нужно для начала его собрать и протестировать.
Принципы работы CI/CD
Разделение зон ответственности по разным командам и людям. Аналитики отвечают за планирование, разработчики — за код, QA-инженеры — за качество продукта, DevOps — за логистику программного кода и мониторинг системы. Ответственность можно декомпозировать на каждом этапе и в каждой зоне.
Снижение рисков. Каждый участник процесса должен минимизировать возможные риски при прохождении продукта через этапы жизненного цикла.
Короткий цикл обратной связи. Автоматизация позволяет быстро реагировать на ошибки или запросы новой функциональности.
Единая реализация среды. У программиста должно быть единое пространство, которое сопоставимо с продакшен-, dev- и тестовым окружением.
Этапы CI/CD
Стадии непрерывной интеграции и доставки часто изображают как петлю бесконечности. Ниже разберемся, что и как происходит на каждой стадии.
План. Задача поступает от менеджера проекта или тимлида.
Код. Разработчик пишет код, в котором реализует нужную функциональность.
Код отправляется в удаленный репозиторий на GitVerse или любой другой платформе (BitBucket, GitLab, GitHub). Разработчик создает новую ветку: fix/new-fix. Все эти изменения потенциально могут затронуть другой функционал и сломать продукт.
После того как разработчик пушит (git push) изменения, запускается автоматический конвейер CI и CD.
CI — непрерывная интеграция
Для чего нужен. Понять, что та функциональность, которую добавил разработчик, интегрируется в кодовую базу и не сломает продукт.
Цель. Обеспечить автоматизацию сборки, упаковки и тестирования.
Что происходит внутри:
Сборка проекта. У нас существует кодовая база + появились изменения: программист убрал баг, добавил функциональность. Значит, нужно пересобрать приложение. Создается новый Docker-образ (шаблон, хранящий все необходимое для запуска приложения), чтобы его можно было разворачивать на любых серверах и в любом количестве. Этот процесс занимает немного времени и не отлавливает никаких ошибок. В код могли прокрасться баги и критические уязвимости, которые разработчик не заметил. Нужна следующая стадия — тестирование.
Тестирование. На этой стадии проверяют линтеры, форматтеры, логику, наличие уязвимостей, безопасность, покрытие тестами, нет ли замечаний по стилю написания кода и т. д. Часто на эти проверки устанавливают гейты — процент разрешенных ошибок и несоответствий. Если возникают проблемы, то pull request или merge request (заявка на слияние в основную ветку) будет заблокирован: разработчик пойдет дорабатывать код. Затем снова код компилируется, запускаются автотесты (unit-тесты, интеграционные). Когда все в порядке, переходят на следующий этап.
Как правило, на крупных проектах под CI выделяют отдельный сервер. Обычно минимальные требования — 4vcpu / 16gb RAM. Подобрать сервер можно на Advanced Elastic Cloud Server от Cloud.ru. На платформе доступны готовые CI/СD-процессы для web-приложения: пользователи получают настроенные пайплайны для сборки frontend- и backend-части приложений. CI-сервер используется только для прогона сборок и тестов. В небольших компаниях отдельные CI-серверы могут и не использовать.
Чтобы этап CI имел смысл, тестирование build-версии должно занимать не больше 10 минут. В противном случае разработка затягивается.
Само приложение на этом этапе не разворачивается. Просто потому, что часто сложно разворачивать все приложение на каждую fix-ветку. Представьте, что в команде 15 backend-разработчиков, каждый создает по несколько merge request. Получается, что в таком случае нужно разворачивать по 20 дополнительных приложений. Это ресурсозатратно. Но могут быть и другие варианты. Например, Иван задеплоил версию А, Петр задеплоил версию В, которая ломает код Ивана. В результате Иван тестировал сломанную версию. Чтобы такой ситуации не было, приходится договариваться. Иван пишет Петру: «Забираю dev.stage на 45 минут».
Как только сливается код с ветки fix (которую запушил разработчик) с веткой dev, запускается процесс CI / CD. Проверенный на этапе CI build разворачивают и доставляют конечному пользователю. Это происходит в пару кликов или вообще автоматически.
CD — непрерывная доставка и развертывание
Для чего нужен. Доставить релизную версию конечному пользователю и участникам команды.
Цель CD. Автоматизировать развертывание приложения в разные окружения.
Для разворачивания используются ветки dev и main. После того как разработчик отправил (запушил) изменения в ветку, она сливается с веткой dev (тестовым контуром / тестовым сайтом). На dev нет реальных пользователей. Тестовый контур нужен в работе тестировщиков, программистов, продуктовых менеджеров, бизнес-аналитиков. Например, часто все приложения, которые развернуты на тестовом сайте, доступны только с VPN и только сотрудникам компании.
В CD есть 2 этапа:
- Релиз. Стабильная версия проекта, которую могут использовать разработчики (она называется релиз-кандидатом).
- Развертывание (деплой). Релизную ветку загружают и разворачивают на продакшен-сервере клиента: старая версия сайта заменена на новую.
Когда команда работает над проектом, появляются десятки версий. Релизная же протестирована QA-инженерами, проверена frontend- и backend-разработчиками. Эта версия (файл, Docker-образ) разворачивается для всех пользователей программного продукта.
Docker-образы хранятся в специальном месте — Registry. Здесь можно найти старые релизные образы. Они пригодятся, если после разворачивания новой версии становится ясно, что ошибок очень много, невозможно поддерживать и использовать обновленное приложение. Разработчики «откатываются» на старую релизную версию, которую можно достать из хранилища Registry.
Таким образом, CD — DevOps-практика развертывания кода после проверки его успешной интеграции. «Доставка» функциональности до конечного пользователя.
Поддержка и мониторинг — стадия, на которой разработчики следят за развернутой версией продукта и в случае проблем стабилизируют ее и устраняют ошибки. Затем снова приступают к планированию, и весь процесс начинается заново.
Преимущества
Повышение надежности разработки. Найти ошибки в небольшом куске кода проще, чем в написанном за 3 месяца на 100 000 строк. Это позволяет сделать релизы более стабильными.
Ускорение времени разработки, тестирования, доставки конечным пользователям. Развертывание в прод возможно хоть каждый день или каждый час. Правда, такой вариант подходит не всем приложениям и программным продуктам.
Инструменты для CI/CD
В вакансиях наниматели часто указывают, что на позицию IT-специалиста нужно:
- понимать DevOps lifecycle (жизненный цикл DevOps) и основные концепции (СI/CD, CM, IaC);
- уметь работать с определенными инструментами — например, Jenkins declarative pipelines, GitVerse CI/CD, GitHub и GitHub Actions и/или с GitLab Ci;
- создавать пайплайны Jenkins, плейбуки Ansible, docker-файлы.
В зависимости от проекта могут использовать:
- Jenkins,
- CircleCD,
- GitVerse CI/CD,
- AWS CodeBuild,
- Azure DevOps,
- Atlassian Bamboo,
- Travis CI.
Как настроить CI/CD на проекте
GitVerse CI/CD — это система непрерывной интеграции и непрерывной поставки. Она встроена в отечественную платформу для автоматизации задач:
- тестирования,
- сборки,
- развертывания.
GitVerse Actions и вебхуки позволяют настроить CI/CD: например, пулл-реквест запускает пайплайн, проект собирается, тестируется и деплоится.
Создание workflow — файла рабочего процесса
В workflow — файле рабочего процесса — прописывают конфигурацию и последовательность задач, которые должны быть выполнены в рамках GitVerse Actions (CI/CD). Например, можно указать, что при каждом коммите в репозиторий будет запускаться задача сборки и тестирования кода.
Файл рабочего процесса написан на YAML и может располагаться в .gitverse/workflows или .github/workflows.
В примере кода:
- name — конфигурация CI/CD;
- on — события, на которые реагирует CI/CD;
- push — пример события-триггера (push в ветку);
- jobs — список задач (джобов), которые нужно выполнить.
build-test:
- name: Test context — название задачи для выполнения;
- runs-on: ubuntu-latest — операционная система, на которой будет выполняться задача (последняя версия ubuntu);
- steps — список шагов в рамках задачи.
Каждый шаг имеет:
- name — название;
- run — команда для выполнения в рамках шага. Для нее используют переменные окружения GitVerse:gitverse.event_name, gitverse.workflow, gitverse.Repository, gitverse.repository_owner, gitverse.actor и прочие. Пошаговая инструкция, как настроить CI/CD на GiVerse представлена в базе знаний в разделе «Регистрация и запуск раннеров».
Список поддерживаемых событий (триггеров) включает:
- pull_request_sync — синхронизация пулл реквеста;
- pull_request — создание или обновление пулл реквеста;
- create — создание нового репозитория, ветки, тега;
- fork — создание форка репозитория и прочие.
Зарегистрировать и запустить раннер
Раннер — это программа, которая позволяет запускать GitVerse Actions. В нем инженер описывает необходимую последовательность команд. Они будут запускаться на Агенте. Это все те команды, которые обычно вводили руками: npm build, build-test, docker build, npm start. Теперь все делается автоматически.
Для настройки необходимо включить CI/CD в профиле репозитория (Настройки —> Репозиторий —> CI/CD —> Обновить).
Для регистрации раннера нужен регистрационный токен. Он доступен на странице настроек (https://gitverse.ru/<владелец>/<название-репозитория>/settings/runners)
Далее необходимо зарегистрировать раннер с полученным токеном. Это обязательно, так как в противном случае runner не будет знать, откуда брать задания.
Для интерактивной регистрации используется команда:
./act_runner register
Далее необходимо указать токен, имя раннера и метки.
Для неинтерактивной регистрации используют команду:
./act_runner register --no-interactive --token <registration_token> --name <runner_name>
Runner будет забирать задания с платформы GitVerse и выполнять их только после запуска. Для этого необходима команда:
./act_runner daemon
Активность раннера отображается на странице CI/CD.
Таким образом, на сервере настраивается определенный сервис — агент (раннер): например, существуют GitLabRunner, Jenkins Agent. Раннер подключен к CI-системе и получает от нее задания.
Отечественная платформа поддерживает настройку CI/CD в разрезе:
- работы с Docker;
- бинарных раннеров;
- работы с сервисом cloud.ru (доступно после создания виртуальной машины).
Чтобы окружение, в котором разработчик собирает фронтенд, бэкенд и тесты, всегда было одинаковым и свежим (без следов других сборок), используют отдельные контейнеры. Когда контейнеров становится много, их нужно оркестрировать: автоматически управлять запуском на кластере из нескольких серверов.
В таком случае в раннере прописывают команду «поднять контейнер из определенного образа», а затем все команды выполняются уже внутри изолированного окружения.