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

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 (gitlab:pass@ci.org/project/job-generator). Схематично это выглядит вот так:

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

  1. Задача-генератор seed-job
  2. Задача типа 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. За счет гибкости и функционала вы можете использовать разные подходы, которые позволят именно вам управлять задачами максимально просто и удобно исходя из ваших требований и требований инфраструктуры.

Что еще почитать по теме

T-Rex 30 марта 2021

Что такое SMTP-протокол и как он устроен?

SMTP (Simple Mail Transfer Protocol) — протокол передачи почты. Он был представлен еще в 1982 году, но не теряет актуальности до сих пор. В статье разбираемся, какие задачи решает протокол и как он ра…
T-Rex 30 марта 2021
Владимир Туров 1 сентября 2020

Дело совершенно секретного iPod

Это был обычный серый день в конце 2005 года. Я сидел на рабочем месте и писал код для следующей версии iPod. Вдруг без стука ворвался директор ПО для iPod, начальник моего начальника, и закрыл дверь.
Владимир Туров 1 сентября 2020
T-Rex 21 августа 2020

TrendForce: цены на SSD упадут

Эксперты DRAMeXchange предсказывают значительное падение цен на оперативную память и твердотельные накопители в ближайшее время. Причина — сокращение спроса на чипы для NAND и DRAM.
T-Rex 21 августа 2020

Новое в блоге

Михаил Фомин 24 июня 2022

Docker Swarm VS Kubernetes — как бизнес выбирает оркестраторы

Рассказываем, для каких задач бизнесу больше подойдет Docker Swarm, а когда следует выбрать Kubernetes.
Михаил Фомин 24 июня 2022
Ульяна Малышева 30 сентября 2022

«Нулевой» локальный диск. Как мы запустили облако только с сетевыми дисками и приручили Ceph

Чем хороши сетевые диски и почему именно Ceph, рассказал директор по развитию ядра облачной платформы Иван Романько.
Ульяна Малышева 30 сентября 2022
Валентин Тимофеев 30 сентября 2022

Как проходит онбординг сотрудников ИТО? Что нужно, чтобы выйти на смену в дата-центр

Рассказываем, как обучаем новых сотрудников, какие задачи и испытания проходят инженеры прежде, чем выйти на свою первую смену.
Валентин Тимофеев 30 сентября 2022
T-Rex 28 сентября 2022

Книги по SQL: что почитать новичкам и специалистам

Собрали 6 книг, которые помогут на старте изучения SQL и при углублении в тему.
T-Rex 28 сентября 2022