Jenkins в Kubernetes: динамические pod-агенты

Рейтинг: 45.3% · 9 голосов
Подробный курс по Jenkins и CI/CD: установка и настройка, плагины и Configuration as Code, конвейеры (pipeline) и Jenkinsfile, declarative и scripted, агенты, Docker и Kubernetes, общие библиотеки на Groovy, безопасность и credentials, интеграции (SonarQube, артефакты), траблшутинг. Актуально на 2026.
Ответить
Аватара пользователя
Andrey_CICD
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Jenkins в Kubernetes: динамические pod-агенты

Сообщение Andrey_CICD »

Оглавление курса (47)
  1. Что такое Jenkins и зачем нужен CI/CD
  2. Jenkins в 2026: версии, экосистема и сравнение с GitLab CI и GitHub Actions
  3. Архитектура Jenkins: контроллер, агенты, узлы и исполнители
  4. Установка Jenkins: пакеты, Docker и Kubernetes
  5. Первичная настройка Jenkins: мастер, плагины, пользователи
  6. Плагины Jenkins: установка, обновление и ключевой набор
  7. Configuration as Code (JCasC): настройка Jenkins декларативно
  8. Конвейеры Jenkins и Jenkinsfile: pipeline as code
  9. Scripted против Declarative: два синтаксиса конвейера
  10. Структура конвейера: node, stage, steps и первый pipeline
  11. Генератор сниппетов, запуск конвейера и Replay
  12. Типы заданий Jenkins: Freestyle, Pipeline, Multibranch и Organization
  13. Декларативный конвейер: структура pipeline, agent, stages
  14. agent, environment и переменные в конвейере
  15. tools, options, parameters и triggers в декларативном конвейере
  16. stages, parallel и matrix: организация этапов
  17. Условное выполнение when и блок post
  18. Триггеры сборки: webhook от GitHub, SCM polling и расписание
  19. Параметры сборки и пользовательский ввод
  20. Управление потоком: timeout, retry, sleep и waitUntil
  21. Параллелизм и блокировки: parallel, lock, milestone
  22. Постобработка и уведомления о результате сборки
  23. Groovy для Jenkins: основы скриптового конвейера
  24. Скриптовый конвейер: логика, циклы и функции
  25. Общие библиотеки Jenkins: Shared Libraries
  26. Подключение и загрузка общих библиотек
  27. Шаги оболочки: sh, bat, powershell и коды возврата
  28. Переменные среды, withEnv и рабочие пространства
  29. Работа с файлами, артефактами и отпечатками
  30. Сборка проектов в конвейере: Maven, Gradle, npm
  31. Качество кода: SonarQube и покрытие тестами
  32. Управление артефактами: публикация в Nexus и Artifactory
  33. Docker в Jenkins: образы как агенты сборки
  34. Сборка и публикация Docker-образов из конвейера
  35. Jenkins в Kubernetes: динамические pod-агенты (вы здесь)
  36. Развёртывание в Kubernetes из конвейера
  37. Безопасность Jenkins: аутентификация и матрица прав
  38. Учётные данные Jenkins: credentials в конвейере
  39. Безопасность сценариев: Groovy sandbox и Vault
  40. Уведомления и отчёты: email, Slack, Telegram, HTML
  41. Blue Ocean и интерфейс Jenkins в 2026
  42. Автоматизация Jenkins: CLI, REST API и script console
  43. Поиск и устранение неисправностей: читаем логи конвейера
  44. Типичные ошибки конвейера: сериализация и неутверждённый код
  45. Эксплуатация Jenkins: бэкап, обновление, масштабирование
  46. Конвертация и миграция: от Freestyle к Jenkinsfile
  47. Итог: сквозной CI/CD конвейер и Jenkins против альтернатив в 2026
Знакомая картина: у тебя три постоянных агента на статичных виртуалках. Один забит сборкой на полдня, второй простаивает, а на третьем кто-то полгода назад оставил кривую версию Node, и теперь каждая вторая сборка падает "только на этом ноде". Ты платишь за железо круглосуточно, но в пике все равно не хватает мощности, а в выходные половина мощностей греет воздух. И главная боль - изоляция: сборки тащат друг другу мусор в общие каталоги, кэши конфликтуют, "у меня локально работает, а на агенте нет".

Связка jenkins kubernetes решает это радикально. Идея простая до гениальности: под каждую сборку Kubernetes поднимает свежий эфемерный pod, агент в нем подключается к контроллеру, делает работу и сразу после удаляется. Никакого общего состояния, никакого простоя, никаких "грязных" нод. Это и есть cloud-native подход, которого в книге Ластера 2018 года еще не было как стандарта - тогда динамические агенты считались экзотикой, а сегодня это база масштабируемого Jenkins.

Как работает kubernetes-плагин и эфемерные pod-агенты

