Jenkins: Настройка агентов на основе отдельного Linux-сервера и Docker контейнера

Использование Master(главного и единственного сервера, на котором непосредственно установлен Jenkins) вместе с агентами(подчиненными серверами) позволяет выполнять сборки на этих агентах, уменьшая тем самым нагрузку на master-сервере, выполнять сборки на различном программном обеспечении/операционных системах, параллельно выполнять разные шаги одной и той же сборки на разных Jenkins-агентах(например, запуск параллельных тестов для различных WEB-браузеров(Chrome, Firefox, Opera и т.д.) или запуск большого количества интеграционных тестов можно разделить, например, на 4-х агентах, тем самым уменьшая общее время выполнения всех тестов теоретически в 4 раза).

Рассмотрим настройку двух типов Jenkins slave/agent, которые,например, будут собирать Java-проект с помощью maven.
В качестве slave-агентов будут выступать:

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

 

Настройка Jenkins slave/agent на основе  standalone Linux-сервера

Настройка slave/agent standalone Jenkins-сервера

1.Установить java,git,maven

2.Создать группу и пользователя с именем jenkins

3.Переключиться на этого пользователя и

4.Проверить доступность Java

5.Добавить публичный ключ пользователя jenkins с master сервера Jenkins в .ssh/authorized_keys пользователя jenkins на Slave-сервере

 

Настройка Master Jenkins-сервера
1.Переключиться под пользователя jenkins

2.Подключиться по SSH к Slave-серверу(проверить корректность подключения по SSH-ключу)

3.Настройка/добавление Slave-агента  в настройках на Jenkins Master

В частности в этом примере будем собирать на Slave-сервере только те сборки, метки которых совпадают с меткой самого Slave-сервера(linux-slave1)

Что при этом происходит/как это работает?
Jenkins Master по SSH-подключается и копируется jar-файл на Slave в каталог, определенный параметром
«Корень удаленной файловой системы»( в нашем случае–это домашний каталог пользователя jenkins – каталог /home/jenkins)
После чего запускает этот jar-файл

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

Также полезна вкладка System Information (наряду с вкладкой Logs), которая предоставляет полную системную информацию о slave-сервере(свойства системы, переменные окружения и т.д.)

Для того, чтобы сборка выполнялась на slave-сервере в настройках сборки присвоем метку сборки такую же, как и метка slave-сервера (linux-slave1)

После чего запускаем сборку и проверяем ее логи на предмет выполнения сборки на Slave-сервере

При этом настройки сборки, логи ее выполнения, результаты тестов, артефакты и т.д. все хранится на master-сервере, на agent хранится только среда выполнения сборки(workspace), в которой непосредственно и собирается сборка

 

Настройка Jenkins slave/agent на основе Docker-контейнера

1.Настройка Docker-сервера на прослушивание удаленных запросов с Jenkins-сервера

На уровне файерволла разрешаем подключение к порту 4243 с Jenkins-сервера

Проверяем доступность Docker-сервера через API выполняя запрос с Jenkins-сервера
Проверка существующих образов на Docker-сервере

2.Установка Jenkins-плагина с именем Docker

 

3.Подготовка Docker-образа,который будет использоваться Jenkins-ом для создания Docker-контейнера( Jenkins-slave) на лету

В качестве родительского докер-образа будем использовать образ ubuntu
Загрузим образ ubuntu

Создадим и запустим контейнер

