какая информация копируется на главный узел jenkins во время выполнения задачи

Jenkins Pipeline: заметки об оптимизации. Часть 1

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Меня зовут Илья Гуляев, я занимаюсь автоматизацией тестирования в команде Post Deployment Verification в компании DINS.

В DINS мы используем Jenkins во многих процессах: от сборки билдов до запуска деплоев и автотестов. В моей команде мы используем Jenkins в качестве платформы для единообразного запуска смоук-проверок после деплоя каждого нашего сервиса от девелоперских окружений до продакшена.

Год назад другие команды решили использовать наши пайплайны не только для проверки одного сервиса после его обновления, но и проверять состояние всего окружения перед запуском больших пачек тестов. Нагрузка на нашу платформу возросла в десятки раз, и Jenkins перестал справляться с поставленной задачей и стал просто падать. Мы быстро поняли, что добавление ресурсов и тюнинг сборщика мусора могут лишь отсрочить проблему, но не решат ее полностью. Поэтому мы решили найти узкие места Jenkins и оптимизировать их.

В этой статье я расскажу, как работает Jenkins Pipeline, и поделюсь своими находками, которые, возможно, помогут вам сделать пайплайны быстрее. Материал будет полезен инженерам, которые уже работали с Jenkins, и хотят познакомиться с инструментом ближе.

Что за зверь Jenkins Pipeline

Jenkins Pipeline — мощный инструмент, который позволяет автоматизировать различные процессы. Jenkins Pipeline представляет собой набор плагинов, которые позволяют описывать действия в виде Groovy DSL, и является преемником плагина Build Flow.

Скрипт для плагина Build Flow исполнялся напрямую на мастере в отдельном Java-потоке, который выполнял Groovy-код без барьеров, препятствующих доступу к внутреннему API Jenkins. Данный подход представлял угрозу безопасности, что впоследствии стало одной из причин отказа от Build Flow, и послужило предпосылкой для создания безопасного и масштабируемого инструмента для запуска скриптов — Jenkins Pipeline.

Подробнее об истории создания Jenkins Pipeline можно узнать из статьи автора Build Flow или доклада Олега Ненашева о Groovy DSL в Jenkins.

Как работает Jenkins Pipeline

Теперь разберемся, как работают пайплайны изнутри. Обычно говорят, что Jenkins Pipeline — совершенно другой вид заданий в Jenkins, непохожий на старые добрые freestyle-джобы, которые можно накликать в веб-интерфейсе. С точки зрения пользователя это, может, и выглядит так, но со стороны Jenkins пайплайны — набор плагинов, которые позволяют перенести описание действий в код.

Сходства Pipeline и Freestyle джобы

Правда в том, что параметры, описанные в Pipeline, автоматически добавятся в раздел настройки в веб-интерфейсе при запуске джобы. Верить мне можно потому, что этот функционал в последней редакции писал я, но об этом подробнее во второй части статьи.

Отличия Pipeline и Freestyle джобы

Запуск Jenkins Declarative Pipeline

Процесс запуска Jenkins Pipeline состоит из следующих шагов:

При старте pipeline-джобы Jenkins создает отдельный поток и направляет задание в очередь на выполнение, а после загрузки скрипта определяет, какой агент нужен для выполнения задачи.

Для поддержки данного подхода используется специальный пул потоков Jenkins (легковесных исполнителей). Можно заметить, что они выполняются на мастере, но не затрагивают обычный пул исполнителей:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Количество потоков в данном пуле не ограничено (на момент написания статьи).

Работа параметров в Pipeline. А также триггеров и некоторых опций

Обработку параметров можно описать формулой:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Из параметров джобы, которые мы видим при запуске, сначала удаляются параметры Pipeline из предыдущего запуска, а уже потом добавляются параметры заданные в Pipeline текущего запуска. Это позволяет удалить параметры из джобы, если они были удалены из Pipeline.

Источник

Управление задачами в Jenkins

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

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

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

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