За всю магию отвечает kubernetes-plugin. Логика такая. Контроллер видит, что в очереди появилась задача с меткой (label), под которую настроен pod-шаблон. Плагин через Kubernetes API создает pod по этому шаблону. Внутри pod обязательно есть контейнер агента (исторически он называется jnlp - там запускается inbound-агент, который сам стучится на контроллер), плюс любые твои сборочные контейнеры: maven, node, docker-cli, kubectl, что угодно. Pod регистрируется как агент, забирает задачу, выполняет шаги. Как только сборка закончилась (или истек idle-таймаут), pod уничтожается.

Что это дает на практике:
  • Эластичность. Прилетело 50 сборок одновременно - кластер поднимет 50 pod (в пределах квот). Тихо ночью - ноль агентов, ноль трат. С автоскейлером узлов кластер сам докупает железо под пик и отдает обратно.
  • Идеальная изоляция. Каждая сборка в своем pod со своей файловой системой и сетевым неймспейсом. Сборки физически не могут испортить состояние друг другу.
  • Воспроизводимость. Окружение описано в YAML и лежит рядом с кодом. Никакого ручного доустанавливания пакетов на агенте - что в шаблоне, то и в сборке.
Именно поэтому связку jenkins k8s называют будущим масштабируемого CI: ты перестаешь администрировать парк агентов и начинаешь описывать окружение декларативно.

Изображение

Запуск Jenkins-контроллера в кластере через Helm

Прежде чем раздавать pod-агенты, сам контроллер обычно тоже живет в кластере. Канонический способ поставить jenkins в kubernetes - официальный Helm-чарт. Он сразу настраивает ServiceAccount с правами на создание pod, ставит kubernetes-plugin и подключает Configuration as Code (JCasC), так что облако агентов конфигурируется кодом, а не кликами в UI.

Код: Выделить всё

helm repo add jenkins https://charts.jenkins.io
helm repo update
helm upgrade --install jenkins jenkins/jenkins \
  --namespace jenkins --create-namespace \
  -f values.yaml
Само облако агентов описывается через JCasC прямо в values чарта. Минимальный кусок, который объясняет контроллеру, как и где поднимать pod:

Код: Выделить всё

controller:
  JCasC:
    configScripts:
      kube-cloud: |
        jenkins:
          clouds:
            - kubernetes:
                name: "k8s"
                namespace: "jenkins"
                jenkinsUrl: "http://jenkins.jenkins.svc.cluster.local:8080"
                containerCapStr: "50"
                templates:
                  - name: "default"
                    label: "k8s-agent"
                    containers:
                      - name: "jnlp"
                        image: "jenkins/inbound-agent:latest-jdk21"
Обрати внимание на jenkinsUrl - это внутренний DNS-адрес сервиса контроллера в кластере, по нему inbound-агент находит контроллер. И на actуальную базу 2026: образ агента на JDK 21, потому что современные LTS-линии Jenkins (баз овая линия около 2.541.x на начало 2026) уже требуют как минимум Java 17, а ветка weekly с января 2026 - Java 21. Проект официально рекомендует Java 21, так что новые окружения сразу собирай под нее, чтобы не упереться в апгрейд через полгода.

Практика: pod-агенты в Jenkinsfile (jenkins pod agent на деле)

Самый чистый способ 2026 года - описать pod прямо в pipeline через declarative-блок agent с kubernetes и сырым YAML. Сборочные контейнеры объявляешь обычным Kubernetes-манифестом, а шаги загоняешь в нужный контейнер директивой container. Вот рабочий пример сборки и публикации образа (jenkins docker kubernetes - классический сценарий, только docker-демона тут нет, образ собираем kaniko, без привилегий):

Код: Выделить всё

pipeline {
  agent {
    kubernetes {
      yaml '''
        apiVersion: v1
        kind: Pod
        spec:
          containers:
          - name: maven
            image: maven:3.9-eclipse-temurin-21
            command: ["sleep"]
            args: ["infinity"]
          - name: kaniko
            image: gcr.io/kaniko-project/executor:debug
            command: ["sleep"]
            args: ["infinity"]
      '''
      defaultContainer 'maven'
      retries 2
    }
  }
  stages {
    stage('Build & Test') {
      steps {
        sh 'mvn -B clean verify'
      }
    }
    stage('Image') {
      steps {
        container('kaniko') {
          sh '''
            /kaniko/executor \
              --context `pwd` \
              --dockerfile Dockerfile \
              --destination registry.cyberlake.ru/app:$BUILD_NUMBER
          '''
        }
      }
    }
  }
}
Здесь defaultContainer задает контейнер по умолчанию для всех sh-шагов, а явный container('kaniko') переключает шаг в нужный контейнер. Директива retries (доступна в declarative-агенте kubernetes) повторит запуск, если pod не поднялся из-за инфраструктурного сбоя - очень полезно на нагруженном кластере.

Если шаблон используется в нескольких пайплайнах, выноси его в общий podTemplate (scripted-стиль), где динамика уместна. Важная деталь: podTemplate создает эфемерный шаблон только на время своего блока и удаляет его сразу после - ровно та самая одноразовость:

Код: Выделить всё

