构建你的第一个 Jenkins 声明式 CI/CD 流水线

通过构建你的第一个 Jenkins 声明式流水线,释放自动化软件交付的强大力量。这份全面的指南提供了一个循序渐进的教程,涵盖了完整的 CI/CD 工作流程,从集成源代码管理到定义安全的构建、测试和条件部署阶段。学习 `Jenkinsfile` 的基本结构,并实施处理代理和凭据的最佳实践,确保为你的项目实现健壮且可维护的自动化。

30 浏览量

构建您的第一个用于 CI/CD 的 Jenkins 声明式流水线

Jenkins 是开源自动化服务器的实际标准,是数千个组织中持续集成和持续交付 (CI/CD) 流水线的核心支柱。Jenkins 提供了两种流水线语法——脚本式 (Scripted) 和声明式 (Declarative)——但由于其更简单、结构化且更具可读性的 Groovy DSL,声明式流水线语法是大多数用户的推荐方法。

本指南提供了一个全面的分步教程,指导您构建第一个功能性的 Jenkins 声明式流水线。我们将涵盖集成源代码管理 (SCM)、定义构建环境、执行测试以及实现一个示例部署阶段,为您自动化软件交付生命周期奠定坚实的基础。

了解声明式流水线结构

声明式流水线将整个工作流程定义在一个名为 Jenkinsfile 的文件中,该文件与您的应用程序代码一起存储在您的 SCM 仓库中(例如 Git)。这种实践被称为 Pipeline as Code(流水线即代码)。

声明式流水线的核心元素

声明式流水线必须包含以下顶级块:

  1. pipeline: 定义流水线内容的必需的最外层块。
  2. agent: 指定流水线或特定阶段将在何处执行(例如,anynone 或特定的标签)。
  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 Job

要从代码运行流水线,您需要配置一个 Jenkins Job,使其从您的仓库中读取 Jenkinsfile

  1. 导航到您的 Jenkins 仪表板并选择新建项目 (New Item)
  2. 输入您的流水线名称(例如,my-first-ci-pipeline)。
  3. 选择流水线 (Pipeline)项目类型,然后单击确定 (OK)
  4. 在配置页面中,向下滚动到流水线 (Pipeline)部分。
  5. 将定义从 流水线脚本 (Pipeline script) 更改为来自 SCM 的流水线脚本 (Pipeline script from SCM)
  6. 选择您的 SCM(例如 Git)。
  7. 输入仓库 URL (Repository URL),并在必要时配置您的凭证。
  8. 确保脚本路径 (Script Path)设置为 Jenkinsfile(默认值)。

步骤 2:定义用于 CI/CD 的 Jenkinsfile

我们将创建一个全面的 Jenkinsfile,模拟一个简单的 CI/CD 工作流程,集成了用于成功部署的标准阶段。

假设您的仓库结构包含应用程序源代码(例如,一个简单的 Python 或 Java 项目)以及位于根目录的 Jenkinsfile

完整的声明式流水线示例

此流水线使用 node 代理(如果已配置),并利用基本 shell 步骤 (sh) 来模拟实际工作。部署阶段是条件性的,仅在前一阶段成功完成后运行。

// Jenkinsfile
pipeline {
    // 1. 代理定义:指定整个流水线的运行位置
    agent { 
        label 'my-build-agent' // 如果可用,使用特定标签,或使用 'any'
    }

    // 2. 环境变量:定义可在整个流水线中使用的变量
    environment {
        CONTAINER_REGISTRY = 'registry.example.com'
        IMAGE_NAME = 'myapp'
    }

    stages {

        // 阶段 1:检出 (Source Code Management)
        stage('Checkout Source') {
            steps {
                // 'checkout scm' 步骤根据 Jenkins Job 设置中定义的配置
                // 自动检出代码。
                checkout scm
                sh 'echo "Source code successfully checked out."
            }
        }

        // 阶段 2:构建产物
        stage('Build Artifact') {
            steps {
                sh 'echo "Starting build for $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 "Running integration tests..."'
                // 收集测试结果的示例(需要适当的插件)
                // 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 "Deployment successful to Staging environment."
                }
            }
        }
    }

    // 3. 后置操作:根据最终的流水线状态定义操作
    post {
        success {
            echo 'Pipeline completed successfully. Notifying team via Slack...'
            // slackSend channel: '#devops-alerts', message: 'CI/CD Success!'
        }
        failure {
            echo 'Pipeline failed. Review logs for errors.'
        }
        cleanup {
            sh 'docker rmi -f $(docker images -aq --filter label=build_id=$BUILD_ID)'
        }
    }
}

步骤 3:运行和监控流水线

一旦 Jenkinsfile 被提交并推送到您 Jenkins Job 中配置的分支:

  1. 在 Jenkins Job 页面上,单击立即构建 (Build Now)(或等待 SCM 轮询/Webhook 触发)。
  2. 构建历史 (Build History)面板中监控构建。
  3. 单击正在运行的构建编号,然后选择控制台输出 (Console Output)以逐步查看执行详情。
  4. 您还可以使用阶段视图 (Stage View)可视化功能(如果安装了插件)以图形方式查看 CheckoutBuildTestDeploy 阶段的进度。

最佳实践和高级功能

利用库和共享代码

对于复杂或高度重复的步骤,请避免直接在 Jenkinsfile 中编写冗长的 Groovy 代码。相反,应使用共享库 (Shared Libraries)。这些外部库允许您定义可从多个流水线调用的通用函数(如标准部署例程或通知函数),从而使您的 Jenkinsfile 更简洁。

// 调用共享库步骤
stage('Custom Setup') {
    steps {
        customLibrary.initializeEnvironment(env: 'prod')
    }
}

使用凭证

切勿将敏感信息(密码、令牌、API 密钥)直接硬编码到 Jenkinsfile 中。请使用 Jenkins 内置的凭证管理系统 (Credentials Management system)。

withCredentials 步骤允许您安全地访问存储的密钥:

stage('Authenticate Registry') {
    steps {
        withCredentials([usernamePassword(credentialsId: 'docker-registry-creds', 
                                          passwordVariable: 'PASS', 
                                          usernameVariable: 'USER')]) {
            sh "docker login -u ${USER} -p ${PASS} ${CONTAINER_REGISTRY}"
        }
    }
}

警告:代理选择

提示: 始终使用 label 具体定义您的 agent,而不是使用 agent any。使用 agent any 意味着流水线可能会在 Jenkins 控制器节点上运行,这会带来安全风险并可能影响控制器性能。请确保您已正确配置了安装有所需工具(Docker、Maven、Node.js)的 Jenkins 代理(节点)。

结论

Jenkins 声明式流水线为实现持续集成和持续交付提供了一个强大、可读且可维护的框架。通过定义工作流程结构——包括代理、环境变量、顺序阶段和构建后操作——您可以对软件自动化过程获得完全的可见性和控制权。在建立了这一基础 Jenkinsfile 之后,您现在可以集成更复杂的步骤,例如自动化安全扫描、产物发布和多环境晋升。