Базовый подход к управлению задачами предлагается нам через веб-интерфейс самого Jenkins, где мы можем что угодно сконфигурировать, но поддерживать это при большом количестве задач и их разнотипности становится сложнее.

Ниже мы рассмотрим, как упростить и ускорить создание задач в Jenkins.

Инструменты, которые будем использовать

Jenkins job builder

Это python-утилита, позволяющая описывать задачи в YAML- или JSON форматах, которые через HTTP API загружаются на сервер. Для работы достаточно установить ее на локальной машине, написать конфигурацию с подключением и описать требуемые задачи.

DSL Plugin

Это плагин для Jenkins, с помощью которого мы сможем описывать задачи на специальном языке (DSL, Domain Specific Language) и создавать их на основе этих описаний. Работает локально на самом Jenkins-сервере.

Jenkins Pipeline

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

Gitlab и Gitlab CI

Наиболее популярный и развивающийся сейчас selfhosted проект, который также используется во многих компаниях. Он включает в себя версию для сообщества и энтерпрайз-решение.

Внутри имеется собственный CI, написанный на Go, который через специальные подключаемые агенты (runners) позволяет нам проводить различные стадии сборки и деплоя.

Итак, начнем

Для начала поставим необходимые инструменты. Jenkins-job-builder в нашем случае необходимо установить как на локальную машину, так и на машину, где будет работать агент gitlab. Можно обойтись просто локальной машиной gitlab.

Локально на linux и mac установим последнюю доступную версию:

Локально для описания нашего seed job мы сможем протестировать его работоспособность.
Добавлю, что seed job в терминологии DSL Plugin является задача типа Free-style project, которая создает остальные задачи из DSL-скриптов.

На gitlab-сервере установка будет ничем не отличаться от локальной установки на linux-машину:

На всякий случай запустим утилиту и проверим, что она работает:

Установка плагина

Теперь установим плагин в Jenkins. Для установки можно воспользоваться как классическим UpdateCenter в разделе Manage Jenkins → Manage Plugins → Available, так и используя установку с помощью curl/wget, скачав плагин с официальной страницы плагина:

Создание репозитория

Создадим репозитории под код с описанием задач.

Для начала подготовим наш seed job — так называется задача, которая генерирует из себя все остальные. Репозиторий будет состоять из следующих файлов:

jenkins.ini

job-generator.yml

.gitlab-ci.yml

Подключим gitlab-runner к нашему проекту. Поскольку интерфейс gitlab последнее время часто меняется, то рекомендуем обращаться к официальной документации.

После подключения он будет выглядеть примерно так:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Теперь закоммитим изменения и в разделе Jobs у нашего проекта увидим следующее:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Вся схема выглядит следующим образом:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Подготовим репозиторий с описанием задач. Создадим его с названием repo-dsl и плоской структурой. Все файлы располагаются как есть.
Положим в него файл с нашим pipeline:

И настроим webhook по запуску seed-job, который мы создали ранее.