podTemplate(yaml: '''
  apiVersion: v1
  kind: Pod
  spec:
    containers:
    - name: node
      image: node:22-bookworm
      command: ["sleep"]
      args: ["infinity"]
''') {
  node(POD_LABEL) {
    container('node') {
      checkout scm
      sh 'npm ci && npm test'
    }
  }
}
Переменная POD_LABEL генерируется плагином автоматически и привязывает блок node именно к этому поднятому pod - так задача гарантированно едет на свой агент, а не на чужой.

Типичные грабли
  • Забыли command/args в сборочном контейнере. Если контейнер с образом maven просто запустится и завершится, pod упадет в CrashLoopBackOff. Держи контейнеры живыми через sleep infinity - тогда Jenkins выполняет в них шаги.
  • Нет прав у ServiceAccount. Контроллер должен иметь RBAC-права на create/delete/watch pod в нужном namespace. Helm-чарт это настраивает, но при ручной установке легко забыть Role и RoleBinding - агенты просто не поднимутся.
  • Неверный jenkinsUrl. Если внутри кластера агент не может достучаться до контроллера (указали внешний адрес или закрыли порт inbound-агента), pod создается, висит и отваливается по таймауту. Используй внутренний svc-адрес.
  • Слишком жирный pod без лимитов. Без resources requests/limits Kubernetes может выселить агент в середине сборки. Указывай ресурсы для каждого контейнера.
  • Ставка на Blue Ocean для визуализации. Blue Ocean с 2023 в режиме поддержки - только security-фиксы, новых фич не будет. Это наследие; смотри сборки в штатном Pipeline UI, не строй процессы вокруг него.
Для ориентира: облачные конкуренты - GitHub Actions и GitLab CI - давно работают по похожей модели одноразовых раннеров в контейнерах. Сильная сторона Jenkins на Kubernetes в том, что ты получаешь ту же эфемерность и эластичность, но с полным контролем над кластером, без вендор-лока и с гибкостью pipeline-as-code там, где облачным YAML-only решениям не хватает динамики.

Мини-лаба
  • Подними тестовый кластер (kind или minikube) и поставь контроллер Helm-чартом в namespace jenkins.
  • Проверь, что в Manage Jenkins появилось облако k8s (через JCasC), и запусти простейший pipeline с agent kubernetes и одним контейнером alpine, выполнив sh 'echo hello && hostname'.
  • Запусти сборку и параллельно следи за pod: kubectl get pods -n jenkins -w. Убедись, что pod рождается на старте и исчезает после.
  • Запусти 5 сборок разом и посмотри, как кластер поднимает несколько pod одновременно - это та самая эластичность вживую.
Контрольные вопросы
  • Зачем в pod-шаблоне контейнеру задают command sleep infinity и что будет без этого?
  • Чем declarative-блок agent kubernetes отличается от шага podTemplate и когда выбирать второй?
  • Какие права в кластере нужны контроллеру, чтобы поднимать эфемерные агенты, и кто их настраивает при установке через Helm?
  • Почему jenkinsUrl должен указывать на внутренний адрес сервиса, а не на внешний домен?
Итог

Динамические pod-агенты превращают Jenkins из парка вечно живых нод в эластичную фабрику одноразовых окружений: pod под сборку, чистая изоляция, оплата только за работу. Контроллер ставим Helm-чартом, облако описываем через JCasC, окружение - YAML рядом с кодом. Это и есть зрелый cloud-native Jenkins 2026 года, который масштабируется вместе с твоей нагрузкой, а не упирается в нее.
👍4 ❤️2 🔥 😄 🤔1
Аватара пользователя
toonis
Сообщения: 1
Зарегистрирован: 29 май 2026, 05:24

Re: Jenkins в Kubernetes: динамические pod-агенты

Сообщение toonis »

Перешли на kind у себя в тестах по этому уроку, и да, CrashLoopBackOff на maven-контейнере поймал почти сразу. sleep infinity реально спасает, спасибо что предупредили.
👍2 ❤️1 🔥 😄 🤔1
Аватара пользователя
mbox01
Сообщения: 1
Зарегистрирован: 13 май 2026, 23:13

Re: Jenkins в Kubernetes: динамические pod-агенты

Сообщение mbox01 »

А есть смысл держать пару статичных агентов рядом с k8s-облаком? Боюсь холодного старта pod на первой сборке после простоя, иногда минуту ждать приходится.
👍3 ❤️1 🔥 😄 🤔
Ответить
← Предыдущая глава
Сборка и публикация Docker-образов из конвейера
Следующая глава →
Развёртывание в Kubernetes из конвейера

Все главы курса «Jenkins: конвейеры CI/CD от основ до продакшена»

Поделиться темой: ✈ Telegram VK
Похожие запросы: что такое jenkins простыми словамикак установить jenkins на linux и в dockerпервичная настройка jenkins после установкикакие плагины jenkins нужны новичкукак настроить агенты jenkins для сборкиcicd для начинающих с чего начать на jenkins

Вернуться в «Jenkins: конвейеры CI/CD от основ до продакшена»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость