Создайте свой первый декларативный конвейер Jenkins для CI/CD

Создайте первый декларативный конвейер Jenkins с этапами, агентами, проверкой кода, тестами, шлюзами развертывания, учетными данными и пост-действиями.

Создайте свой первый декларативный конвейер Jenkins для CI/CD

Ваш первый декларативный конвейер Jenkins должен ответить на практический вопрос: может ли Jenkins проверить ваш код, собрать его, протестировать и выполнить шаги развертывания только при прохождении правильной ветки? Jenkinsfile предоставляет этот рабочий процесс как код в том же репозитории, что и ваше приложение.

Декларативный синтаксис — хорошая отправная точка, поскольку он дает предсказуемую структуру: pipeline, agent, stages, steps и post.

Понимание структуры декларативного конвейера

Декларативный конвейер определяет весь рабочий процесс в файле с именем Jenkinsfile, который хранится вместе с кодом вашего приложения в вашем SCM-репозитории (например, Git). Эта практика известна как Pipeline as Code.

Основные элементы декларативного конвейера

Декларативный конвейер должен содержать следующие блоки верхнего уровня:

  1. pipeline: Обязательный внешний блок, определяющий содержимое конвейера.
  2. agent: Указывает, где будет выполняться конвейер или конкретный этап (например, any, none или определенные метки).
  3. stages: Содержит один или несколько последовательных блоков stage.
  4. stage: Определяет концептуальный блок работы (например, Сборка, Тестирование, Развертывание).
  5. steps: Содержит одну или несколько команд или функций, выполняемых в рамках stage.
pipeline {
    agent any 
    environment { // Опционально: Определяет переменные окружения
        APP_VERSION = '1.0.0'
    }
    stages {
        stage('Build') {
            steps {
                // Команды здесь
            }
        }
    }
    post { // Опционально: Действия, выполняемые после завершения конвейера
        always { 
            echo 'Pipeline finished.' 
        }
    }
}

Шаг 1: Настройка задания Jenkins

Чтобы запустить конвейер из кода, вам нужно настроить задание Jenkins для чтения Jenkinsfile из вашего репозитория.

  1. Перейдите на панель управления Jenkins и выберите Новый элемент.
  2. Введите имя для вашего конвейера (например, my-first-ci-pipeline).
  3. Выберите тип элемента Pipeline и нажмите ОК.
  4. На странице конфигурации прокрутите вниз до раздела Pipeline.
  5. Измените определение с Pipeline script на Pipeline script from SCM.
  6. Выберите вашу SCM (например, Git).
  7. Введите URL репозитория и настройте учетные данные при необходимости.
  8. Убедитесь, что Путь к скрипту установлен на Jenkinsfile (по умолчанию).

Шаг 2: Определение Jenkinsfile для CI/CD

Мы создадим комплексный Jenkinsfile, который имитирует простой рабочий процесс CI/CD, интегрируя стандартные этапы для успешного развертывания.

Предположим, у вас есть структура репозитория, содержащая исходный код вашего приложения (например, простой проект на Python или Java) и Jenkinsfile в корне.

Полный пример декларативного конвейера

Этот конвейер использует агент node (если настроен) и использует базовые шаги оболочки (sh) для имитации реальной работы. Этап развертывания является условным и выполняется только после успешного завершения предыдущих этапов.

// Jenkinsfile
pipeline {
    // 1. Определение агента: Указывает, где выполняется весь конвейер
    agent { 
        label 'my-build-agent' // Используйте конкретную метку, если доступно, или 'any'
    }
    
    // 2. Переменные окружения: Определите переменные, используемые во всем конвейере
    environment {
        CONTAINER_REGISTRY = 'registry.example.com'
        IMAGE_NAME = 'myapp'
    }
    
    stages {
        
        // Этап 1: Получение кода (Управление исходным кодом)
        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 --label build_id=${BUILD_ID} -t ${CONTAINER_REGISTRY}/${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 "Развертывание в среду Staging выполнено успешно."
                }
            }
        }
    }
    
    // 3. Пост-действия: Определите действия в зависимости от конечного статуса конвейера
    post {
        success {
            echo 'Конвейер успешно завершен. Уведомление команды через Slack...'
            // slackSend channel: '#devops-alerts', message: 'CI/CD Success!'
        }
        failure {
            echo 'Конвейер завершился ошибкой. Просмотрите логи для выявления ошибок.'
        }
        cleanup {
            sh 'docker image prune -f --filter "label=build_id=$BUILD_ID"'
        }
    }
}

Шаг 3: Запуск и мониторинг конвейера

После того как Jenkinsfile зафиксирован и отправлен в ветку, настроенную в вашем задании Jenkins:

  1. На странице задания Jenkins нажмите Собрать сейчас (или дождитесь опроса SCM/триггера вебхука).
  2. Отслеживайте сборку на панели История сборок.
  3. Нажмите на номер выполняемой сборки и выберите Вывод консоли, чтобы просмотреть детали выполнения пошагово.
  4. Вы также можете использовать визуализацию 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 '''
                printf '%s' "$PASS" | docker login \
                  --username "$USER" \
                  --password-stdin "$CONTAINER_REGISTRY"
            '''
        }
    }
}

Выбор агента

Совет: Всегда определяйте своего agent конкретно, используя label, а не agent any. Использование agent any означает, что конвейер может выполняться на узле контроллера Jenkins, что представляет угрозу безопасности и может повлиять на производительность контроллера. Убедитесь, что у вас правильно настроены агенты Jenkins (узлы) с необходимыми инструментами (Docker, Maven, Node.js).

Вывод

Сделайте первый конвейер скучным и надежным: выберите реальную метку агента, получите код, соберите, протестируйте, ограничьте развертывание по ветке и храните секреты в учетных данных Jenkins. Как только это заработает, добавляйте публикацию артефактов, сканирование безопасности и продвижение по средам по одному шагу за раз.