Jenkins入门实战:从流水线搭建到自动部署
Jenkins 入门实战:从流水线搭建到自动部署
持续集成(CI)和持续交付(CD)几乎是每个研发团队的必修课。Jenkins 是最老牌的开源自动化服务器之一,它把「编译、测试、打包、部署」这些重复劳动变成了流水线里的一行配置,让工程师把精力放在写代码本身。
本文从零开始,带你搭起一条能真正跑起来的 Jenkins 流水线。
一、Jenkins 是什么
Jenkins 是一个开源的自动化构建与持续交付工具,用 Java 编写。核心能力可以概括为四点:
| 能力 | 说明 |
|---|---|
| 持续集成 | 每次代码提交自动触发编译与单元测试 |
| 持续交付 | 测试通过后自动把构件推送到测试/生产环境 |
| 自动化运维 | 定时任务、备份、巡检等重复操作交给它 |
| 插件生态 | 数百个官方与社区插件,几乎覆盖所有主流工具 |
它的定位不是替代 Git、Gradle 或 Maven,而是站在这些工具前面做编排:谁在什么时机触发、跑哪些步骤、成功后往哪走,全由 Jenkins 决定。
二、部署 Jenkins
2.1 用 Docker 快速启动
最省事的方式是官方镜像:
docker run -d \
--name jenkins \
-p 8080:8080 \
-v jenkins_home:/var/jenkins_home \
--restart unless-stopped \
jenkins/jenkins:lts
容器启动后需要解锁,初始管理员密码在日志里:
docker logs jenkins 2>&1 | grep -i "initial admin password"
复制该密码,浏览器打开 http://<服务器IP>:8080,粘贴并进入解锁向导,然后按提示安装推荐插件。
2.2 权限与凭证管理
生产环境千万别让 Jenkins 以 root 身份运行。更重要的是不要把账号密码明文写在 Pipeline 里,统一放到凭证库:
进入「Manage Jenkins → Credentials → System → Global credentials」,添加一条 Secret text,ID 命名为 docker-registry-token。后续在脚本里用 credentials('docker-registry-token') 引用,Jenkins 会自动注入真实值,日志里只会显示 ****。
三、第一个任务:Hello Pipeline
新建任务时选择 Pipeline,直接粘贴脚本:
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello, Jenkins!'
sh 'echo "当前时间: $(date)"'
}
}
}
}
点击「立即构建」,几秒后控制台输出里就能看到结果。先跑通这个最小闭环,再往里加东西,这是最快的学习路径。
四、声明式 Pipeline 的核心结构
Jenkins 有两种 Pipeline 写法:脚本式(Groovy)和声明式(Declarative)。新项目一律用声明式,语法更接近 YAML,可读性更好。
一个典型的三阶段流水线:
pipeline {
agent any
options {
timestamps() // 每行日志带时间戳
buildDiscarder(logRotator(numToKeepStr: '10'))
}
environment {
APP_NAME = 'demo-service'
REGISTRY = 'registry.example.com'
}
stages {
stage('Checkout') {
steps {
git url: 'https://git.example.com/team/demo-service.git',
branch: 'main',
credentialsId: 'git-token'
}
}
stage('Build') {
steps {
sh 'mvn -B clean package -DskipTests'
}
}
stage('Deploy') {
steps {
echo "构建产物已准备就绪,将推送到 ${REGISTRY}/${APP_NAME}"
}
}
}
post {
success {
echo '流水线执行成功'
}
failure {
echo '流水线执行失败,需要人工介入'
}
always {
cleanWs() // 无论成败都清理工作区
}
}
}
几个值得记住的设计点:
- stage 是可读性的核心,在 Blue Ocean 视图里每个 stage 显示为一个色块,一眼看出卡在哪一步
- post 块负责收尾:
success/failure/always三种场景分别处理 - options.buildDiscarder 一定要配,否则历史构建记录会无限堆积,把磁盘撑爆
- cleanWs() 放在
always里,避免多次构建之间互相污染
五、触发方式:让流水线自己跑起来
手动点「立即构建」只是验证阶段,真正上线后要自动化。
5.1 代码提交触发
需要先装 Git plugin 和 GitHub Branch Source 插件,然后在任务配置里勾选:
triggers {
githubPush(
branches: [[pattern: 'main']],
causeId: 'push-main'
)
}
GitHub 侧还要装 Jenkins 的 GitHub App 或 Webhook 插件,把仓库的 webhook 指向 Jenkins 的回调地址。
5.2 定时触发
triggers {
cron('H/15 * * * *') // 每 15 分钟一次
}
cron 用的是 Jenkins 自己的语法,H 表示「哈希分布到小时内的某个随机值」,避免所有任务都挤在整点触发把节点打爆。H/15 表示每小时的第 0、15、30、45 分钟。
六、把构建产物推送到镜像仓库
现在的工程实践基本都容器化,构建产物当然也要容器化:
stage('Docker Build & Push') {
steps {
script {
def img = "${REGISTRY}/${APP_NAME}:${BUILD_NUMBER}"
sh """
docker build -t ${img} .
docker push ${img}
echo "IMAGE_TAG=${img}" > image.env
"""
}
}
}
用 script 块是为了在声明式流水线里执行 Groovy 变量插值。注意 BUILD_NUMBER 是 Jenkins 内置变量,等于第几次构建,直接拿来做镜像 tag 很方便。
七、部署到生产环境
最后一公里最需要谨慎。几条实战原则:
1. 生产环境用 Agent 节点而不是构建机。 在 agent 里限制标签:
agent { label 'production' }
2. 部署前先确认版本。 加一个输入步骤让人工确认:
stage('Confirm Deploy') {
steps {
timeout(time: 5, unit: 'MINUTES') {
input message: '确认部署到生产环境?', ok: '继续'
}
}
}
timeout` 是必须的,否则没人点确认,流水线会一直挂着占着执行槽位。
3. 部署要可回滚。 部署前记录当前版本:
stage('Deploy') {
steps {
sh 'kubectl get deploy ${APP_NAME} -o jsonpath="{.spec.template.spec.containers[0].image}" > current_version.txt'
sh 'kubectl set image deployment/${APP_NAME} ${APP_NAME}=${IMAGE_TAG}'
sh 'kubectl rollout status deployment/${APP_NAME} --timeout=120s'
}
}
rollout status 会一直等到滚动更新完成,失败就返回非零退出码,让流水线判定为失败。
八、常见问题排查
构建卡在拉取代码。 通常是凭证过期或者 SSH 私钥没配好。先到「Manage Jenkins → System → SSH Private Keys」把私钥加进去。
容器里执行 docker 命令报权限错。 Jenkins 容器内没有 docker socket 权限,解决方案是把宿主机的 /var/run/docker.sock 挂进来:
docker run -d --name jenkins \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 8080:8080 jenkins/jenkins:lts
构建太慢。 勾选「Use cached checkout」复用工作区,配合 cleanWs() 在 post 里清理,既提速又不脏。另外可以用 parallel 让多个 stage 并行跑:
stage('Test') {
parallel {
stage('Unit Test') { steps { sh 'mvn test' } }
stage('Lint') { steps { sh 'npm run lint' } }
}
}
磁盘告警。 到「Manage Jenkins → System Monitor」看磁盘使用,并检查 $JENKINS_HOME 下的 builds 目录是不是没配 buildDiscarder。
九、总结与最佳实践
- 从最小闭环起步:先跑通 Hello Pipeline,再逐步加 stage
- 一律用声明式语法,配合 Blue Ocean 看图排错
- 凭证绝不写进脚本,统一放 Credentials,脚本里用
credentials()引用 - 生产部署要有
timeout+input双重保险,并保留rollout status的回滚依据 - 一定要配 buildDiscarder 和 cleanWs(),这两条能挡掉八成的 Jenkins 运维事故
- 构建机与生产 Agent 分离,避免生产环境被构建任务带崩
Jenkins 的学习曲线集中在前两周,把上面这些结构性的东西摸熟之后,剩下的就是不断往流水线里塞 stage 了。把它当成团队的自动化基线来用,收益会远超投入。
- 点赞
- 收藏
- 关注作者
评论(0)