Создание вашего первого декларативного конвейера Jenkins для CI/CD
Jenkins является де-факто стандартом для серверов автоматизации с открытым исходным кодом, служащих основой для конвейеров непрерывной интеграции и непрерывной доставки (CI/CD) в тысячах организаций. Хотя Jenkins предлагает два типа синтаксиса конвейеров — сценарный (Scripted) и декларативный (Declarative) — синтаксис Declarative Pipeline является рекомендуемым подходом для большинства пользователей благодаря своей простоте, структурированности и более читабельному Groovy DSL.
Это руководство предоставляет всесторонний, пошаговый учебник по созданию вашего самого первого функционального декларативного конвейера Jenkins. Мы рассмотрим интеграцию управления исходным кодом (SCM), определение среды сборки, выполнение тестирования и реализацию примера этапа развертывания, что даст вам прочную основу для автоматизации жизненного цикла доставки программного обеспечения.
Понимание структуры декларативного конвейера
Декларативный конвейер определяет весь рабочий процесс в файле с именем Jenkinsfile, который хранится вместе с кодом вашего приложения в вашем репозитории SCM (например, Git). Эта практика известна как конвейер как код (Pipeline as Code).
Основные элементы декларативного конвейера
Декларативный конвейер должен содержать следующие блоки верхнего уровня:
pipeline: Обязательный внешний блок, определяющий содержимое конвейера.agent: Указывает, где будет выполняться конвейер или конкретный этап (например,any,noneили определенные метки).stages: Содержит один или несколько последовательных блоковstage.stage: Определяет концептуальный блок работы (например, Сборка, Тестирование, Развертывание).steps: Содержит одну или несколько команд или функций, выполняемых внутриstage.
pipeline {
agent any
environment { // Необязательно: Определяет переменные окружения
APP_VERSION = '1.0.0'
}
stages {
stage('Build') {
steps {
// Команды размещаются здесь
}
}
}
post { // Необязательно: Действия, выполняемые после завершения конвейера
always {
echo 'Pipeline finished.'
}
}
}
Шаг 1: Настройка задания Jenkins
Чтобы запустить конвейер из кода, вам нужно настроить задание Jenkins для чтения Jenkinsfile из вашего репозитория.
- Перейдите на панель управления Jenkins и выберите Создать элемент (New Item).
- Введите имя для вашего конвейера (например,
my-first-ci-pipeline). - Выберите тип элемента Конвейер (Pipeline) и нажмите ОК.
- На странице конфигурации прокрутите вниз до раздела Конвейер (Pipeline).
- Измените определение с Скрипт конвейера (Pipeline script) на Скрипт конвейера из SCM (Pipeline script from SCM).
- Выберите ваш SCM (например, Git).
- Введите URL репозитория (Repository URL) и настройте учетные данные при необходимости.
- Убедитесь, что Путь к скрипту (Script Path) установлен как
Jenkinsfile(по умолчанию).
Шаг 2: Определение Jenkinsfile для CI/CD
Мы создадим всеобъемлющий Jenkinsfile, который имитирует простой рабочий процесс CI/CD, интегрируя стандартные этапы для успешного развертывания.
Предположим, у вас есть структура репозитория, содержащая исходный код вашего приложения (например, простой проект на Python или Java) и Jenkinsfile в корне.
Полный пример декларативного конвейера
Этот конвейер использует node agent (если настроен) и применяет базовые шаги оболочки (sh) для имитации реальной работы. Этап развертывания является условным, он выполняется только после успешного завершения предыдущих этапов.
// Jenkinsfile
pipeline {
// 1. Определение агента: Указывает, где выполняется весь конвейер
agent {
label 'my-build-agent' // Используйте конкретную метку, если доступна, или 'any'
}
// 2. Переменные окружения: Определяют переменные, доступные во всем конвейере
environment {
CONTAINER_REGISTRY = 'registry.example.com'
IMAGE_NAME = 'myapp'
}
stages {
// Этап 1: Checkout (Управление исходным кодом)
stage('Checkout Source') {
steps {
// Шаг 'checkout scm' автоматически выгружает код
// на основе конфигурации, определенной в настройках задания Jenkins.
checkout scm
sh 'echo "Исходный код успешно выгружен."
}
}
// Этап 2: Сборка артефактов
stage('Build Artifact') {
steps {
sh 'echo "Начинается сборка для $IMAGE_NAME:$BUILD_ID"'
// Симуляция: Сборка Docker-образа или компиляция jar/war файла
sh "docker build -t ${IMAGE_NAME}:${BUILD_ID} ."
}
}
// Этап 3: Тестирование и проверки качества
stage('Run Tests') {
steps {
sh './run_unit_tests.sh'
sh 'echo "Запуск интеграционных тестов..."'
// Пример сбора результатов тестов (требует соответствующих плагинов)
// junit '**/target/surefire-reports/*.xml'
}
}
// Этап 4: Развертывание (Условное)
stage('Deploy to Staging') {
// Директива 'when' гарантирует, что этап выполняется только при определенных условиях
when {
branch 'main'
}
steps {
sh "docker push ${CONTAINER_REGISTRY}/${IMAGE_NAME}:${BUILD_ID}"
sh 'kubectl apply -f k8s/deployment-staging.yaml'
script {
// Блоки 'script' позволяют использовать традиционную Groovy-логику внутри декларативных шагов
echo "Развертывание в тестовую среду успешно."
}
}
}
}
// 3. Пост-действия: Определяют действия на основе конечного статуса конвейера
post {
success {
echo 'Конвейер успешно завершен. Уведомляем команду через Slack...'
// slackSend channel: '#devops-alerts', message: 'CI/CD Success!'
}
failure {
echo 'Конвейер завершился с ошибкой. Проверьте логи на наличие ошибок.'
}
cleanup {
sh 'docker rmi -f $(docker images -aq --filter label=build_id=$BUILD_ID)'
}
}
}
Шаг 3: Запуск и мониторинг конвейера
После того как Jenkinsfile закоммичен и отправлен в ветку, настроенную в вашем задании Jenkins:
- На странице задания Jenkins нажмите Собрать сейчас (Build Now) (или дождитесь опроса SCM/триггера веб-хука).
- Отслеживайте сборку на панели История сборок (Build History).
- Нажмите на номер запущенной сборки и выберите Вывод консоли (Console Output), чтобы просмотреть детали выполнения пошагово.
- Вы также можете использовать визуализацию Stage View (если плагин установлен), чтобы графически увидеть прогресс этапов
Checkout,Build,TestиDeploy.
Лучшие практики и расширенные функции
Использование библиотек и общего кода
Для сложных или сильно повторяющихся шагов избегайте написания многословного Groovy напрямую в Jenkinsfile. Вместо этого используйте Общие библиотеки (Shared Libraries). Эти внешние библиотеки позволяют определять общие функции (например, стандартные процедуры развертывания или функции уведомлений), которые могут быть вызваны из нескольких конвейеров, делая ваш Jenkinsfile более чистым.
// Вызов шага общей библиотеки
stage('Custom Setup') {
steps {
customLibrary.initializeEnvironment(env: 'prod')
}
}
Работа с учетными данными
Никогда не хардкодьте конфиденциальную информацию (пароли, токены, ключи API) напрямую в Jenkinsfile. Используйте встроенную систему управления учетными данными Jenkins.
Шаг withCredentials позволяет безопасно получить доступ к хранимым секретам:
stage('Authenticate Registry') {
steps {
withCredentials([usernamePassword(credentialsId: 'docker-registry-creds',
passwordVariable: 'PASS',
usernameVariable: 'USER')]) {
sh "docker login -u ${USER} -p ${PASS} ${CONTAINER_REGISTRY}"
}
}
}
Внимание: Выбор агента
Совет: Всегда определяйте свой
agentконкретно, используяlabel, а неagent any. Использованиеagent anyозначает, что конвейер может быть запущен на узле-контроллере Jenkins, что является риском безопасности и может повлиять на производительность контроллера. Убедитесь, что у вас правильно настроены агенты Jenkins (узлы) с установленными необходимыми инструментами (Docker, Maven, Node.js).
Заключение
Декларативный конвейер Jenkins предлагает мощную, читабельную и поддерживаемую основу для реализации непрерывной интеграции и непрерывной доставки. Определяя структуру рабочего процесса — включая агентов, переменные окружения, последовательные этапы и действия после сборки — вы получаете полную прозрачность и контроль над процессом автоматизации программного обеспечения. С этой установленной основой Jenkinsfile вы теперь готовы интегрировать более сложные шаги, такие как автоматическое сканирование безопасности, публикация артефактов и продвижение в различные среды.