В данной версии gitlab webhooks располагаются в проекте в разделе Settings → Integrations.
Создаем webhook на push (http://gitlab:pass@ci.org/project/job-generator). Схематично это выглядит вот так:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Теперь в нашем Jenkins есть две задачи:

В проекте с названием sample-project создадим Jenkinsfile следующего содержания:

В итоге готовый pipeline будет выглядеть следующим образом в интерфейсе blueocean в Jenkins:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Или так в классическом интерфейсе:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Для запуска этой задачи автоматически мы можем добавить webhook в проекте с docker-image, где после отправки изменений в репозиторий будет запускаться эта задача.

В заключении отметим, что данная статья описывает лишь один из множества подходов управления задачами в jenkins. За счет гибкости и функционала вы можете использовать разные подходы, которые позволят именно вам управлять задачами максимально просто и удобно исходя из ваших требований и требований инфраструктуры.

Источник

Jenkins Scripting Pipeline — генерация стадий выполнения

Всем привет! В интернете довольно много статей, связанных с Declarative Jenkins pipeline, и совсем немного о Jenkins Scripting Pipeline, хотелось бы восполнить этот пробел.

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

В 2008 году Jenkins был ответвлен от проекта Hudson, принадлежащего компании Oracle, и стал самостоятельным продуктом с открытым кодом. В начале, как и его предок, Jenkins поддерживал только последовательное выполнение шелл скриптов (Windows cmd/linux bash). Многие проекты до сих пор с успехом пользуются классическим вариантом интерфейса для обеспечения процесса непрерывной интеграции и развертывания. Первым значительным улучшением стал переход на использование так называемого Jenkins Pipeline. В качестве языка для написания Jenkins Pipeline скрипта был выбран Groovy в связи с тем, что весь остальной код Jenkins написан на Java, а Groovy и Java тесно взаимосвязаны. К сожалению, переход к использованию Jenkins Pipeline сильно усложнил процесс непрерывной интеграции и развертывания, так как требовал дополнительных навыков в написании Groovy скриптов, а также характеризовался сложным процессом отладки этого скрипта. В результате был разработан Jenkins plugin Blue Ocean и редактор Jenkins Pipeline. Но это была немного другая версия Jenkins Pipeline, которая получила название Jenkins Declarative Pipeline. Это был тоже своего рода прорыв, так как позволял людям без особых навыков программирования Groovy описывать довольно сложные процессы интеграции и развертывания.

В нашем проекте мы используем Jenkins для запуска интеграционных (E2E) тестов, которые проверяют функционал системы в целом.

К использованию Jenkins Scripting Pipeline мы пришли не сразу. В начале мы использовали классический Jenkins CI, но довольно быстро перешли на Jenkins Declarative Pipeline, так как выяснилось, что мы не можем запускать тесты одним куском, а должны исполнять их несколькими группами с немного различающимися параметрами запуска. Использование Jenkins Pipeline так же позволило нам запускать параллельно различные группы тестов, что также ускорило общее время выполнения. По мере разрастания функционала и тестов время выполнения полного пакета тестов стало увеличиваться и достигло на пике 40-50 минут. Кроме того, стало понятно, что имеющиеся UI-mock тесты часто не позволяют отловить ошибку, что приводит к потере времени на анализ ошибки в релизной версии. В результате было решено, что помимо UI-mock тестов мы должны выполнять интеграционные тесты прежде, чем осуществить процесс слияния поднятого PR в релизную ветку. Было решено перевести проект на Multibranch Pipeline. За счет распараллеливания тестов удалось сократить время выполнения до 30-35 минут. Мы выделили специальную фазу с небольшим количеством тестов, которые выполнялись за 10 минут. Эта фаза стала использоваться для выполнения тестов на ветке кода перед процессом слияния с релизной веткой.

В результате перед нашей командой были поставлены две задачи, связанные с уменьшением общего времени прогона тестов и времени прогона тестов перед процессом слияния. Для этого мы решили действовать в двух направлениях:

Для решения второй задачи пришлось перейти на использование Jenkins Scripting Pipeline по следующим причинам:

Для решения второй причины мне показалось удобным осуществлять генерацию выполнения тестов в зависимости от конфигурации, прописанной в Jenkins Pipeline файле.

Информацией о том, что вышло в итоге и хочется поделиться, так как в процессе написания Jenkins-pipeline скрипта выяснилось, что в интернете достаточно информации про Declarative Jenkins Pipeline и довольно мало по Jenkins Scripting Pipeline.

Структура тестов

Прежде чем перейти к описанию получившегося Jenkins-pipeline скрипта, необходимо рассказать о структуре и запуске тестов, чтобы дать представление о том, почему стало возможным сделать генерацию выполнения групп тестов.

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

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

Запуск тестов осуществляется командой:

Дополнительные параметры исполнения регулируются установкой переменных окружения. Одним из параметров окружения является PATH_TO_TESTS, в которую вносится путь до тестов относительно папки server-tests. То есть, например, если PATH_TO_TESTS=’stage1’, то выполняются все тесты из папки ‘stage1’, включая все тесты из поддиректорий: ‘sub-stage-11’ и ‘sub-stage-12’. А если PATH_TO_TESTS=’stage1/sub-stage-11’, то тесты только из этой папки.

Именно благодаря такой структуре тестов удалось создать Jenkins-pipeline файл, который в процессе исполнения создает фазы исполнения исходя из конфигурации этих этапов.

Конфигурация этапов выполнения

В качестве групп тестов использовали названия собранных по функционалу директорий, например, ‘stage1’. Для начала было решено выделить 3 больших пакета: Smoke Pack, Main Pack и Special Pack, в которые распределены имеющиеся группы тестов.

В результате выполнения должно было получиться следующее:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Выяснилось, что группа тестов в свою очередь может состоять из некоторых подгрупп, которые могут выполняться либо параллельно, либо последовательно. Для конфигурирования выполнения я стал использовать три map-коллекции:

Основная перегруппировка происходит в первой коллекции. Именно в ней я переставляю группы тестов по пакетам или переношу в новые группы.

Генерация этапов выполнения

Из-за особенностей Jenkins Scripting Pipeline пришлось выделить 2 обязательных этапа:

Наконец, пишем основной скрипт генерации этапов выполнения.

Существует возможность запуска необходимых тестов вручную (пакетами, отдельными группами тестов), поэтому в переменной окружения STAGES_TO_BE_EXECUTED находится список запускаемых пакетов/групп тестов. По умолчанию он установлен в “Smoke Pack”, таким образом, если запуск происходит в результате изменения ветки кода (commit), то выполняются тесты, входящие в пакет “Smoke Pack”.

Алгоритм генерации довольно простой:

Для каждого пакета из jobPacks:

Выглядит это следующим образом:

Алгоритм функции создания списка групп выполнения:

Алгоритм функции генерации фазы выполнения (stage) в Jenkins:

Шаги выполнения тестов одинаковые, благодаря чему получилось создать данный генератор:

В stageEnv устанавливаются дополнительные переменные окружения, с которыми должна выполнятся та или иная группа тестов. В основном это установка роли пользователя, от которого эти тесты выполняются, а также относительный путь к тестам из этой группы на основании имени фазы выполнения. Для этого в generateStage и в generateExecuteStagesList создавались имена с “/” типа “Stage5/sub stage 51”.

Итоги и выводы

Удалось сократить размер Jenkinsfile в 2 раза за счет удаления повторяющегося кода, который был написан в Declarative Jenkins pipeline.

Стало удобнее перемещать группы тестов между пакетами выполнения. Появилась возможность легко разделить группу тестов на несколько подгрупп с последующим параллельным выполнением.

Грамотно подобранная конфигурация позволила сократить время выполнения полного пакета тестов примерно в 2 раза (с 25-30 минут до 13-16 минут).

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Smoke пакет при этом выполняется от 2 до 5 минут (около половины тестов):

Источник

Простой способ редактирования, хранения и передачи параметров между job’ами Jenkins

Как и любой здоровый человек — могу назвать себя в меру ленивым.

Так, например, мне лень писать длинный pipeline (вообще писать руками pipeline лень). И мне не нравится идея гонять туда — сюда файлик, в который придётся писать параметры, для чего городить огород из лишнего кода.

Кстати, может кто-то из читателей этой статьи сможет объяснить, почему нужно выполнять все операции (сборка дистрибутива, его тестирование и т. д.) на той же машине, где расположен Jenkins? Я вот так не считаю и моя архитектура построена так, что Jenkins нужен для запуска задач, а вот они (задачи) выполняются на отведённых под эти вещи машинах. Но это лирика и желание пообщаться и поделиться опытом.

Сама статья о другом: как сохранить параметры и параметризовать регулярную Job’у удобно и штатно?

Давайте представим гипотетическую ситуацию, когда вам нужно сделать регулярный запуск некоторого набора тестов по расписанию.

Вы уже сделали некоторою Job’у, с использованием плагина Active Choices и теперь вы молодцы и можете запускать руками нужный набор.

Но как теперь объединить обе этих функции, чтобы получить выгоду от обоих подходов?
Не буду рассказывать всех тех вариантов, которые мне пришлось услышать или попробовать, а сразу перейду к самой сути. Решение моё лишь частично, так как реализация была найдена на Medium. Я же решил поделиться им с сообществом, чтобы больше людей перестали костылить и делать глупости.

Целевая картина в нашем случае будет выглядеть так: есть Job’а для управления набором сценариев, которая используется, когда этот самый набор нужно отредактировать, и есть регулярная Job’а, которая будет использовать и регулярно запускать нужный набор.
Первое, что нужно сделать — это создать пару переменных: одна для хранения «эталонного набора» и вторая для непосредственного хранения целевого набора. Для этого переходим по меню Jenkins «Настроить Jenkins — > Конфигурация системы — > Глобальные настройки»:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Создатели Jenkins позаботились о своих пользователях и нам только остаётся добавить две переменные, как показано на изображении выше.

Когда переменные созданы, нужно установить плагин Active Choices, если ещё не установлен. Он нам ещё пригодится.
Создадим задачу со свободной конфигурацией. Укажем, что сборка параметризованная, установив checkbox «Это — параметризованная сборка». И добавим параметр типа «Active Choices Reactive Parameter».

Назовём этот параметр «first_param», для примера.

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Добавим следующий код, как показано на изображении выше:

На выходе код отдаёт одномерный массив.

Я предпочитаю заполнять блок fallback, как показано ниже:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

«Choice Type» предлагаю выбрать самостоятельно. В моём случае это «Checkboxes». » Referenced parameters» оставляем пустым.

Теперь нужно создать ещё один параметр. В моём примере это second_param.

В секцию «Groovy script» добавим следующее:

В блок «Groovy Script» добавляем код:

или что-то более читаемое.

«Choice Type» ставим любой, поскольку эта переменная нам фактически нужна только для выполнения Groovy кода для записи глобальной перемернной. Наверняка можно обойтись и без неё, но так было проще и быстрее.

В «Referenced parameters» записываем название предыдущей переменной second_param, чтобы связать два блока.

Жмём сохранить — et voilà!

Для проверки давайте посмотрим, какие исходные значения глобальных переменный у нас сейчас записаны, для чего проходим «Настроить Jenkins — > Конфигурация системы — > Глобальные настройки»:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Теперь возвращаемся к нашей Job’е и нажимаем «Собрать с параметрами». Выбираем, для примера, только один пункт:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Жмём «Собрать» и снова проверяем глобальные переменные:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Как видим, всё работает.

Использование же глобальной переменной до крайности простое. И в своей регулярной Job’е вы можете обратиться к ней, как обычно:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Из нюансов, вынужден отметить, что нажимать кнопку «Собрать» вовсе необязательно, так как перезапись глобальной переменной происходит всякий раз, когда вы выбираете один из пунктов. Но совершенству нет предела и вы можете усовершенствовать моё решение.

Источник

Учимся разворачивать микросервисы. Часть 4. Jenkins

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Это четвертая и заключительная часть серии статей «Учимся разворачивать микросервисы», и сегодня мы настроим Jenkins и создадим пайплайн для микросервисов нашего учебного проекта. Jenkins будет получать файл конфигурации из отдельного репозитория, собирать и тестировать проект в Docker-контейнере, а затем собирать Docker-образ приложения и пушить его в реестр. Последней операцией Jenkins будет обновлять кластер, взаимодействуя с Helm (более подробно о нем в прошлой части).

Ключевые слова: Java 11, Spring Boot, Docker, image optimization

Ключевые слова: Kubernetes, GKE, resource management, autoscaling, secrets

Ключевые слова: Helm 3, chart deployment

Настройка Jenkins и пайплайна для автоматической доставки кода в кластер

Ключевые слова: Jenkins configuration, plugins, separate configs repository

Jenkins — это сервер непрерывной интеграции, написанный на Java. Он является чрезвычайно расширяемой системой из-за внушительной экосистемы разнообразных плагинов. Настройка пайплайна осуществляется в декларативном или императивном стиле на языке Groovy, а сам файл конфигурации (Jenkinsfile) располагается в системе контроля версий вместе с исходным кодом. Это удобно для небольших проектов, однако, часто более практично хранить конфигурации всех сервисов в отдельном репозитории.

Код проекта доступен на GitHub по ссылке.

Установка и настройка Jenkins

Установка

Существует несколько способов установить Jenkins:

War-архив с программой можно запустить из командной строки или же в контейнере сервлетов (№ Apache Tomcat). Этот вариант мы не будем рассматривать, так как он не обеспечивает достаточной изолированности системы.

Устранить этот недостаток можно, установив Jenkins в Docker. Из коробки Jenkins поддерживает использование докера в пайплайнах, что позволяет дополнительно изолировать билды друг от друга. Запуск докера в докере — плохая идея (здесь можно почитать почему), поэтому необходимо установить дополнительный контейнер ‘docker:dind’, который будет запускать новые контейнеры параллельно контейнеру Jenkins’а.

Также возможно развернуть Jenkins в кластере Kubernetes. В этом случае и Jenkins, и дочерние контейнеры будет работать как отдельные поды. Любой билд будет полностью выполняться в собственном контейнере, что максимально изолирует выполнения друг от друга. Из недостатков этот способ имеет довольно специфичную конфигурацию. Из приятных бонусов Jenkins в Google Kubernetes Engine может быть развернут одним кликом.

Хоть третий способ и кажется наиболее продвинутым, мы выберем прямолинейный путь и развернем Jenkins в Docker напрямую. Это упростит настройку, а также избавит нас от нюансов работы со stateful приложениями в Kubernetes. Хорошая статья для любопытствующих про Jenkins в Kubernetes.

Так как проект учебный, то мы установим Jenkins на локальной машине. В реальной обстановке можно посмотреть в сторону, например, Google Compute Engine. В дополнение замечу, что изначально я пробовал использовать Jenkins на Raspberry Pi, но из-за разной архитектуры «малинки» и машин кластера они не могут использовать одни и те же Docker-образы. Это делает невозможным применение Raspberry Pi для подобных вещей.

После установки Jenkins открываем http://localhost:8080/ и следуем инструкциям. Настроить Jenkins можно через UI, либо программно. Последний подход иногда называют «инфраструктура как код» (IaC). Он подразумевает описание конфигурации сервера с помощью хуков — скриптов на Groovy. Оставим этот способ настройки за рамками данной статьи. Для интересующихся ссылка.

Плагины

Для нашего проекта нам понадобится установить два плагина: Remote File Plugin и Kubernetes CLI. Remote File Plugin позволяет хранить Jenkinsfile в отдельном репозитории, а Kubernetes CLI предоставит доступ к kubectl внутри нашего пайплайна.

Установка Helm

Глобальные переменные среды

Так как у нас два сервиса, то мы создадим два пайплайна. Некоторые данные у них будут совпадать, поэтому логично вынести их в одно место. Это можно сделать, задав глобальные переменные среды, которые будут установлены перед выполнением любого билда на сервере Jenkins. Отмечу, что не стоит с помощью этого механизма передавать пароли — для этого существуют секреты.

Секреты

Имя секретаТипОписание
github-credsusername with passwordЛогин/пароль от git-репозиториев
dockerhub-credsusername with passwordЛогин/пароль от реестра Docker-образов
kubernetes-credssecret textТокен сервисного аккаунта нашего кластера

В предыдущей части в файле NOTES.txt нашего чарта мы описали последовательность команд для получения токена сервисного аккаунта. Вывести эти команды для кластера можно, запросив статус Helm-инсталляции ( helm status msvc-project ).

Конфигурация пайплайна

Как уже было упомянуто ранее, пайплайны описываются на Groovy, и могут быть написаны в декларативном и императивном стилях. Мы будем придерживаться декларативного подхода.

В Jenkins процесс выполнения пайплайна (билд) поделен на ряд шагов (stage). Каждый шаг выполняется определенным агентом (agent).

Наши пайплайны будут состоять из следующих шагов:

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Структура файла конфигурации

Файл конфигурации будет иметь следующую структуру:

Агенты в Jenkins подчиняются типичным правилам «наследования» — если в шаге не определен агент, то будет использован агент родительского шага. Тег pipeline может рассматриваться как корневой шаг для всех остальных. Корневой шаг мы используем для объявления переменных среды и опций, которые по тому же правилу наследования будут иметь силу для всех вложенных шагов. Поэтому для тега pipeline установлен агент ‘none’. Использование этого агента подразумевает, что вложенные шаги обязаны переопределить этот агент для выполнения каких-либо полезных действий.

Агент в шагах Push Images и Trigger Kubernetes равен ‘any’. Это значит, что шаг может быть выполнен на любом доступном агенте. В простейшем случае это означает выполнение в контейнере Jenkins’а. Также эти шаги будут выполнены только для коммитов в мастер-ветку ( when < branch 'master' >).

Далее мы более пристально посмотрим на каждый из шагов, а также на блоки options и environment.

Опции

Блок опций может быть использован для настройки выполнения пайплайна или же отдельного шага. Мы используем следующие опции:

skipStagesAfterUnstable заставит Jenkins сразу прервать билд, eсли тесты были провалены. Поведение по умолчанию предусматривает установку статуса билда в UNSTABLE и продолжение выполнения. Это позволяет в сложных случаях более гибко обрабатывать подобные ситуации.

skipDefaultCheckout отключает автоматический чекаут репозитория проекта. Дефолтно Jenkins делает force чекаут репозитория для каждого шага с собственным агентом (в нашем случае Prepare Checkout, Push images и Trigger Kubernetes). То есть по сути затирает все изменения. Это может быть полезно при использовании пайплайна с несколькими различными образами. Однако нам нажно получить исходники с репозитория только единожды — на шаге Build. Применив опцию skipDefaultCheckout, мы получаем возможность произвести чекаут вручную. Также стоит заметить, что Jenkins будет автоматически переносить артефакты между шагами. Так, например, скомпилированные исходники из шага Build будут полностью доступны в шаге Test.

Переменные среды

Переменные среды могут быть также объявлены как для всего пайплайна, так и для отдельного шага. Их можно использовать, чтобы вынести какие-то редкоизменяемый свойства. В этом блоке мы определим имя файла докера и имена создаваемых Docker-образов.

В предыдущих статьях при работе с кластером мы всегда использовали наиболее свежие latest образы, но напомню, что это не лучший вариант из-за проблем при откатах к предыдущим версиям. Поэтому мы предполагаем, что в начальный момент времени кластер создается из самых свежих образов, а потом уже будет обновляться на конкретную версию. Тег IMAGE_TAG будет зависеть только от номера билда, который можно получить из предустановленной глобальной переменной среды BUILD_NUMBER. Таким образом наши версии будут составлять монотонную последовательность при условии того, что пайплайн не будет пересоздаваться (это приведет к сбросу номера билда). При неуспешных билдах BUILD_NUMBER также будет инкрементирован, следовательно последовательность версий образов может содержать «пробелы». Основное преимущество такого подхода к версионированию — его простота и удобство восприятия человеком. В качестве альтернативы можно подумать об использовании метки времени, чексуммы коммита или даже внешних сервисов.

Компиляция, тестирование, сборка

Чисто технически фазы компиляции, тестирования и сборки возможно объединить в один шаг, но для лучшей наглядности мы опишем их как отдельные шаги. С помощью плагинов Maven можно с легкостью добавлять дополнительные фазы, такие как статический анализ кода или интеграционное тестирование.

В фазе тестирования командой junit ‘**/target/surefire-reports/TEST-*.xml’ мы указываем Jenkins’у на файл с результатами тестов. Это позволит их отобразить прямо в веб-интерфейсе.

На последнем шаге мы генерируем jar-архив с нашим приложением.

Создание и отправка Docker-образа в реестр

На следующем шаге мы должны собрать Docker-образы и запушить их в реестр. Мы будем делать это средствами Jenkins, но в качестве альтернативы можно реализовать это и с помощью Maven-плагина.

Для начала нам надо доработать докер-файлы наших сервисов, которые мы разработали в первой статье цикла. Эти докер-файлы собирали приложение из исходников прямо в процессе создания образа. Сейчас же у нас имеется протестированный архив, следовательно один из шагов создания образа уже выполнен средствами Jenkins. Мы назовем этот новый файл Dockerfile-packaged.

Докер-файл для микросервиса шлюза аналогичен.

В конце шага происходит удаление установленных локально образов.

Обновление кластера Kubernetes

Финальным шагом осталось сообщить Kubernetes, что в реестре появился новый образ, и необходимо запустить процедуру обновления подов одного из микросервисов.

Итоговый Jenkinsfile

Jenkinsfile для микросервиса шлюза полностью аналогичен.

Подключение пайплайна

В Jenkins существует несколько видов пайплайнов. В данном проекте мы используем Multibranch pipeline. Как и следует из названия, билд будет запускаться для любого коммита в произвольной ветке.

Branch sources. Выбираем GitHub, в графе ‘Credentials’ выбираем секрет с логином/паролем от аккаунта и указываем URL репозитория с исходным кодом микросервиса.

Build Configuration. В Mode выбираем ‘by Remote File Plugin’, основное поле — Repository URL, в котором надо указать адрес репозитория с Jenkinsfile, а также Script Path с путем к этому файлу.

какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть фото какая информация копируется на главный узел jenkins во время выполнения задачи. Смотреть картинку какая информация копируется на главный узел jenkins во время выполнения задачи. Картинка про какая информация копируется на главный узел jenkins во время выполнения задачи. Фото какая информация копируется на главный узел jenkins во время выполнения задачи

Scan Repository Triggers. В этом разделе настроим период, с которым Jenkins будет проверять, появились ли какие-то изменения в отслеживаемом репозитории. Недостаток этого подхода в том, что Jenkins будет генерировать трафик, даже когда в репозитории ничего не менялось. Более грамотный подход — настроить веб-хуки. При этом хранилище исходного кода само будет инициировать запуск билда. Очевидно, что сделать это можно, только если Jenkins доступен по сети для хранилища исходных кодов (они должны быть либо в одной сети, либо Jenkins должен иметь публичный IP-адрес). Подключение веб-хуков оставим за рамками данной статьи.

Запуск

После того как наш пайплайн настроен, можно его запустить. Наиболее удобно это сделать из меню Blue Ocean (Open Blue Ocean). Первый запуск может занять продолжительное время, так как потребуется время на загрузку Maven-зависимостей. После выполнения билда можно подключиться к кластеру и убедиться в том, что тег образа микросервиса был изменен ( helm get values msvc-project ).

В дальнейшем Jenkins будет отслеживать изменения в репозитории микросервиса и запускать билд автоматически.

Заключение

Jenkins — очень гибкая система, позволяющая реализовывать процесс непрерывной интеграции и развертывания любой сложности. В этой статье мы только коснулись этого инструмента, создав простенький пайплайн для микросервисов нашего проекта. В будущем этот пайплайн можно значительно дорабатывать и улучшать, например, добавив уведомления, дополнительные шаги, веб-хуки и многое-многое другое.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *