Jenkins in Kubernetes
Last updated
Last updated
https://habr.com/ru/companies/slurm/articles/699158/
Из-за роста инстансов Jenkins команда может страдать от избыточного потребления ресурсов и медлительности конвейера доставки. Выход из этой ситуации — масштабирование. В статье пошагово разбираем, как масштабировать Jenkins с помощью Kubernetes.
Масштабируемость — способность системы или процесса обрабатывать увеличенный объём операций без ограничений или структурных узких мест. Масштабируя Jenkins, вы получаете возможность:
выполнять больше сборок параллельно;
автоматически заменять повреждённые инстансы;
распределять нагрузку между разными машинами;
уменьшать time to market приложения.
Хотя функция масштабируемости доступна в Jenkins из коробки, сам процесс масштабирования не так прост. Одним из лучших инструментов для управления масштабируемыми решениями считается Kubernetes.
Если ваша цель — настроить платформу Kubernetes с нуля поверх реального кластера, стоит начать с официальной документации, так как статья сосредоточена не на установке Kubernetes, а на реализации масштабируемого сервера непрерывной интеграции. Если же вам нужен Kubernetes для тестирования, можете использовать Minikube. Это инструмент, специально разработанный для запуска кластера Kubernetes с одним узлом на локальном компьютере. Он прост в установке, но у вас должен быть установлен VirtualBox.
Если у вас есть платформа UNIX, просто используйте эту команду для установки Minikube:
Чтобы запустить Minikube после его установки:
Чтобы проверить, что Minikube работает:
Дополнительно нужно установить интерфейс командной строки Kubernetes для конфигурации кластера через консоль:
Один из способов установить Jenkins master — создать docker образ на основе базового образа Jenkins из официального репозитория (учитывайте, что Docker должен быть установлен на локальном компьютере). Для этого создайте dockerfile:
Dockerfile:
from [image_name]:[tag] — docker-файл будет основан на существующем образе. Очевидно, что для нашего docker-файла мы берем базовый образ Jenkins, который можно найти в официальном репозитории Docker.
RUN [command] — запускаем команду внутри образа в процессе сборки. Используем её для установки плагинов, которые могут потребоваться для вашего Jenkins master;
USER [user_name]: — команда сообщает, что все приведенные ниже команды будут выполняться под конкретным пользователем. В нашем случае используем стандартного административного пользователя, чтобы иметь возможность устанавливать дополнительные инструменты внутри образа во время сборки.
Ключевой плагин в контексте статьи — Jenkins «Kubernetes». Он позволяет развернуть Jenkins поверх кластера Kubernetes.
После dockerfile вам нужно создать образ, который можно использовать и запускать в кластере Kubernetes. Если вы используете Minikube, не забывайте, что он работает на локальной машине, но внутри виртуальной.
Minikube не видит docker образы, созданные на локальной машине. Чтобы сделать их видимыми, создайте docker образ прямо внутри виртуальной машины Minikube:
Затем создайте docker образ на основе dockerfile:
После завершения процесса сборки проверьте, что созданный образ существует:
Jenkins master создан и может использоваться в кластере Kubernetes.
Чтобы развернуть приложение в Kubernetes, нужно создать конфигурацию развёртывания. Давайте посмотрим на базовую конфигурацию развёртывания для запуска Jenkins в Kubernetes:
jenkins-deployment.yaml:
Рассмотрим основные параметры в этом файле:
apiVersion указывает, какая версия API Kubernetes будет использоваться;
kind определяет цель yaml файла;
name обозначает имя развёртывания, чтобы идентифицировать его позже в различных других развёртываниях, которые могут возникнуть;
spec отражает спецификацию основных параметров развёртывания и конфигурации;
containers содержит все контейнеры, которые должны быть запущены в указанном развёртывании;
containers.name обозначает имя контейнера развёртывания, чтобы идентифицировать его позже в других различных контейнерах;
image — docker образ, который используется для запуска контейнера;
env — переменные среды, которые передаются внутри контейнера;
ports — секции с портами, которые пересылаются за пределы контейнеров.
volumetMounts — создаётся, чтобы хранить данные вне контейнера.
Давайте установим только что созданное развёртывание в кластер Kubernetes с помощью команды:
Внутри Kubernetes есть еще один очень важный термин, о котором вам знать, — Pod. Это основной строительный блок и самая маленькая единица в кластере Kubernetes. Он создаётся, как только вы выполняете развёртывание.
Поскольку каждое развёртывание должно создавать pod, давайте проверим, что у нас есть недавно созданный pod для развёртывания Jenkins:
Чтобы поддерживать постоянное соединение с pod, пока его IP-адрес может меняться, в игру вступает сервис Kubernetes. Он определяет абстракцию между внешним миром и самими pods и предоставляет доступ — обрабатывает все коммуникации в развёртывании.
Чтобы создать сервис, нам нужно определить yaml файл:
jenkins-service.yaml:
Как только создадите файл, можете запустить его в контейнере Kubernetes с помощью команды:
Развёртывание и сервис созданы. Теперь откроем панель управления Kubernetes и проверим, что они там:
Когда перейдёте в раздел «Обзор», увидите, что развёртывание и модуль «Jenkins» находятся там:
Если зайдёте в pod, можете найти основные журналы Jenkins, которые могут быть очень полезны в случае возникновения проблем во время использования Jenkins CI:
В качестве окончательной проверки, что Jenkins master установлен, попробуем открыть пользовательский интерфейс Jenkins. Прежде всего, нам нужен порт, который служба Jenkins расширяет за пределами кластера Kubernetes. Узнаем его номер:
Также нужен IP-адрес кластера Kubernetes:
В нашем случае результат Jenkins UI URL — 192.168.99.100: 3259.
Теперь настроим Jenkins slave. Поскольку мы установили плагин Kubernetes с помощью dockerfile, нам не нужно ничего устанавливать отдельно.
Чтобы настроить Jenkins slave, нужно знать URL-адрес Kubernetes master и внутренний URL-адрес кластера Jenkins pod. Получить URL-адрес Kubernetes можно с помощью команды:
URL-адрес Jenkins pod стандартный — 8080. Чтобы получить IP-адрес, нужно:
Узнать идентификатор Jenkins pod:
Выполнить команду, которая описывает pods, передающие идентификатор модуля в качестве аргумента. Вы найдёте IP-адрес в выходных данных:
Теперь можно заполнять конфигурацию плагина Kubernetes. Для этого откройте интерфейс Jenkins, перейдите в раздел «Управление Jenkins -> Configure System -> Cloud -> Kubernetes» и заполните «URL-адрес Kubernetes» и «URL Jenkins», используя значения, полученные на предыдущем шаге:
В разделе «Kubernetes Pod Template» настройте образ, который будет использоваться для запуска slaves. Если у вас есть требования к slaves, можете создать ещё один dockerfile с соответствующими изменениями так же, как мы делали для Jenkins master. Если у вас нет специфических требований, можете использовать Jenkins slaves образ, доступный в официальном репозитории Docker hub. В разделе «Kubernetes Pod Template» нужно указать:
Kubernetes Pod Template Name: может быть любым и будет отображаться в качестве приставки для уникальных сгенерированных названий slaves, которые будут запускаться автоматически во время сборки.
Docker image: название docker образа, которое будет использоваться в качестве ссылки для запуска нового Jenkins slave.
Вся конфигурация на месте, и мы готовы к тестам. Давайте создадим две сборки с одним шагом, который имитирует тайм-аут (скажем, 30 секунд) для выполнения длительной операции:
Теперь запустим выполнение для обеих сборок. Вы должны увидеть, что оба плана сборки появляются в окне Build Queue почти сразу:
Если вы применили правильную конфигурацию на предыдущих шагах, вы увидите, что у вас есть два дополнительных исполнителя, и оба имеют приставку «jenkins-slave». Это значит, что узлы были автоматически запущены внутри кластера Kubernetes с помощью плагина Jenkins Kubernetes. И самое главное — они были запущены параллельно:
Также вы можете подтвердить это с помощью панели управления Kubernetes, которая покажет вам пару новых pods:
После завершения сборок вы увидите, что оба исполнителя сборки удалены и больше не доступны внутри кластера:
Так выглядит процесс масштабирования Jenkins с помощью Kubernetes. Напоминаем, что Jenkins можно использовать для добавления всех ваших тестов, включая нагрузочные, в непрерывную интеграцию.
Материал подготовлен на основе статьи «Jenkins + Kubernetes: How to Set Up Jenkins on Top of a Kubernetes Cluster»