Внутри контейнера выполним команды необходимые для
создания группы и пользователя пользователя jenkins, установим для него пароль
(этот логин(jenkins) и пароль(установленный на этом этапе) будут использоваться при создании Credentials в Jenkins.
Установим программного обеспечения, которое используется при выполнения сборки, например java,git,maven, а также ssh-сервер

Выходим из контейнер(выполняя команду exit)
Для этого узнаем идентификатор контейнера(в данном случае он равен f1f90cbb2da7) с помощью команды

И сохраняем изменения, сделанные нами в контейнере путем создания нового Docker-образа c именем maven-build-slave-0.1

 

4.Создание credentials для доступа к Docker в Jenkins

 

5.Настройка Docker-настроек в Jenkins

Нажимаем на кнопку Test Connection И проверяем корректный доступ к Docker-серверу с Jenkins

Добавляем созданный ранее докер-образ

Например, в Jenkins-джобе используем следующий pipeline

Согласно метке в поле node сборка будет запущена на Jenkins-slave с меткой docker-maven-build-slave, эта метка, которая соответствует нашему docker-контейнеру, настроенного на предыдущем шаге( в пункте 5)

Запускаем сборку с указанным выше pipeline-ом и проверяем,что в процессе выполнения сборки создался Docker-контейнер на основе Docker-образа maven-build-slave-0.1, в котором были выполненные указанные в pipeline шаги сборки.

 

Для запуска сборки (с анализом кода с использованием SonarQube, а также загрузки артефактов в maven-репозитарий, созданного на Nexus-сервере) на Docker-контейнере в качестве Jenkins-агента, а не на Jenkins-мастере необходимо выполнить несколько изменений:

SonarQube требует Java версии 8, по умолчанию с latest ubuntu Docker-образа ставится Java 11(при выполнении команды apt-get install java), поэтому небходимо доустановить Java версии 8 и сделать ее версией по-умолчанию.
После чего снова сохранить образ

 

Заходим внутрь docker-контейнера

 

1.Устанавливаем Java версии 8 и делаем ее версией по умолчанию

 

2.Добавляем/проверяем настройки maven в конфигурационный файл maven внутри контейнера

Логин/пароль,который был создан на Nexus-сервере с доступом ,к размещенному на Nexus maven-репозитарию.

Настройки maven относительно SonarQube

Выходим из контейнера и создаем новый Docker-образ с тем же именем(maven-build-slave-0.1) для сохранения сделанных изменений

В корне репозитария в файле pom.xml проверяем/добавляем(после чего не забываем закоммитить сделанные изменения)

Настройки свойств проекта

……

Настройки для Nexus-репозитария

 

3. Предоставить auth-токен для аутентификации на SonarQube-сервере(для загрузки результатов анализа кода)
Такой токен аутентификации можно передать через переменные окружения(чтобы не хардкодить его в Jenkins-file(при использовании pipeline script from scm) или непосредственно в самой сборке(при использовании pipeline script), например, выполняя команду

Что является не лучшим способом с точки зрения безопасности)
Для передачи токена через переменные окружения необходимо в настройках Docker agent template в Jenkins добавляем переменную окружения

После чего использовать эту переменную для аутентификации в SonarQube при вызове шага maven для проверки кода анализатором SonarQube

Jenkins-pipeline имеет вид(теперь все шаги сборки будут выполнены на Docker-контейнере,созданного на базе Docker-образа maven-build-slave-0.1 )

 

Использование volume(томов) смонтированный с Docker-хоста в Docker-контейнер для уменьшения времени sполнения сборки
При сборке могут загружаться много зависимостей проекта(например, при использовании Maven/Gradle), что увеличивает время выполнения сборки.
Например, смонтируем каталог с ноды /opt/docker/jenkins/volume-maven-build-slave-0.1 внутрь контейнера в каталог .m2 в домашнем каталоге пользователя jenkins (/home/jenkins/.m2) для того, чтобы при запуске сборки в контейнере Maven  каждый раз не загружал зависимости проекта
В настройках Jenkins в разделе Configure Jenkins->Cloud->Docker->Docker Agent Templates для докер образа maven-build-slave-0.1 нажимаем Container Settings и добавляем

Необходимо отметить, что UID/GID-пользователя jenkins, под которым внутри контейнера выполняется сборка должен соответствовать такому же значению UID/GID для владельца/группы на каталог ноды /opt/docker/jenkins/volume-maven-build-slave-0.1
(чтобы пользователь jenkins внутри контейнера имел право записи в каталог /home/jenkins/.m2/)
Например, внутри контейнера UID/GID равен 999/1000

На ноде выставляем рекурсивно соответствующие UID:GID на каталог, который монтируется внутрь контейнера

 

Источник: Книга Learning Continuous Integration with Jenkins 2nd Edition by Nikhil Pathania

Комментирование и размещение ссылок запрещено.

Комментарии закрыты.

Яндекс.Метрика