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) позволяет нам проводить различные стадии сборки и деплоя.
Для начала использования достаточно в репозитории проекта создать файл .gitlab-ci.yml, в котором описать необходимую нам последовательность. Для работы отлично может использовать Docker.
Итак, начнем
Для начала поставим необходимые инструменты. Jenkins-job-builder в нашем случае необходимо установить как на локальную машину, так и на машину, где будет работать агент gitlab. Можно обойтись просто локальной машиной gitlab.
Локально на linux и mac установим последнюю доступную версию:
pip install jenkins-job-builder
brew install jenkins-job-builder
Локально для описания нашего seed job мы сможем протестировать его работоспособность.
Добавлю, что seed job в терминологии DSL Plugin является задача типа Free-style project, которая создает остальные задачи из DSL-скриптов.
На gitlab-сервере установка будет ничем не отличаться от локальной установки на linux-машину:
pip install jenkins-job-builder
На всякий случай запустим утилиту и проверим, что она работает:
? ~ jenkins-jobs
usage: jenkins-jobs [-h] [--conf CONF] [-l LOG_LEVEL] [--ignore-cache]
[--flush-cache] [--version] [--allow-empty-variables]
[--user USER] [--password PASSWORD]
{update,test,delete,delete-all} ...
Установка плагина
Теперь установим плагин в Jenkins. Для установки можно воспользоваться как классическим UpdateCenter в разделе Manage Jenkins > Manage Plugins > Available, так и используя установку с помощью curl/wget, скачав плагин с официальной страницы плагина:
- Версия gitlab — 9.4.4-ce.0
- Версия gitlab-ci-multi-runner — 9.4.2
Создание репозитория
Создадим репозитории под код с описанием задач.
Для начала подготовим наш seed job — так называется задача, которая генерирует из себя все остальные. Репозиторий будет состоять из следующих файлов:
jenkins.ini
[job_builder]
ignore_cache=True
keep_descriptions=False
include_path=.
recursive=False
allow_duplicates=False
[jenkins]
user=username
password=secret-pass
url=http://example-ci.org
job-generator.yml
---
- job:
name: job-generator
description: 'Do not edit this job through the web!'
scm:
- git:
url: git@gitlab-selfhosted.org:group/repo-dsl.git
branches:
- origin/master
credentials-id: some-credentials-id
timeout: 20
basedir: dsl
triggers:
- gitlab:
trigger-push: true
trigger-merge-request: false
trigger-open-merge-request-push: both
ci-skip: false
set-build-description: false
add-note-merge-request: false
add-vote-merge-request: false
add-ci-message: true
allow-all-branches: true
branch-filter-type: RegexBasedFilter
target-branch-regex: '.*master*.'
builders:
- dsl:
target: "dsl/*.groovy"
ignore-existing: "false"
removed-job-action: "DISABLE"
removed-view-action: "DELETE"
lookup-strategy: "SEED_JOB"
.gitlab-ci.yml
job:
script: 'jenkins-jobs --conf jenkins.ini update job-generator.yml'
Подключим gitlab-runner к нашему проекту. Поскольку интерфейс gitlab последнее время часто меняется, то рекомендуем обращаться к официальной документации.
После подключения он будет выглядеть примерно так:
Теперь закоммитим изменения и в разделе Jobs у нашего проекта увидим следующее:
Вся схема выглядит следующим образом:
Подготовим репозиторий с описанием задач. Создадим его с названием repo-dsl и плоской структурой. Все файлы располагаются как есть.
Положим в него файл с нашим pipeline:
pipelineJob('testpipeline-build') {
description('Build test docker image, test and push it to local registry')
definition {
cpsScm {
scm {
git {
branch('origin/master')
remote {
url('git@gitlab-selfhosted.org:test-group/sample-project.git')
credentials('gitlab-creds')
}
}
}
scriptPath('Jenkinsfile')
}
}
}
И настроим webhook по запуску seed-job, который мы создали ранее.
В данной версии gitlab webhooks располагаются в проекте в разделе Settings > Integrations.
Создаем webhook на push (http://gitlab:pass@ci.org/project/job-generator). Схематично это выглядит вот так:
Теперь в нашем Jenkins есть две задачи:
- Задача-генератор seed-job
- Задача типа pipeline с названием testpipeline-build.
В тестовом pipeline мы будем собирать docker-образ, который после будет загружаться в локальный docker registry. Файл с образом будет браться с другого проекта.
В проекте с названием sample-project создадим Jenkinsfile следующего содержания:
node {
def app
stage('Clone repository') {
checkout([$class: 'GitSCM', branches: [[name: '*/master']],
doGenerateSubmoduleConfigurations: false, extensions: [],
submoduleCfg: [], userRemoteConfigs:
[[credentialsId: 'gitlab-repo-creds',
url: 'git@gitlab-selfhosted.org:test-group/docker-image-file.git']]])
}
stage('Build image') {
app = docker.build("docker-image")
}
stage('Test image') {
sh '''
if ! docker inspect docker-image &> /dev/null; then
echo 'docker-image does not exist!'
exit 1
fi
'''
}
stage('Push image') {
echo 'Push image'
docker.withRegistry('https://local-registry:9666', 'registry-creds') {
app.push("${env.BUILD_NUMBER}")
app.push("latest")
}
}
stage('Clean existing image') {
sh "docker rmi docker-image"
}
}
В итоге готовый pipeline будет выглядеть следующим образом в интерфейсе blueocean в Jenkins:
Или так в классическом интерфейсе:
Для запуска этой задачи автоматически мы можем добавить webhook в проекте с docker-image, где после отправки изменений в репозиторий будет запускаться эта задача.
В заключении отметим, что данная статья описывает лишь один из множества подходов управления задачами в jenkins. За счет гибкости и функционала вы можете использовать разные подходы, которые позволят именно вам управлять задачами максимально просто и удобно исходя из ваших требований и требований инфраструктуры.
Комментарии (15)
Hile
05.10.2017 14:36-1Я вот что то не пойму, а зачем тут Jenkins?
У гитлаба при создании в CI конфига, даже есть темплейт который в 30 строчек, собирает образ и пушит его в свой registry изкаропки <_<
Возможно какой то уникальный Flow с DSL Jenkins'a — как догадка
Плюс, есть минус) Храним доступы к Jenkins в репе — как то не очень.glebio Автор
05.10.2017 22:19+2Я вот что то не пойму, а зачем тут Jenkins?
Изначально, когда Jenkins вводился, gitlab не имел достаточного функционала. После, когда они их добавили, переход на gitlab ci уже невозможен из-за объема сборок в jenkins'ах, которых уже 7 инстансов. И даже с добавленным функционалом gitlab ci не обладает всем тем, что нам необходимо в jenkins.
Плюс, есть минус) Храним доступы к Jenkins в репе — как то не очень.
Так никто и не хранит. Это всего-лишь id для доступа к credentials, которые хранятся в самом Jenkins.
spopovru
06.10.2017 22:02Коллеги, у кого есть опыт использования Jenkins с Blueocean — как оно вам? Старый интерфейс Jenkins'а и Hudson'а оставлял, мягко говоря, желать лучшего…
И такой ещё вопрос — этот интерфейс там сейчас доступен из коробки, или надо как-то устанавливать отдельно?
Понимаю, что всё гуглится легко, но реально сейчас даже на это времени не могу найти… :(glebio Автор
06.10.2017 22:06+1Используем blueocean у себя. Полезных действий только одно: показать красивую картинку с кружочками менеджеру. Больше какой-то практической цели сам интерфейс не несет. Особенно, когда используется управление через jjb/dsl/etc.
И такой ещё вопрос — этот интерфейс там сейчас доступен из коробки, или надо как-то устанавливать отдельно?
Устанавливается все через плагин. После по /blue будет доступен интерфейс.
guai
Зачем начинать статью с буллшита?
CI вообще — возможно, тоже сомнительно. Именно дженкинс — явно нет.
ALexhha
а есть бесплатные альтернативы, с таким же функционалом?
glebio Автор
Не рассматривал, но GoCD также предоставляет пайплайны. Можно использовать и Gitlab CI для построения пайплайнов, которые они недавно добавили в новой версии.
guai
полно
Для небольших команд тимсити халявен, и фичей у него всяко побольше конкурентов.
ALexhha
Ну в том списке много проектов, которые бесплатные для не коммерческих проектов, так что сразу можно их вычеркивать. Плюс у многих ограничения на кол-во нод/билд агентов. Так что не совсем корректно приводить их для сравнения, имхо.
Можно пример фич тимсити, которых нет в Jenkins? Который кстати халявен для любого размера команд ;)
guai
Если вы и без меня это всё знаете, зачем спрашиваете?
На пару с автором топите за дженкинс только из абстрактной любви к опенсурсу и ненависти к корпоративному монстру? :)
glebio Автор
Сам много с TC не работал, но в одной из работ релизеры выбрали TC из-за своевременной поддержки плагинов, в отличие от опенсорса, где добавления нужных фич или исправления багов еще нужно подождать.
ALexhha
Не могу ничего сказать по поводу ТС, но много раз сталкивался с платными продуктами, и если у вас не мега энтерпрайзная подписка, то ждать новых фич/фиксов багов приходилось очень долго.
К тому же Jenkins — open source, можно и самому подфиксить/расширить при большом желании ;)
SyrexS
Например, ТС работает через агентов, которые можно разнести по разным машинам.
Мне больше нравится REST у ТС — более логично построен, чем на Jenkins
ALexhha
Ну в Jenkins тоже есть слейвы, а учитывая, что он написан на Java, то их можно запустить практически на любой платформе.
Ipeacocks
Ну с Дженкинсом ладно. А как жить без CI?