目录
[1.1 定义与价值](#1.1 定义与价值)
[1.2 核心概念](#1.2 核心概念)
[1.3 核心功能](#1.3 核心功能)
[1.4 工作流程](#1.4 工作流程)
[1.5 常见CI/CD工具对比](#1.5 常见CI/CD工具对比)
[2.1 环境准备](#2.1 环境准备)
[2.2 安装Jenkins](#2.2 安装Jenkins)
[2.2.1 方式一:通过包管理器安装(推荐用于生产环境)](#2.2.1 方式一:通过包管理器安装(推荐用于生产环境))
[2.2.2 方式二:通过 WAR 包安装(适合快速测试)](#2.2.2 方式二:通过 WAR 包安装(适合快速测试))
[2.3 防火墙与访问设置](#2.3 防火墙与访问设置)
[2.4 初始配置与插件管理](#2.4 初始配置与插件管理)
[3.1 基本任务创建](#3.1 基本任务创建)
[3.2 源码管理(Git)](#3.2 源码管理(Git))
[3.3 构建触发器](#3.3 构建触发器)
[3.4 构建环境与步骤](#3.4 构建环境与步骤)
[2.5 保存与构建](#2.5 保存与构建)
[2.6 实用技巧](#2.6 实用技巧)
[4.1 创建流水线任务](#4.1 创建流水线任务)
[4.2 配置流水线任务](#4.2 配置流水线任务)
[4.3 保存并运行](#4.3 保存并运行)
一、概念
1.1 定义与价值
Jenkins 是一个开源的、用 Java 编写的持续集成和持续交付(CI/CD)工具 。它本质上是一个自动化服务器,用于自动化软件开发过程中的各种任务,例如编译、测试、打包、部署等。
核心价值:自动化构建、测试和部署过程,尽早发现集成错误,提高软件质量与交付效率。
1.2 核心概念
-
任务/项目(Job/Project): Jenkins中自动化流程的配置单元,比如一个构建Java应用的任务。
-
流水线 :这是现代 Jenkins 的核心功能。可以将整个构建、测试、部署流程以代码的形式(称为
Jenkinsfile
)定义下来,这使得流程可版本化、可审查、可重复。流水线分为声明式和脚本式两种,前者语法更简洁,后者灵活性更高。-
声明式流水线(Declarative Pipeline) :推荐使用,提供了更简单、更结构化的语法,降低了上手难度。
-
脚本式流水线(Scripted Pipeline):基于 Groovy 的 DSL,提供极大的灵活性,但语法相对复杂。
-
-
构建(Build): 执行一次任务的过程,包括拉取代码、编译、测试等步骤。
-
工作空间(Workspace): Jenkins每次构建时,用来存放源代码和生成产物的目录。
-
插件(Plugin): Jenkins 拥有一个极其丰富的插件生态系统(超过 1800 个插件),这使其能够与 Git、Docker、Kubernetes、Jira 等几乎所有主流开发工具无缝集成,功能得以无限扩展。
1.3 核心功能
-
持续集成(CI)
-
自动化构建:当开发人员向版本控制系统(如 Git、SVN)提交代码后,Jenkins 可以自动侦听这一事件(通过 Webhook),拉取最新代码。
-
自动化编译/打包:根据项目类型(如 Java/Maven、.NET、Node.js、Python),调用相应的构建工具(如 Maven、Gradle、npm、dotnet)将源代码编译成可执行的软件包(如 JAR、WAR、Docker 镜像)。
-
-
持续测试
-
自动化测试:在构建完成后,自动运行各种测试套件,包括单元测试、集成测试等。
-
测试报告生成:收集测试结果,生成可视化的报告和趋势图,帮助团队快速了解代码质量和测试覆盖率。
-
-
持续交付/持续部署(CD)
-
自动化部署:将构建好的、通过测试的软件包自动部署到各种环境中,如测试环境、预生产环境,乃至生产环境。
-
多环境管理:通过插件和配置,轻松管理向不同环境的部署流程,通常与审批流程结合(持续交付),或完全自动化(持续部署)。
-
-
强大的流水线(Pipeline)
-
这是 Jenkins 的灵魂功能。它将整个 CI/CD 流程定义为一个"流水线",由多个"阶段"(Stage)组成,例如:
代码检出 -> 编译 -> 单元测试 -> 集成测试 -> 构建Docker镜像 -> 部署到测试环境 -> 验收测试
。 -
Jenkinsfile:使用 Groovy 语法将流水线定义为代码,存储在项目源码库中。这使得流程与代码同在,便于管理和协作。
-
-
广泛的插件生态系统
-
Jenkins 拥有超过 1800 个插件,这是它最核心的竞争力之一。几乎所有能想到的第三方工具都可以通过插件与 Jenkins 集成,例如:
-
版本控制:Git、GitHub、GitLab、Bitbucket。
-
构建工具:Maven、Gradle、Ant、npm、Yarn。
-
测试框架:JUnit、Selenium、Cucumber。
-
部署目标:Kubernetes、Docker、AWS、Azure、Tomcat、SSH。
-
通知:Email、Slack、钉钉、企业微信。
-
-
-
监控与通知
-
Jenkins 会监控整个构建和部署过程的状态(成功、失败、不稳定)。
-
当流程中断时,它会通过邮件、即时消息等渠道通知相关人员,确保问题能被及时处理。
-
1.4 工作流程
-
监听触发:Jenkins 会持续监听代码仓库(如 Git)的变动,一旦有新的代码提交,或者到达预设的时间点,它就会被触发开始工作。
-
拉取代码:从版本控制仓库拉取最新的源代码。
-
执行任务:按照预先定义好的"流水线",一步步执行命令,常见步骤包括编译代码、运行测试、打包项目、进行代码质量检查以及部署到服务器等。
-
反馈结果:任务执行完成后,Jenkins 会生成详细报告,并通过邮件、钉钉等方式通知相关人员构建结果。
1.5 常见CI/CD工具对比
工具 | 托管方式 | 配置方式 | 核心优势 | 主要缺点 | 最佳适用场景 |
---|---|---|---|---|---|
Jenkins | 主要自托管 | Jenkinsfile (Groovy) / UI | 极度灵活,插件生态丰富,免费 | 维护成本高,学习曲线陡,界面陈旧 | 需要高度定制化,有专人维护的复杂环境 |
GitLab CI/CD | SaaS/自托管 | .gitlab-ci.yml (YAML) |
与GitLab无缝集成,一体化的DevOps体验 | 与GitLab平台强绑定 | 已使用GitLab,追求端到端工具链的团队 |
GitHub Actions | SaaS | YAML 工作流文件 | 与GitHub深度集成,事件驱动,Action市场丰富 | 与GitHub平台强绑定 | 代码在GitHub,希望利用事件驱动自动化的团队 |
CircleCI | 主要SaaS | .circleci/config.yml (YAML) |
云版本性能快,Docker支持好,配置清晰 | 免费计划限制较多 | 追求速度和稳定性,使用Docker的云原生项目 |
Azure Pipelines | SaaS/自托管代理 | YAML / UI | 平台无关性,免费额度慷慨,微软栈集成好 | 微软生态外非首选 | 微软技术栈,Azure用户,开源项目 |
二、安装与配置
2.1 环境准备
Jenkins 需要运行在具有 Java 环境的服务器上,以下是针对不同操作系统的安装方法:
安装 Java
Ubuntu/Debian 系统:
bash
sudo apt update
sudo apt install openjdk-11-jdk
java -version # 验证安装
CentOS/RHEL 系统:
bash
sudo yum install java-11-openjdk
- 版本选择 :Jenkins 2.357 及更高版本需要 Java 11 或更高版本。建议选择 Java 11 或 Java 17 这些长期支持版(LTS)。
环境配置 :设置 JAVA_HOME
环境变量,例如在 /etc/profile
文件中添加:
bash
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk
export PATH=$JAVA_HOME/bin:$PATH
然后执行 source /etc/profile
使配置生效。
2.2 安装Jenkins
2.2.1 方式一:通过包管理器安装(推荐用于生产环境)
这种方法便于后续的管理和升级。
Ubuntu/Debian 系统:
bash
# 添加仓库密钥和源
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt update
sudo apt install jenkins
CentOS/RHEL 系统:
bash
# 添加仓库
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
sudo yum install jenkins
安装完成后,启动 Jenkins 并设置开机自启:
bash
sudo systemctl start jenkins
sudo systemctl enable jenkins
2.2.2 方式二:通过 WAR 包安装(适合快速测试)
这种方式简单灵活,只需具备 Java 环境即可。
bash
wget https://get.jenkins.io/war-stable/2.426.2/jenkins.war
sudo java -jar jenkins.war --httpPort=8090
2.3 防火墙与访问设置
确保服务器防火墙开放了 Jenkins 所使用的端口(例如默认的 8080 端口)。
-
查看防火墙状态 :
systemctl status firewalld
-
开放端口(以 8080 为例):
bash
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --reload
- 访问 Jenkins :在浏览器中输入
http://<你的服务器IP地址>:8080
即可访问 Jenkins 初始页面。
2.4 初始配置与插件管理
首次访问 Jenkins 时:
-
获取管理员密码 :在服务器上执行
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
查看初始密码,并将其输入网页。 -
选择插件安装方式 :建议先**"安装推荐的插件"**。如果网络环境导致下载缓慢或失败,可以参考后续的"插件加速"部分进行配置后再安装。
由于网络原因,直接从 Jenkins 官方仓库下载插件可能很慢。可以切换至国内镜像源,例如清华大学镜像源。
-
登录 Jenkins 管理后台,进入 Manage Jenkins > Manage Plugins > Advanced。
-
在 Update Site 栏目中,将 URL 修改为:
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
-
点击 Submit 保存。
如果修改配置后插件安装问题依旧,可以尝试重启 Jenkins 服务(
sudo systemctl restart jenkins
)或手动修改 Jenkins 主机上的更新中心配置文件。
创建管理员用户:在插件安装完成后,系统会提示你创建一个新的管理员用户。建议务必在此步骤创建,以便后续管理。
全局工具配置:为了让 Jenkins 能够执行构建、打包等任务,需要配置所需工具的路径。
进入 Manage Jenkins > Global Tool Configuration:
-
JDK :可以取消"自动安装",手动指定
JAVA_HOME
路径,如/usr/lib/jvm/java-11-openjdk
。 -
Git :通常使用系统自带的 Git,路径可能是
/usr/bin/git
。如果系统未安装,需先执行yum install git
或apt install git
。 -
Maven:如果构建 Java Maven 项目,可以指定 Jenkins 自动安装特定版本,或手动指定已安装在服务器上的 Maven 路径。
-
Node.js :对于前端项目,可以在插件市场安装 NodeJS Plugin 后,在此处配置 Node.js 版本。
三、简单使用(自由风格项目)
3.1 基本任务创建
-
点击 Jenkins 首页的 新建任务(New Item)。
-
输入任务名称,例如
My-First-Project
。 -
选择任务类型,对于初学者,常见的类型有:
-
Freestyle project(自由风格项目):提供灵活的图形化配置界面,适合大多数简单场景。
-
Pipeline (流水线项目):使用代码(Jenkinsfile)来定义构建流程,更适合复杂、多阶段的 CI/CD 流程。
本例中选择 Freestyle project。
-
3.2 源码管理(Git)
在任务配置页面的 Source Code Management 部分:
-
选择 Git。
-
在 Repository URL 中输入 Git 仓库地址,例如
https://github.com/username/repo.git
。 -
如果仓库是私有的,需要配置凭据(Credentials)。点击 Add > Jenkins:
-
Kind 选择 "Username with password"。
-
输入 Git 用户名和密码(或 Personal Access Token)。
-
-
在 Branches to build 指定分支,例如
*/main
或*/master
。
3.3 构建触发器
在 Build Triggers 部分,可以设置何时自动触发构建:
-
手动构建 :不配置任何触发器,每次在 Jenkins 页面上手动点击 Build Now。
-
定时构建 :例如,
H 2 * * *
表示每天凌晨 2 点左右构建。 -
轮询 SCM :定期检查代码仓库是否有变更,如有变更则触发构建。例如
*/5 * * * *
表示每 5 分钟检查一次。 -
GitHub Webhook(更高效):当代码推送到仓库时,GitHub 会主动通知 Jenkins 触发构建。这需要额外的 Webhook 配置。
3.4 构建环境与步骤
在 Build 部分,点击 Add build step,根据项目类型添加相应的步骤。
-
对于 Maven 项目 :可以选择 Invoke top-level Maven targets ,然后指定 Maven 目标,如
clean package
。 -
对于 Shell 脚本 :可以选择 Execute shell,然后输入命令,例如:
bash
# 前端项目示例
npm install
npm run build
# 将构建产物复制到指定目录
cp -r dist /path/to/target/
2.5 保存与构建
配置完成后,点击页面底部的 Save 。在项目详情页,点击左侧的 Build Now 即可立即开始一次构建。点击构建历史记录中的链接(例如 #1),再选择 Console Output,可以查看详细的构建日志,这对于调试非常重要。
2.6 实用技巧
-
修改 JVM 内存设置 :如果构建时出现
java.lang.OutOfMemoryError
,需要增加 Jenkins 的堆内存。可以通过修改启动参数实现,例如在JAVA_OPTS
中加入-Xms512m -Xmx1024m
。 -
设置"丢弃旧的构建":在项目配置中勾选此选项,可以设置保留构建的天数和最大保留个数,有效节省服务器磁盘空间。
-
权限管理 :安装 Role-based Authorization Strategy 插件,可以为不同用户(如开发、测试)分配不同的项目查看和操作权限。
四、使用(流水线项目)
以一个完整的 Java Maven 项目为例,结合 Docker 部署
4.1 创建流水线任务
-
登录 Jenkins 控制台,点击首页左侧的 "新建任务" (New Item)
-
输入任务名称,例如
my-pipeline-project
-
关键选择 :在任务类型中选择 "流水线" (Pipeline)
-
点击 "确定"
4.2 配置流水线任务
进入任务配置页面后,找到 "流水线" (Pipeline) 部分,这里有几种定义流水线的方式:
方式一:直接编写脚本 (Pipeline script)
-
适用场景:快速测试、简单脚本、学习阶段
-
操作方法 :在 "脚本" (Script) 文本框中直接粘贴或编写 Jenkinsfile 内容
-
示例:
Groovy
pipeline {
agent any // 指定流水线在任何可用的代理上执行:cite[5]:cite[10]
// 定义环境变量
environment {
REGISTRY_URL = 'harbor.example.com' // 私有镜像仓库地址
PROJECT_NAME = 'my-java-app'
DOCKER_CREDENTIALS_ID = 'docker-harbor-login' // Jenkins中配置的Docker凭据ID
}
stages {
// 阶段1:拉取代码
stage('Checkout') {
steps {
checkout scm: [
$class: 'GitSCM',
branches: [[name: '*/main']],
userRemoteConfigs: [[url: 'http://your-git-repo.com/your-project.git']]
]
echo "代码拉取完成"
}
}
// 阶段2:编译和单元测试
stage('Build and Test') {
steps {
sh 'mvn clean compile' // 编译代码
sh 'mvn test' // 运行单元测试
}
post {
always {
junit 'target/surefire-reports/*.xml' // 归档JUnit测试报告:cite[2]
}
}
}
// 阶段3:打包JAR文件
stage('Package') {
steps {
sh 'mvn package -Dmaven.test.skip=true' // 跳过测试进行打包
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true // 归档生成的JAR包
}
}
// 阶段4:构建Docker镜像
stage('Build Docker Image') {
steps {
script {
// 动态生成镜像标签,例如使用构建号
dockerImage = docker.build "${REGISTRY_URL}/${PROJECT_NAME}:v1.0.${BUILD_NUMBER}"
}
}
}
// 阶段5:推送Docker镜像
stage('Push Docker Image') {
steps {
script {
docker.withRegistry("https://${REGISTRY_URL}", DOCKER_CREDENTIALS_ID) {
dockerImage.push() // 推送镜像到仓库
}
}
}
}
// 阶段6:部署到服务器
stage('Deploy') {
steps {
script {
// 使用SSH远程执行部署脚本
sshagent(['your-ssh-credentials-id']) {
sh """
ssh -o StrictHostKeyChecking=no user@your-server-ip '
docker stop ${PROJECT_NAME} || true
docker rm ${PROJECT_NAME} || true
docker pull ${REGISTRY_URL}/${PROJECT_NAME}:v1.0.${BUILD_NUMBER}
docker run -d -p 8080:8080 --name ${PROJECT_NAME} ${REGISTRY_URL}/${PROJECT_NAME}:v1.0.${BUILD_NUMBER}
'
"""
}
}
}
}
}
// 构建后处理
post {
always {
echo "流水线执行完成,构建号:${BUILD_NUMBER}"
// 这里可以添加清理工作,例如删除临时文件
}
success {
echo "构建成功!"
// 可以在这里添加成功通知,例如发送邮件:cite[3]
}
failure {
echo "构建失败!"
// 可以在这里添加失败通知
}
}
}
阶段 | 核心任务 | 关键命令/插件 | 说明 |
---|---|---|---|
Checkout | 从版本库拉取代码 | checkout scm |
获取最新的源代码。 |
Build and Test | 编译代码并运行单元测试 | mvn clean compile , mvn test , junit |
运行测试并生成测试报告。 |
Package | 打包应用程序 | mvn package , archiveArtifacts |
生成可部署的JAR/WAR包并归档。 |
Build Docker Image | 构建Docker镜像 | docker.build |
使用项目中的Dockerfile构建镜像。 |
Push Docker Image | 推送镜像到仓库 | docker.withRegistry , dockerImage.push |
将镜像推送到私有仓库以备部署。 |
Deploy | 部署到目标服务器 | sshagent , ssh |
通过SSH在目标服务器上拉取新镜像并重启容器。 |
方式二:从代码仓库获取 (Pipeline script from SCM) - 推荐用于生产
-
适用场景:实际项目开发,实现"Pipeline as Code"
-
配置细节:
-
SCM:选择版本控制系统(Git、SVN等)
-
Repository URL:输入代码仓库地址
-
凭据:添加访问仓库的用户名/密码或SSH密钥
-
分支指定器 :默认
*/main
或*/master
-
脚本路径 :关键设置,指定 Jenkinsfile 在仓库中的路径
-
脚本路径的详细说明:
在 "脚本路径" (Script Path) 字段中,需要告诉 Jenkins 在哪里找到 Jenkinsfile:
场景 | 脚本路径示例 | 说明 |
---|---|---|
根目录下 | Jenkinsfile |
Jenkinsfile 直接在仓库根目录 |
子目录下 | ci/Jenkinsfile |
Jenkinsfile 在 ci 文件夹下 |
不同名称 | Jenkinsfile.prod |
使用非标准名称的流水线文件 |
多分支 | Jenkinsfile |
多分支流水线项目中每个分支可有不同的Jenkinsfile |
假设项目结构如下:
my-java-app/
├── src/
├── pom.xml
└── Jenkinsfile ← 流水线定义文件
在Jenkins中的配置:
-
任务名称 :
my-java-app-pipeline
-
流水线定义 :选择 "Pipeline script from SCM"
-
SCM :
Git
-
Repository URL :
https://github.com/yourname/my-java-app.git
-
凭据:添加GitHub访问令牌
-
分支 :
*/main
-
脚本路径 :
Jenkinsfile
(保持默认)
对应的 Jenkinsfile 内容举例(无docker):
Groovy
pipeline {
agent any
tools {
maven 'Maven-3.8.6' // 在Jenkins全局工具配置中定义的Maven版本
jdk 'JDK-11' // 在Jenkins全局工具配置中定义的JDK版本
}
stages {
stage('Checkout') {
steps {
checkout scm // 拉取代码
}
}
stage('Build') {
steps {
sh 'mvn clean compile'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml' // 归档测试报告
}
}
}
stage('Package') {
steps {
sh 'mvn package -DskipTests'
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
}
}
}
post {
always {
echo "构建完成: ${currentBuild.fullDisplayName}"
}
success {
emailext (
subject: "SUCCESS: 构建 ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: "构建成功!\n详情: ${env.BUILD_URL}",
to: "dev-team@company.com"
)
}
failure {
emailext (
subject: "FAILED: 构建 ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: "构建失败,请检查!\n详情: ${env.BUILD_URL}",
to: "dev-team@company.com"
)
}
}
}
4.3 保存并运行
-
点击页面底部的 "保存" (Save)
-
返回项目页面,点击 "立即构建" (Build Now)
-
查看构建进度和日志
五、Jenkinsfile核心指令
指令/区块 | 是否必须 | 说明与示例 |
---|---|---|
pipeline |
是 | 声明流水线的根区块。 |
agent |
是 | 指定整个流水线或特定阶段在哪个 Jenkins 节点上执行。常用选项有 any (任意可用节点)、label '节点标签' 或使用 docker 提供容器化环境。 |
stages |
是 | 包含一个或多个 stage 指令的序列,定义了流水线的所有阶段。 |
stage |
是 | 定义流水线中的一个具有明确职责的阶段,如构建、测试、部署。stages 内至少包含一个 stage 。 |
steps |
是 | 在每个 stage 中定义具体要执行的命令序列。 |
environment |
否 | 定义环境变量,可在流水线级别或阶段级别使用。支持使用 credentials() 方法安全地获取 Jenkins 中存储的密码等凭据。 |
parameters |
否 | 定义流水线的参数,实现参数化构建。支持字符串、选择框、布尔值等类型。 |
options |
否 | 配置流水线特有的选项,例如设置超时时间 timeout(time: 1, unit: 'HOURS') 。 |
post |
否 | 根据流水线或阶段的最终状态执行附加操作。例如,无论成功失败都发送通知(always ),仅在失败时发送警报(failure )。 |
triggers |
否 | 定义流水线的自动触发条件,如定时构建 cron('0 8 * * 1-5') 或轮询 SCM。 |