Непрерывная интеграция (Continuous Integration, CI) и непрерывная поставка (Continuous Delivery/Deployment, CD) — это культура, набор принципов и практик, позволяющих разработчикам чаще и надежнее развертывать изменения программного обеспечения. CI/CD — одна из DevOps-практик, относящаяся к практикам автоматизации развертывания. Она позволяет разработчикам сосредоточиться на реализации бизнес-требований, качестве кода и безопасности.
Определение CI/CD
Непрерывная интеграция (CI) — методология разработки и набор практик, при которых в код вносятся небольшие изменения с частыми коммитами. Поскольку большинство современных приложений разрабатываются с использованием различных платформ и инструментов, появляется необходимость в механизме интеграции и тестирования вносимых изменений. С технической точки зрения, цель CI — обеспечить последовательный и автоматизированный способ сборки, упаковки и тестирования приложений. При налаженном процессе непрерывной интеграции разработчики с большей вероятностью будут делать частые коммиты, что будет способствовать улучшению коммуникации и повышению качества программного обеспечения.
Непрерывная поставка (CD) начинается там, где заканчивается непрерывная интеграция. Она автоматизирует развертывание приложений в различные окружения (production, разработка, тестирование). Инструменты CD помогают настраивать специфические параметры окружения, конфигурируемые при развертывании, а также автоматизируют необходимые запросы к веб-серверам, базам данных и другим сервисам, которые могут нуждаться в перезапуске или выполнении дополнительных действий при развертывании приложений.
Непрерывное тестирование и его роль в CI/CD
Непрерывная интеграция и непрерывная поставка нуждаются в непрерывном тестировании, поскольку конечная цель — разработка качественных приложений. Непрерывное тестирование часто реализуется в виде набора различных автоматизированных тестов: юнит-тестов, тестов производительности и других, которые выполняются на CI/CD-конвейере. Зрелая практика CI/CD позволяет реализовать непрерывное развертывание: при успешном прохождении кода через CI/CD-конвейер сборки автоматически развертываются в production-окружении. Команда, практикующая непрерывную поставку, может позволить себе ежедневное или даже ежечасное развертывание. Однако стоит отметить, что непрерывная поставка подходит не для всех бизнес-приложений.
Улучшение коммуникации и качества кода с помощью CI
Непрерывная интеграция — методология разработки, основанная на регламентированных процессах и автоматизации. При внедрении CI разработчики часто коммитят свой код в репозиторий исходного кода. Большинство команд придерживается правила коммитить как минимум один раз в день. В небольших изменениях проще выявлять дефекты и различные проблемы, чем при больших изменениях, над которыми работали в течение длительного периода времени. Кроме того, работа с короткими циклами коммитов уменьшает вероятность изменения одной и той же части кода несколькими разработчиками, что может привести к конфликтам при слиянии.
Команды, внедряющие непрерывную интеграцию, часто начинают с настройки системы контроля версий и определения порядка работы. Несмотря на то, что коммиты делаются часто, реализация фич и исправление багов могут выполняться довольно долго. Для контроля того, какие фичи и код готовы, существуют несколько подходов:
- Фича-флаги: механизм для включения и выключения функционала. Функционал, находящийся в стадии разработки, оборачивается фича-флагами и разворачивается из мастер-ветки в продакшн, но отключается до полной готовности. По данным недавнего исследования, 63% команд, использующих фича-флаги, отмечают улучшение тестируемости и повышение качества программного обеспечения. Для работы с фича-флагами существуют специальные инструменты, такие как LaunchDarkly, Optimizely Rollouts & Feature Flags.
- Ветвление в системе контроля версий: необходимо определить модель ветвления (например, Gitflow) и описать, как код попадает в ветки разработки, тестирования или продакшна. Для фич с длительным циклом разработки создаются отдельные фич-ветки. После завершения работы над фичей разработчики сливают изменения из фич-ветки в основную ветку разработки. Этот подход работает хорошо, но может быть неудобен при одновременной разработке большого количества фич.
Этап сборки в CI/CD
Этап сборки автоматизирует упаковку необходимого программного обеспечения, базы данных и других компонентов. Например, для Java-приложения CI упакует все статические файлы (HTML, CSS или JavaScript) вместе с Java-приложением и скриптами базы данных. CI не только упакует все компоненты, но и автоматически выполнит модульные тесты и другие виды тестирования. Это позволяет разработчикам получить обратную связь о том, что сделанные изменения ничего не сломали. Большинство CI/CD-инструментов позволяет запускать сборку вручную, по коммиту или по расписанию. Командам необходимо обсудить подходящее расписание сборки, учитывая численность команды, ожидаемое количество ежедневных коммитов и другие критерии. Важно, чтобы коммиты и сборка были быстрыми, иначе долгая сборка может препятствовать частым коммитам разработчиков.
Автоматизация поставки изменений в CI/CD-конвейере
Непрерывная поставка — это автоматическое развертывание приложения в целевое окружение. Разработчики обычно работают с одним или несколькими окружениями разработки и тестирования, где приложения разворачиваются для тестирования и review. Для этого используются CI/CD-инструменты, такие как Jenkins, GitLab CI, CircleCI, Azure DevOps, TeamCity и Travis CI.
Типичный CI/CD-конвейер состоит из этапов сборки, тестирования и развертывания. Более сложные конвейеры включают:
- Получение кода из системы контроля версий и выполнение сборки.
- Автоматизированная настройка инфраструктуры через подход «инфраструктура как код.
- Копирование кода в целевую среду.
- Настройка переменных окружения для целевой среды.
- Развертывание компонентов приложения (веб-серверы, API-сервисы и базы данных).
- Выполнение дополнительных действий (перезапуск сервисов, вызов сервисов, необходимых для работы новых изменений).
- Выполнение тестов и откат изменений в случае провала тестов.
- Логирование и отправка оповещений о состоянии поставки.
Например, в Jenkins конвейер определяется в Jenkinsfile, где описываются этапы (сборка, тестирование, развертывание), переменные окружения, секретные ключи и сертификаты, и другие параметры. В разделе post настраивается обработка ошибок. В более сложных конвейерах могут быть дополнительные этапы (синхронизация данных, архивирование, установка обновлений и патчей).
CI/CD-инструменты обычно поддерживают плагины. Jenkins, например, имеет более полутора тысяч плагинов для интеграции со сторонними платформами, расширения пользовательского интерфейса, администрирования, управления исходным кодом и сборкой.
При использовании CI/CD-инструментов разработчики должны убедиться, что все параметры сконфигурированы вне приложения через переменные окружения. CI/CD-инструменты позволяют устанавливать значения этих переменных, маскировать пароли и ключи, а также настраивать их для конкретного окружения. Также в CI/CD-инструментах присутствуют дашборды и отчетность, оповещающие о сбоях сборки или поставки. Интеграция CI/CD с системой контроля версий и DevOps-инструментами облегчает поиск изменений кода и пользовательских историй, вошедших в сборку.
Реализация CI/CD-конвейеров с Kubernetes и безсерверными архитектурами
Многие команды, использующие CI/CD-конвейеры в облаках, используют контейнеры (Docker) и системы регистрации (Docker Registry). Контейнеры позволяют стандартизировать упаковку, поставку и упростить масштабирование и уничтожение окружения с непостоянной нагрузкой. Существует множество вариантов совместного использования контейнеров, инфраструктуры как код и CI/CD-конвейеров.
Архитектура безсерверных вычислений — ещё один способ развертывания и масштабирования приложений. В безсерверном окружении инфраструктурой полностью управляет поставщик облачных услуг, а приложение потребляет ресурсы по мере необходимости. Например, в AWS безсерверное приложение запускается через функции AWS Lambda, развертывание которых может быть интегрировано в CI/CD-конвейер Jenkins с помощью плагина.
Итоги
CI/CD упаковывает, тестирует, собирает и оповещает разработчиков о проблемах. CI/CD автоматически разворачивает приложение и выполняет дополнительные тесты. CI/CD-конвейеры предназначены для организаций, которым необходимо часто вносить изменения в приложение с надежным процессом поставки. Внедрение CI/CD позволяет разработчикам сосредоточиться на улучшении приложений, а не на их развертывании.
CI/CD — одна из DevOps-практик, направленная на решение противоречий между разработчиками (часто вносящими изменения) и эксплуатацией (требующей стабильности). Автоматизация позволяет разработчикам чаще вносить изменения, а команда эксплуатации получает большую стабильность благодаря стандартизированным конфигурациям окружений и непрерывному тестированию. Настройка переменных окружения отделена от приложения, и присутствует автоматизированная процедура отката.
Эффект от внедрения CI/CD-конвейера можно измерить с помощью ключевых показателей эффективности (KPIs):
- Частота поставки.
- Lead time (время реализации изменений).
- Среднее время восстановления после инцидента (MTTR).
Эти показатели часто улучшаются при внедрении CI/CD с непрерывным тестированием.
Для начала работы с CI/CD команде разработчиков и эксплуатации необходимо совместно определиться с технологиями, практиками и приоритетами. Команды должны выработать консенсус в отношении подходов к бизнесу и технологиям для постоянного соблюдения выбранных практик после внедрения CI/CD.