构建你的第一个用于CI/CD的Jenkins声明式流水线
构建第一个Jenkins声明式流水线,包含阶段、代理、代码检出、测试、部署门控、凭据和后置操作。
构建你的第一个用于CI/CD的Jenkins声明式流水线
你的第一个Jenkins声明式流水线应该回答一个实际问题:Jenkins能否在正确的分支通过时,检出你的代码、构建、测试并执行部署步骤?Jenkinsfile 将这一工作流作为代码,存放在与你的应用相同的仓库中。
声明式语法是一个很好的起点,因为它提供了可预测的结构:pipeline、agent、stages、steps 和 post。
理解声明式流水线结构
声明式流水线在名为 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 项目类型,点击 OK。
- 在配置页面,向下滚动到 Pipeline 部分。
- 将定义从 Pipeline script 更改为 Pipeline script from SCM。
- 选择你的 SCM(例如 Git)。
- 输入 Repository URL,必要时配置凭据。
- 确保 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:代码检出(源代码管理)
stage('Checkout Source') {
steps {
// 'checkout scm' 步骤根据Jenkins任务配置中定义的设置自动检出代码
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 --label build_id=${BUILD_ID} -t ${CONTAINER_REGISTRY}/${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 image prune -f --filter "label=build_id=$BUILD_ID"'
}
}
}
步骤3:运行和监控流水线
一旦 Jenkinsfile 被提交并推送到Jenkins任务中配置的分支:
- 在Jenkins任务页面,点击 Build Now(或等待SCM轮询/webhook触发)。
- 在 Build History 面板中监控构建。
- 点击正在运行的构建编号,选择 Console Output 查看逐步执行详情。
- 你也可以使用 Stage View 可视化(如果安装了插件)以图形方式查看
Checkout、Build、Test和Deploy阶段的进度。
最佳实践与高级功能
使用库和共享代码
对于复杂或高度重复的步骤,避免在 Jenkinsfile 中直接编写冗长的Groovy代码。相反,使用 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"
'''
}
}
}
代理选择
提示: 始终使用
label具体定义你的agent,而不是使用agent any。使用agent any意味着流水线可能在Jenkins控制器节点上运行,这存在安全风险并可能影响控制器性能。确保你已正确配置Jenkins代理(节点),并安装了必要的工具(Docker、Maven、Node.js)。
要点
保持第一个流水线简单可靠:选择一个真实的代理标签,检出代码,构建,测试,按分支门控部署,并将密钥保存在Jenkins凭据中。一旦运行正常,再逐步添加制品发布、安全扫描和环境提升。