En

JazzTeam Software Development Company

Agile Java Development

DevOps. Continuous Integration на примере Jenkins

В  данной статье будут изложены основные идеи Continuous Integration, а также приведен пример быстрого развёртывания Jenkins на проекте.

Термины и определения

Прежде чем приступать к основной части, необходимо дать определение используемых терминов.

Непрерывная интеграция (CI, Continuous Integration) — практика разработки программного обеспечения, которая заключается в слиянии рабочих копий в общую основную ветвь разработки несколько раз в день и выполнении частых автоматизированных сборок проекта для скорейшего выявления потенциальных дефектов и решения интеграционных проблем. [wiki]

Jenkins – проект для непрерывной интеграции с открытым исходным кодом, написанный на Java. [jenkins.io]

Автоматизированное тестирование – это процесс верификации программного обеспечения, при котором основные функции и шаги теста, такие как запуск, инициализация, выполнение, анализ и выдача результата, выполняются автоматически при помощи инструментов для автоматизированного тестирования. [protesting]

Немного о CI

В настоящее время Continuous Integration – одна из практик, применяемых в Agile методологии. В подобных методологиях она удачно сочетается с другими практиками, такими как unit тестирование, рефакторинг, стандарт кодирования. Но даже без них можно получить пользу от непрерывной интеграции. Из определения Continuous Integration следует его самая главная идея – найти ошибку на ранней стадии проще для разработки и дешевле для бизнеса. Поэтому, если в проект вносятся достаточно большие изменения, необходимо обязательно проводить тестирование (unit-тесты, автоматизированные тесты).

Стоит отметить, что режимов запусков может быть несколько:

Инструментов для CI существует достаточно много:

Jenkins

Почему стоит использовать именно Jenkins:

Из минусов отметил бы:

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

В случае возникновения кейса, описанного в примере выше, на TeamCity достаточно было указать версию java при запуске прогона.

Отдельно отмечу, что в данном случае Jenkins использовался исключительно для запуска автоматизированных тестов, т.к. они были достаточно длительными и требовали высокого уровня производительности.

Идеальный процесс разработки можно представить так:


Установка Jenkins

Про установку написано достаточно много и подробно, самый лучший мануал конечно от разработчиков – Installing Jenkins.

В свою очередь хочу поделиться своим опытом резервного копирования и последующей установкой из сохраненной копии.

Резервное копирование

Можно использовать встроенные плагины, но могут быть проблемы совместимости разных версий плагинов, поэтому для этой цели мы пришли к использованию bash скриптов которые входили в отдельную сборку, которая запускалась несколько раз в день\неделю. Например, скрипт jenkins-backup.sh – выполнял сохранение текущей рабочей конфигурации: view, job, настроек окружения, плагинов, которые сохранялись в отдельный архив, который можно переносить и использовать далее.

Установка из сохраненной копии

1.Необходимо установить java и инструмент архивации, в нашем случае unzip.

2. Разархивировать ранее сохранённый файл (предварительно перейдя в каталог с сохранным архивом):

unzip Jenkins.zip -d %path_To_Jenkins%

3. Перейти в каталог Jenkins и выполнить запуск Jenkins командой

cd %path_To_Jenkins% && java -jar jenkins.war

4. Зайти в WEB интерфейс по порту 8080.

Если вы работаете с linux машиной по ssh, то после закрытия соединения, вероятно, Jenkins будет остановлен. Для того чтобы избежать такого поведения можно использовать такой приём: выполнить команду с добавлением символа & – в результате команда будет выполняться в фоне, а управление будет возвращено обратно в командную строку, а для того чтобы при отключении от удаленной системы не завершались запущенные задачи можно использовать утилиту nohup, которая позволяет процессам продолжать работу даже после того, как вы выйдете из системы:

nohup java -jar jenkins.war &

Добавление Jenkins в службы

Для того чтобы в linux системах избежать ситуации, описанной в предыдущем абзаце, можно установить Jenkins как службу, для того чтобы каждый раз после перезагрузки Jenkins стартовал автоматически. Для этого необходимо создать файл /etc/systemd/system/jenkins.service командой:

sudo cat /etc/systemd/system/jenkins.service
sudo vi /etc/systemd/system/jenkins.service

и добавить содержимое в jenkins.service:

[Unit]
Description=Jenkins Daemon
[Service]
Environment="JENKINS_HOME=%path_To_Jenkins%"
ExecStart=/usr/bin/java -jar %path_To_Jenkins%/jenkins.war
User=имя текущего пользователя
[Install]
WantedBy=multi-user.target

Выполнить перезапуск службы сервисов: sudo systemctl daemon-reload

Команда для запуска сервиса jenkins: sudo systemctl start jenkins.service

перезапуска sudo systemctl restart jenkins.service

Важно отметить, что файл jenkins.war может быть расположен где угодно. Для того чтобы “подхватились” текущие параметры проекта, можно использовать команду, которая выполнит монтирование раздела Jenkins к работающему jenkins:

sudo mount -o bind /%path_To_Jenkins%/ ~/.jenkins/

Такой вариант будет работать только до перезагрузки системы, поэтому можно создать симлинк в директории ~/:

cd ~/ && sudo ln -s /%path_To_Jenkins%/ .jenkins

Добавление и подготовка к работе node в Jenkins

Данный раздел написан с учетом практики, что жизненный цикл у Jenkins и node ограничен, например, 2 неделями или месяцем.

Для добавления slave node в Jenkins можно добавить каждую машину руками, но из-за этого требуется постоянно заходить на машину и выполнять одни и те же операции, а это приводит к мысли, что всё можно максимально автоматизировать.
Для этого достаточно создать несколько Job, которые будут последовательно выполнять:

  1. заказ машин для добавления в качестве slave node в Jenkins;
  2. добавлять ранее заказанные машины в Jenkins с использованием rest api или Jenkins cli;
  3. выполнять развертывание необходимого окружения.

Все выше названные действия можно выполнять, используя дополнительные инструменты: ansible – для развертывания и настройки необходимых параметров и docker – как для развертывания Jenkins, так и для установки окружения на slave nodes.

Заключение

Главное, чтобы словосочетание “непрерывная интеграция” были на вашем проекте не только красивыми новомодными словами, но и действиями. И если вы, хотя бы минимально, будете соблюдать принципы CI, то проблем в жизненном цикле разработки станет гораздо меньше, а сам процесс станет приятнее. Опрос с интересной статистикой использования CI на проекте – https://habr.com/post/122381/, из которого видно, что всего несколько лет назад среди опрошенных респондентов CI практически не использовался.

Полезные ссылки

  1. Официальная документация Jenkins – https://jenkins.io/doc/
  2. Jenkins Cookbook – https://github.com/chef-cookbooks/jenkins
  3. Статья “Для чего программисту Continuous Integration и с чего начинать” – https://habr.com/post/353194/
  4. Список CI систем, средств для тестирования и деплоя – https://github.com/ciandcd/awesome-ciandcd

, , , , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *