Основы Jenkins

Contents
Введение
Запустить скрипт из репозитория
Jenkins Docker Agent
Автоматический запуск заданий
Переменные окружения
Credentials
Сборщики проектов
Статьи про Jenkins

Введение

Jenkins — программная система с открытым исходным кодом на Java , предназначенная для обеспечения процесса непрерывной интеграции программного обеспечения.

Ответвлена в 2008 году от проекта Hudson, принадлежащего компании Oracle, основным его автором — Косукэ Кавагути.

Распространяется под лицензией MIT.

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

Работает в сервлет-контейнере, например, Apache Tomcat.

Поддерживает инструменты системы управления версиями, включая AccuRev, CVS, Subversion , Git , Mercurial, Perforce, Clearcase и RTC.

Может собирать проекты с использованием Apache Ant и Apache Maven , а также выполнять произвольные сценарии оболочки и пакетные файлы Windows .

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

Возможности Jenkins можно расширять с помощью плагинов.

Контроль доступа реализуется двумя способами: проверкой подлинности пользователя и авторизацией.

Поддерживается защита от внешних угроз, в том числе от CSRF-атак и вредоносных сборок.

В 2011 году Jenkins получил награду InfoWorld как лучший проект с открытым исходным кодом.

По умолчанию слушает TCP порт 8080

Banner Image

Jenkins Docker Agent

Относительно новый способ создавать агентов - запускать их в Docker контейнерах. Для этого в Jenkins нужно добавить плагин Docker

Plugin Manager Cloud Providers Docker

Настройка Jenkins для запуска docker агента изображение с сайта www.aredel.com
После установки Docker плагина
www.aredel.com

Настройка происходит через

Manage Jenkins Manage nodes and clouds Configure Clouds

Настройка Jenkins для запуска docker агента изображение с сайта www.aredel.com
Configure Clouds
www.aredel.com

Настроим Docker сервер на отдельном Ubuntu хосте в локальной сети и затем вернёмся к настройке Jenkins

IP адрес моего Ubuntu хоста 10.15.253.223

Первым делом на нём нужно установить Docker

Затем на Docker сервере нужно разрешить подлючения к Docker API.

Для этого нужно открыть порт 2375 (см. список стандартных TCP/UDP портов)

Также нужно открыть порты от 32768 до 60999 которые будут использоваться для агентов ( инструкция для Ubuntu )

sudo vi /lib/systemd/system/docker.service

# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

sudo vi /lib/systemd/system/docker.service
sudo service docker status -l

docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2023-01-09 12:00:07 EET; 3min 47s ago TriggeredBy: docker.socket Docs: https://docs.docker.com Main PID: 7709 (dockerd) Tasks: 10 Memory: 29.9M CPU: 862ms CGroup: /system.slice/docker.service └─7709 /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock Jul 14 11:32:55 andrei-virtual-machine dockerd[7709]: time="2023-01-09T12:00:05.488100986+02:00" level=info msg="ClientConn switching balancer to \"pick_first\"" module=grpc Jul 14 11:32:55 andrei-virtual-machine dockerd[7709]: time="2023-01-09T12:00:05.850772393+02:00" level=info msg="[graphdriver] using prior storage driver: overlay2" Jul 14 11:32:55 andrei-virtual-machine dockerd[7709]: time="2023-01-09T12:00:05.934673941+02:00" level=info msg="Loading containers: start." Jul 14 11:32:55 andrei-virtual-machine dockerd[7709]: time="2023-01-09T12:00:06.450509708+02:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address" Jul 14 11:32:55 andrei-virtual-machine dockerd[7709]: time="2023-01-09T12:00:06.689935636+02:00" level=info msg="Loading containers: done." Jul 14 11:32:55 andrei-virtual-machine dockerd[7709]: time="2023-01-09T12:00:06.990191356+02:00" level=info msg="Docker daemon" commit=20.10.12-0ubuntu4 graphdriver(s)=overlay2 version=20.10.12 Jul 14 11:32:55 andrei-virtual-machine dockerd[7709]: time="2023-01-09T12:00:06.990408478+02:00" level=info msg="Daemon has completed initialization" Jul 14 11:32:55 andrei-virtual-machine systemd[1]: Started Docker Application Container Engine. Jul 14 11:32:55 andrei-virtual-machine dockerd[7709]: time="2023-01-09T12:00:07.109669043+02:00" level=info msg="API listen on [::]:2375" Jul 14 11:32:55 andrei-virtual-machine dockerd[7709]: time="2023-01-09T12:00:07.122519364+02:00" level=info msg="API listen on /var/run/docker.sock"

Проверим, доступен ли Docker API с помощью curl

curl http://localhost:2375/version

{"Platform":{"Name":""},"Components":[{"Name":"Engine","Version":"20.10.12","Details":{"ApiVersion":"1.41","Arch":"amd64","BuildTime":"2022-03-07T15:57:50.000000000+00:00","Experimental":"false","GitCommit":"20.10.12-0ubuntu4","GoVersion":"go1.17.3","KernelVersion":"5.15.0-57-generic","MinAPIVersion":"1.12","Os":"linux"}},{"Name":"containerd","Version":"1.5.9-0ubuntu3.1","Details":{"GitCommit":""}},{"Name":"runc","Version":"1.1.0-0ubuntu1.1","Details":{"GitCommit":""}},{"Name":"docker-init","Version":"0.19.0","Details":{"GitCommit":""}}],"Version":"20.10.12","ApiVersion":"1.41","MinAPIVersion":"1.12","GitCommit":"20.10.12-0ubuntu4","GoVersion":"go1.17.3","Os":"linux","Arch":"amd64","KernelVersion":"5.15.0-57-generic","BuildTime":"2022-03-07T15:57:50.000000000+00:00"}

Проверим доступность из сети

curl http://10.15.253.223:2375/version

{"Platform":{"Name":""},"Components":[{"Name":"Engine","Version":"20.10.12","Details":{"ApiVersion":"1.41","Arch":"amd64","BuildTime":"2022-03-07T15:57:50.000000000+00:00","Experimental":"false","GitCommit":"20.10.12-0ubuntu4","GoVersion":"go1.17.3","KernelVersion":"5.15.0-57-generic","MinAPIVersion":"1.12","Os":"linux"}},{"Name":"containerd","Version":"1.5.9-0ubuntu3.1","Details":{"GitCommit":""}},{"Name":"runc","Version":"1.1.0-0ubuntu1.1","Details":{"GitCommit":""}},{"Name":"docker-init","Version":"0.19.0","Details":{"GitCommit":""}}],"Version":"20.10.12","ApiVersion":"1.41","MinAPIVersion":"1.12","GitCommit":"20.10.12-0ubuntu4","GoVersion":"go1.17.3","Os":"linux","Arch":"amd64","KernelVersion":"5.15.0-57-generic","BuildTime":"2022-03-07T15:57:50.000000000+00:00"}

Вернёмся в Jenkins и настроим облако

Настройка Jenkins для запуска docker агента изображение с сайта www.aredel.com
Configure Clouds
www.aredel.com

Теперь настроим агента с оглядкой на

Tребования:

The docker container's mapped SSH port, typically a port on the docker host, has to be accessible over network from the master. Docker image must have sshd installed. Docker image must have Java installed. Log in details configured as per ssh-slaves plugin.

Название можно придумать любое, например demo-docker-slave

Docker Image я использую свой. Код можно изучить здесь .

Вы можете либо использовать ссылку на мой образ andreissh/jenkins-docker-slave:latest либо сделать свой образ, и запушить его в свой докерхаб по инструкции

Настройка Jenkins для запуска docker агента изображение с сайта www.aredel.com
Настройка агента
www.aredel.com

Не забудьте указать Remote File System Root. В данном примере это

/home/jenkins

Также советую задать параметр Instance Capacity. Для примера можно ограничить двумя. Если не задавать этот параметр Jenkins будет запускать столько агентов, сколько сможет. При каких-то неполадках вы обнаружите список из большого числа неактивных агентов.

В качесте Connect Method можно выбрать SSH и подключиться по паролю.

Настройка Jenkins для запуска docker агента изображение с сайта www.aredel.com
Настройка агента
www.aredel.com
Настройка Jenkins для запуска docker агента изображение с сайта www.aredel.com
Настройка агента
www.aredel.com
Настройка Jenkins для запуска docker агента изображение с сайта www.aredel.com
Настройка агента
www.aredel.com

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

Выполнить джобу Jenkins на docker агенте изображение с сайта www.aredel.com
Restrict → Label Expression
www.aredel.com

Само задание элементарное - вывести текст командой echo

После успешного завершения в логах можно увидеть, что задание было выполнено удалённо на агенте demo-docker-slave-xxxxxxxxxxxxx id агента генерируется при создании.

Started by user andrei Running as SYSTEM Building remotely on demo-docker-slave-000gd8ottq9e0 on docker (demo-docker-slave) in workspace /home/jenkins/workspace/job_for_docker_agent [job_for_docker_agent] $ /bin/sh -xe /tmp/jenkins17605261416739110587.sh + echo Job for docker agent is done! Job for docker agent is done! Finished: SUCCESS

