Автоматизация лежит в основе DevOps. Различные инструменты и методы автоматизации действительно позволили реализовать концепцию непрерывной интеграции и непрерывной доставки. Эти инструменты быстро развивались с годами, но одно имя, которое, кажется, останется здесь навсегда, — Jenkins.
В этой заметке мы не будем обсуждать вводные понятия CI-CD и тратить время на демонстрацию шагов по установке Jenkins. Если вы новичок в Jenkins, вы можете ознакомиться с официальными документами по установке, чтобы начать работу с Jenkins. Поэтому цель этой заметки — обсудить, как настроить архитектуру Jenkins контроллер-агент (она же архитектура master-slave) и решить некоторые проблемы, возникающие при этом. Это связано с тем, что процесс может быть утомительным, и если вы давно не занимались этим, то в итоге можете потратить несколько часов впустую.
Почему архитектура Jenkins Controller-Agent Architecture?
Узел контроллера (мастер) — это мозг Jenkins, это место, где работает приложение Jenkins. Если мы делаем слишком много работы на узле контроллера (или он падает), все приложение может стать недоступным. Поэтому мы хотим, чтобы главный узел был максимально доступен. Этого можно добиться, делегируя работу узлам-агентам (ведомым узлам). Таким образом, в архитектуре Jenkins Controller-Agent задания планируются и назначаются агентам контроллером. Контроллер также отслеживает, находятся ли ведомые узлы в сети, получает их ответы о результатах сборки и выводит результаты сборки на консоль. Таким образом, главный узел более доступен, а значит, общая производительность нашего сервера Jenkins повышается при использовании этой конструкции.
Еще одним преимуществом этой архитектуры является то, что мы можем установить только минимальный набор инструментов на узле контроллера, а более тяжелые инструменты (требуемые заданиями) мы можем установить на узлах агентов. Это позволяет сохранить легкость контроллера, а также организовать наши задания на основе агентов, которые должны их выполнять. В приведенном выше примере у нас есть контроллер Jenkins и 4 агента. Каждый из агентов может служить определенной цели.
- Например, если нам нужно запускать тесты и создавать задания для приложений на базе javascript, мы можем ограничить выполнение этих заданий агентом, расположенным крайним слева.
- Аналогично, если нам нужно создать несколько приложений .NET, мы можем установить агент Jenkins на хост windows и ограничить выполнение этих заданий крайним справа.
- Кроме того, мы можем улучшить производительность, сбалансировав нагрузку в соответствии с требованиями нашей системы. Допустим, мы настраиваем CI-CD для системы, состоящей из сотен микросервисов, среди которых в два раза больше сервисов, написанных с использованием стека на основе python, чем любого другого стека. В этой ситуации мы можем установить два агента Jenkins с установленными инструментами на основе python, а контроллер Jenkins сбалансирует нагрузку между этими двумя агентами.
Настройка
Шаг 1: Разверните контейнер Jenkins Controller(master).
Мы можем использовать официальный докер-контейнер jenkins. Вот пример файла docker-compose, который вы можете использовать.
version: '3.8'
services:
jenkins_controller:
image: jenkins/jenkins:lts-jdk11
privileged: true
user: root
container_name: $CONTAINER_NAME
ports:
- 50001:8080
- 50002:50000
volumes:
- $JENKINS_HOME:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
Теперь нам нужно раскрутить контейнер и установить необходимые инструменты для узла контроллера Jenkins. Для этого мы можем написать простой bash-скрипт.
#!/bin/bash
set -o nounset
JENKINS_CONTAINER_NAME=$1
JENKINS_HOME=`pwd`/jenkins/jenkins_home
echo "JENKINS HOME: $JENKINS_HOME"
CONTAINER_NAME=$JENKINS_CONTAINER_NAME JENKINS_HOME=$JENKINS_HOME docker-compose -f docker-compose-controller.yaml up --build -d
sleep 10
# Here we have just installed git for our controller node, install as many tools as you require
docker exec $JENKINS_CONTAINER_NAME bash -c "apt-get update -y -q && apt-get upgrade -y -q && apt-get install -y -q git"
- Jenkins использует apache jetty, который по умолчанию использует порт 8080, мы сопоставили порт 50001 нашей хост-машины с портом 8080 контейнера. Таким образом, войдя на http://host:50001, вы попадете на веб-панель Jenkins.
- Проверьте журналы контейнера на наличие первого пароля администратора и создайте нового пользователя admin.
Шаг 2: Настройка агента Jenkins (slave)
Теперь мы можем настроить нашего агента (агентов). Поскольку наш контроллер Jenkins будет взаимодействовать с агентами с помощью SSH, нам необходимо сгенерировать SSH-ключи. В этом случае главный узел Jenkins будет выступать в качестве SSH-клиента, а агенты будут выступать в качестве SSH-серверов. Поэтому нам нужно настроить их соответствующим образом.
- Сгенерировать ключи
ssh-keygen -t rsa -f jenkins_agent_1
- Перейдите на панель управления Jenkins > Управление Jenkins > Управление учетными данными > Добавьте учетные данные ‘System’ для включения SSH в агента Jenkins.
Системные учетные данные в сравнении с глобальными учетными данными
Системный: Доступны только на сервере Jenkins (не видны в задании jenkins).
Глобальный: Доступен везде, включая задание jenkins.
Заполните форму соответствующими значениями. Вот пример,
Имя пользователя: jenkins # мы хотим войти в агент под пользователем ‘jenkins’, который уже существует по умолчанию в контейнере jenkins-agent, который мы будем использовать.
ID: Уникальный идентификатор для учетной записи, который можно использовать для ссылки на учетную запись
Закрытый ключ: Содержимое файла закрытого ключа SSH (например: jenkins_agent_1.pub).
Шаг 3: Разверните контейнер Jenkins Agent(slave).
Мы можем использовать официальный докер-контейнер jenkins-ssh-agent. Вот пример файла docker-compose, который вы можете использовать.
version: '3.8'
services:
jenkins_agent:
image: jenkins/ssh-agent:jdk11
privileged: true
user: root
container_name: $CONTAINER_NAME
expose:
- 22
environment:
- JENKINS_AGENT_SSH_PUBKEY=$JENKINS_AGENT_SSH_PUBKEY
Обратите внимание, что мы должны установить переменную окружения JENKINS_AGENT_SSH_PUBKEY
, что в данном случае мы делаем из переменной bash. Нам также нужно установить необходимые инструменты в агенте Jenkins. Мы можем сделать все это с помощью простого bash-скрипта, как показано ниже,
#!/bin/bash
set -o nounset
JENKINS_CONTAINER_NAME=$1
JENKINS_AGENT_SSH_PUBKEY=$2
CONTAINER_NAME=$JENKINS_CONTAINER_NAME JENKINS_AGENT_SSH_PUBKEY=$JENKINS_AGENT_SSH_PUBKEY docker-compose -f docker-compose-agent.yaml up --build -d
sleep 10
# Here we have just installed tools that help us create a python virtual environment for our agent node, install as many tools as you require
docker exec $JENKINS_CONTAINER_NAME bash -c "apt-get update -y -q && apt-get upgrade -y -q && apt-get install -y -q git python3 python3-venv"
Шаг 4: Настройка агента из контроллера Jenkins
Перейдите на панель управления Jenkins > Управление Jenkins > Управление узлами и облаками > Новый узел
Заполните форму, используя соответствующие значения. Вот пример,
Имя: JenkinsAgent1
NumberOfExecutors: 1-2
RemoteRootDirectory: /home/jenkins/agent
Метки: linux, python # Значения, разделенные пробелами, могут быть полезны для ограничения заданий для запуска на определенном агенте.
Использование: Используйте этот узел как можно чаще
Метод запуска: Запуск агентов через SSH
Host: jenkins_agent # Имя хоста или IP агента для подключения. (имя службы docker-compose, если контроллер и агент находятся на одной машине).
Учетные данные: Выберите учетные данные, созданные в шаге 2.1.
HostKeyVerificationStrategy: Стратегия верификации без проверки
Метод запуска > Расширенный
ConnectionTimeoutInSeconds: 60
MaximumNumberOfRetries: 10
SecondsToWaitBetweenRetries: 15
Есть и другие варианты, которые вы можете рассмотреть, но те, которые я описал, должны помочь вам начать.
Мы можем создать столько агентов, сколько нам нужно, используя процесс, описанный выше.
Шаг 5: Создайте задания и запустите
Теперь наш агент должен быть обнаружен контроллером, и мы можем начать делегировать наши задания агентам. Мы можем ограничить выполнение задания на определенном агенте, используя метки, которые мы назначили при создании агента.
Вот и все :D. Дайте мне знать, если я что-то упустил. Вы также можете найти исходные файлы здесь: ashiqursuperfly/Jenkins-Controller-Agent-Setup