Добавим ещё один шаблон для докер агента. Теперь подключение будет не по SSH а с помощью JNLP

Manage Jenkins Manage nodes and clouds Configure Clouds Docker Agent Template Add Docker Template

Будем использовать образ jenkins/jnlp-slave

Старый образ jenkinsci/jnlp-slave устарел и не рекомендуется к использованию

Требования:
Jenkins master has to be accessible over network from the container.
Docker image must have Java installed.
Docker image must launch agent.jar by itself or using the EntryPoint Arguments below.

В Jenkins мастере

Configure Global Security → Agents → TCP port for inbound agents

Нужно установить Fixed 50000

Порт 50000 был заранее открыт в контейнере параметром ports в docker-compose.yml файле

Автоматический запуск заданий

Рассмотрим задание, которое использует репозиторий на GitHub

Configure → Source Code Management → Build Triggers

Для начала выберем Poll SCM

Частота выполнения проверок обновления репозитория задаётся в стиле cron

H/5 * * * *

Затем нужно сделать коммит в репозиторий подключённый к этому заданию и подождать около пяти минут.

Started by an SCM change Running as SYSTEM Building remotely on docker_slave_ssh-000i0w2937lrg on docker_ubuntu_esxi2 (docker_slave_ssh) in workspace /home/jenkins/workspace/my_python_job The recommended git tool is: NONE No credentials specified Cloning the remote Git repository Cloning repository https://github.com/yourrepojenkins-docker-slave > git init /home/jenkins/workspace/my_python_job # timeout=10 Fetching upstream changes from https://github.com/yourrepojenkins-docker-slave > git --version # timeout=10 > git --version # 'git version 2.34.1' > git fetch --tags --force --progress -- https://github.com/yourrepojenkins-docker-slave +refs/heads/*:refs/remotes/origin/* # timeout=10 > git config remote.origin.url https://github.com/yourrepojenkins-docker-slave # timeout=10 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10 Avoid second fetch > git rev-parse refs/remotes/origin/master^{commit} # timeout=10 Checking out Revision f0943b9194a48bafebf77280e1a848af92c6d6c3 (refs/remotes/origin/master) > git config core.sparsecheckout # timeout=10 > git checkout -f f0943b9194a48bafebf77280e1a848af92c6d6c3 # timeout=10 Commit message: "QA: adds ! to helloworld.py" > git rev-list --no-walk 09810fbbf97a812d396aca02e50c443ce999fa8f # timeout=10 [my_python_job] $ /bin/sh -xe /tmp/jenkins8662150179336980601.sh + python3 helloworld.py Hello World! Finished: SUCCESS

Если ваше задание - это Multibranch Pipleline, то можно использовать

Configure Scan Multibranch Pipeline Triggers Periodically if not otherwise run Interval

Где можно задать нужный интервал.

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

Переменные окружения

Изучить доступные переменные окружения можно на странице

http://jenkins_url/env-vars.html

Например, в моём примере это

http://jenkins.andrei.com:8080/env-vars.html/

Credentials

Установив плагин Credentials можно централизованно хранить логин, пароль и другие средства аутентификации прямо в Jenkins

Credential Scopes:

System - доступны только на Jenkins сервере и нодах. Они не видны Jenkins заданиям (jobs)

Global - доступны всем.

Если зайти в Pipleline там тоже будет раздел Credentials - там задаются Credentials локальные для этого проекта и не видимые из других. Для этого требуется плагин Folders.

Создание Jenkins Credentials изображение с сайта www.aredel.com
Нажмите Add Credentials
www.aredel.com
Создание Jenkins Credentials изображение с сайта www.aredel.com
Создание Credentials
www.aredel.com

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

Для того чтобы пользоваться сохранёнными в Jenkins учётными данными нужно установить плагин Credentials Binding Plugin

Credentials Bind Jenkins изображение с сайта www.aredel.com
Плагин
www.aredel.com

О том как использовать учетные данные в Pipeline читайте в статье «Использование учетных данных в Jenkins Pipeline»

Сборщики проектов

pipeline { agent any tools { gradle 'Gradle-6.2' } stages { stage("run frontend") { steps { echo 'executing yarn…' nodejs('Node-10.17') { sh 'yarn install' } } } stage("run backend") { steps { echo 'executing gradle…' sh './gradlew -v' } } } }

Статьи про Jenkins
Jenkins
Install Jenkins
Jenkins Basics
Jenkins Pipeline
Schedule
Errors
DevOps
Docker
Make
Banner Image

Search on this site

Subscribe to @aofeed channel for updates

Visit Channel

@aofeed

Feedback and Questions in Telegram

@aofeedchat