持续集成与Jenkins安装使用教程
一、持续集成与Jenkins
持续集成(Continuous integration,简称CI)指的是,频繁地(一天多次)将代码集成到主干。
持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。
它的核心措施是代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。
通过持续集成,团队可以快速的从一个功能到另一个功能,简而言之,敏捷软件开发很大一部分都要归功于持续集成。
(一)持续集成的步骤
1.提交
流程的第一步,是开发者向代码仓库提交代码。所有后面的步骤都始于本地代码的一次提交。
2.测试(第一轮)
代码仓库对commit操作配置了钩子(hook),只要提交代码或者合并进主干,就会跑自动化测试。
3.构建
通过第一轮测试,代码可以合并进主干,就算可以交付了。
交付后,就先进行构建(build),再进入第二轮测试。所谓构建,指的是将源码转换为可以运行的实际代码,比如安装依赖,配置各种资源(样式表、js脚本、图片)等等。
4.部署
过了测试和构建,当前代码就是一个可以直接部署的版本(artifact)。将这个版本的所有文件打包存档,发到生产服务器。
5.回滚
一旦当前版本发生问题,就要回滚到上一个版本的构建结果。最简单的做法就是修改以下符号链接,指向上一个版本的目录。
(二)持续集成的组成要素
一个自动构建的过程,从检出代码、编译构建、运行测试、结果记录、测试统计等都是自动完成的,无需人工干预。
一个代码存储库,即需要版本控制软件来保障代码的可维护性,同时作为构建过程的素材库,一般使用SVN或Git。
一个持续集成服务器,jenkins就是一个配置简单和使用方便的持续集成服务器。
(三)持续集成的好处
1.降低风险,由于持续集成不断去构建,编译和测试,可以很早期发现问题,所以修复的代价就少
2.对系统健康持续检查,减少发布风险带来的问题。
3.减少重复性工作
4.持续部署,提供可部署单元包
5.持续交付可供使用的版本
6.增强团队信心。
二、持续集成服务器Jenkins
Jenkins是一款流行的开源持续集成工具,广泛用于项目开发,具有自动化构建、测试和部署等功能。
(一)环境准备
Jenkins作为持续集成工具,使用Git工具到Git仓库拉取代码到集成服务器,再配合JDK,Maven等软件完成代码编译,代码测试与审查,测试,打包等工作,在这个过程中每一步出错,都重新再执行一次整个流程。
最后,Jenkins把生成的jar或war包分发到测试服务器或者生产服务器,测试人员或用户就可以访问应用。
因此,一个完善的持续集成体系包含一台Gitlab代码托管服务器,一台Jenkins持续集成服务器,一台测试服务器和一台生产服务器。
涉及到Gitlab安装、Jenkins安装、Maven安装、Tomcat安装。
(二)Gitlab安装
参考我的博客中gitlab安装教程
gitlab安装教程
(三)安装jdk
如果需要安装最新版本的Jenkins的话,是要下载JDK17的,当然,有时候项目使用jdk8的构建,所以两种版本都要会安装。
# 查看yum源可以安装的jdk版本
yum list | grep jdk
# 可以很方便安装jdk8
yum install -y java-1.8.0-openjdk
# 如果yum源支持jdk17的话,按下列命令安装
yum install -y java-17-openjdk-devel
目前国内yum源最多支持到jdk11,多数情况还是需要手动下载jdk17的压缩包。
# 为避免手动配置环境变量,直接下载rpm包
wget https://download.oracle.com/java/17/archive/jdk-17.0.12_linux-x64_bin.rpm
# 安装rpm包
rpm -ivh jdk-17.0.12_linux-x64_bin.rpm
该安装包会把程序安装在/usr/java/
目录下。
然后检查jdk的版本,查看是否成功安装
# 查看版本
java -version
安装完成后,应该在“Dashboard - Manage Jenkins - Tools”中将JDK加入到全局配置中。
(四)Jenkins安装
1.Centos安装Jenkins
官方网站下载地址:https://www.jenkins.io/download/
不建议在官方网站下载Jenkins.war包,因为还得上传到服务器并且安装tomcat。
# 添加Jenkins的yum仓库
sudo wget -O /etc/yum.repos.d/jenkins.repo \https://pkg.jenkins.io/redhat/jenkins.repo
# 导入Jenkins的GPG密钥
sudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io-2023.key
# 更新yum仓库
sudo yum upgrade
# 安装依赖
sudo yum install fontconfig
# 安装Jenkins
sudo yum install jenkins
然后就可以启动jenkins了
# 启动jenkins
systemctl start jenkins
# 查看jenkins状态
systemctl status jenkins
启动成功后,接着就可以访问http://服务器IP:8080
的jenkins网页了。
如果还不能访问,可以检查下防火墙设置。
# 检查防火墙端口
firewall-cmd --zone=public --list-ports
# 如果8080端口不在列表中,可以添加它
firewall-cmd --permanent --zone=public --add-port=8080/tcp
# 重新加载防火墙规则
firewall-cmd --reload
2.docker安装jenkins
如果公司有很多开发人员,每个人都想用不同版本的jenkins或者使用不同的插件,那么推荐使用docker安装jenkins。
# 在宿主机的某个目录下创建一个"jenkins_home"目录,用于后面jenkins容器挂载,这里我是在home目录下创建的
# 修改jenkins目录的访问权限
mkdir -p /home/jenkins_home
chmod 777 /home/jenkins_home
# 拉取镜像,这里我们使用的是带有lts标签的镜像,它代表最新的长期支持版本。
docker pull jenkins/jenkins:lts
# 启动Jenkins容器
docker run -d -p 8080:8080 -p 50000:50000 --name jenkins-master -v /home/jenkins_home:/var/jenkins_home jenkins/jenkins:lts
使用docker安装Jenkins的话,需要不断更新维护自有版本的镜像文件配置,有点麻烦,不过如果想再换个环境部署迁移的话就很方便。
(五)Jenkins初始化
1.登录Jenkins
执行完成创建jenkins容器的命令后,通过浏览器访问http://服务器IP:8080
的方式就可以了。
# 查看密码
cat /var/lib/jenkins/secrets/initialAdminPassword
复制粘贴密码后等待一段时间,会跳出如下界面。
jenkins默认会连接官网进行插件的安装,这样速度比较慢,所以初始化安装时可以不安装插件!
所以应该点击“选择插件来安装”,然后选择“无”
然后系统提示我们创建初始化后的管理员账号密码,自己设置一个就可以了。
一路点击下一步,就完成正常的安装了
在“Dashboard - Manage Jenkins - Plugins”,可以看到所有可以安装的插件。
看英文困难的同学可以先安装一下 Chinese (Simplified) 中文汉化插件。
2.更换插件安装的镜像源
由于国外插件的安装速度较慢,可以替换安装源为国内镜像。
不过貌似国内的镜像源也失效了,如果找到了新的安装源地址可以自己替换一下。
# 将.xml文件中的"<url>https://updates.jenkins.io/update-center.json</url>"
# 修改为"<url>https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</url>"
vi /var/lib/jenkins/hudson.model.UpdateCenter.xml# 替换后重启容器
systemctl restart jenkins
可以看到再“Advanced settings”中替换成了我们的新地址。
(六)安装凭据管理插件
Jenkins想要访问Gitlab需要输入账号密码,这个通过安装Credentials Binding凭证管理来实现。
搜索Credentials Binding插件并安装,安装成功后打开凭据管理。
在“凭据-系统-全局”这里可以添加凭证。
如下,可以分为五种凭证:
- username with password 账号密码登录
- SSH username with private key 免密ssh登录
- Secret file 密钥文件
- Secret text 密钥文本
- Certificate 证书PCKS方式
一般账号密码登录的方式比较多,我们可以在此提前录入Gitlab的账号密码。
例如,如下图,拉取代码分为SSH克隆(免密ssh登录)和HTTP克隆(账号密码登录)两种方式。
填入账号密码后,新建工程拉取Git代码仓库时就可以用这个信息了。
(七)安装Git插件
前面凭据管理插件装之后,我们可以去Gitlab拉取代码,这个要使用Git工具。
安装完成后,我们创建一个项目,在源码管理这里就会多一个Git
选项。
除了要装git插件,还需要git的工具。
# 安装git
yum install -y git
# 查看git版本
git --version
(八)安装maven
1.下载安装maven
maven可以通过下载压缩包的方式安装,也可以直接直接通过yum安装。
官方下载地址:https://maven.apache.org/download.cgi
maven的3.3.x系列支持jdk6以上版本,3.5.x~3.8.x支持jdk7以上版本,3.9.x支持jdk8以上版本。
这里我选择的是装3.9.x系列版本
# 下载maven的安装包
curl -O "https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.tar.gz"
# 解压压缩包到/usr/local目录
tar -zxvf apache-maven-3.9.9-bin.tar.gz -C /usr/local
# 修改配置文件
vi /etc/profile
# 在文件末尾添加如下内容:
export MAVEN_HOME=/usr/local/apache-maven-3.9.9
export PATH=$PATH:$MAVEN_HOME/bin
# 添加完成后,使配置文件生效
source /etc/profile
配置生效后,检查版本
mvn -version
2.配置maven环境变量
安装完成后,在“Dashboard - Manage Jenkins - Tools”将maven的路径加入全局配置里。
为了保证Jenkins能正确找到并使用必要的工具和环境,需要在“Dashboard -> Manage Jenkins -> System”中的Environment variables添加全局变量,分别添加JAVA_HOME、M2_HOME、PATH+EXTRA等路径地址。
- JAVA_HOME:java目录地址 /usr/lib/jvm/jdk-17.0.12-oracle-x64
- M2_HOME:maven目录地址 /usr/local/apache-maven-3.9.9
- PATH+EXTRA:环境变量附加bin目录地址 $M2_HOME/bin
3.配置maven仓库
# 找个空间大的分区,创建maven仓库存放的目录,并赋予权限
mkdir /home/maven-repo
chmod 777 /home/maven-repo
# 编辑maven/conf目录下的settings.xml的配置文件
vi /usr/local/apache-maven-3.9.9/conf/settings.xml
# 做以下修改:1.去掉注释然后修改仓库地址 2.修改为阿里镜像源
<localRepository>/home/maven-repo</localRepository>
<mirror><id>nexus-aliyun</id><mirrorOf>central</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
(九)构建过程
前面的各种插件都安装完成,接下来我们可以执行构建流程。
再打开项目中的配置菜单中“Dashboard -> test1 -> Configuration -> Build Steps”中选择Execute Shell
选项,意思是构建步骤中要执行shell命令。
填入shell命令,执行maven的清除和打包命令。
mvn clean package
保存完成后,可以点击左侧的Build Now
执行构建。
点击正在执行的进度条,可进入控制台查看构建的详细过程。
构建成功后,可以在控制台查看打包好的工程项目的地址。
进入服务器后台,也会发现在此目录下生成了一个jar包。
到此Jenkins的编译打包功能就成功完成了!
(十)远程部署
远程部署需要Publish Over SSH的插件,这个要安装一下。
安装完成后,就可以在全局配置里设置SSH服务器了。
上面的输入栏都可以空着。
点击新增,填入远程服务器的IP地址、账号、密码、目录等信息。
发送文件
填入传输的文件(可以用通配符)、目录地址以及传输完成后执行的命令。
保存后执行构建,查看控制台的输出日志,系统连上测试服务器了,并发送了一个文件。
登录测试服务器,可以看到文件成功传输到测试服务器。
只要配置的时候填过执行运行jar包的命令,到此就实现jar包的自动运行了!
三、Jenkins使用进阶
(一)Jenkins的项目构建类型
Jenkins自动构建类型分为三种:
- 自由风格软件项目(FreeStyle Project) 适用于任何类型的项目,比如是Java、Python还是其他语言编写的项目
- Maven项目(Maven project) 专门为Java项目设计的,特别是遵循Maven标准目录结构的项目。
- 流水线项目(Pipeline project) 适合于复杂的构建、测试和部署流程,允许将整个过程定义为一段Groovy脚本。
1.自由风格软件项目
自由风格的软件项目适用于任何类型的项目,在使用java的自由风格项目时一般是打包成war包发送到tomcat服务器中。
分为三步,拉取代码-构建代码-部署到远程服务器。
前面已经会拉取代码和编译构建了,还缺一步,就是需要将代码传输给远程服务器进行部署。
Jenkins需要安装一下用于部署的Deploy to Container插件。
安装完成后,继续选择构建后步骤的Deploy war/ear to a container
选项。
输入工程项目文件的路径和tomcat的凭证就可以部署到远程服务器。
2.maven项目
在Jenkins中安装一下Maven Integration插件。
安装完成后,就可以在Jenkins上构建maven项目了。
可以看到,maven项目多了不少选项。与自由风格项目的区别是读取的是POM.xml文件,然后不用写mvn的前缀。
3.流水线项目
前面两个项目各构建节点都是分散的,为方便统一管理可以使用Pipeline来管理。
安装一下Pipeline插件。
安装之后,就可以建立流水线项目了。
接着就可以通过写脚本的方式执行构建了。
(二)Pipeline语法
Pipeline脚本可以用来实现从构建、测试到部署的整个过程,它分为声明式(Declarative)和脚本式(Scripted)的语法。
基础概念
- Pipeline: 是一组按照特定顺序执行的步骤(steps),用于定义整个CI/CD过程。
- Node: 在Jenkins环境中执行Pipeline或部分Pipeline的机器。它可以是master节点或者任何agent节点。
- Stage: 代表了整个流程中的一个阶段,例如“Build”,“Test”,“Deploy”。每个stage通常对应于Pipeline中的一组操作。
- Step: 每个单独的任务称为step,它是Pipeline的最小执行单位。
1.声明式语法
pipeline {agent any // 表示可以在任何可用的agent上运行这个pipelinestages { // 所有阶段stage('Clone repository') { // 第一阶段名称:克隆仓库steps {git 'https://github.com/your-repo/your-project.git' // 替换为你的Git仓库地址}}stage('Build') { // 第二阶段名称:构建项目steps {sh './build.sh' // 假设有一个名为build.sh的shell脚本来进行构建}}stage('Test') { // 第三阶段:测试项目steps {sh './test.sh' // 假设有一个名为test.sh的shell脚本来运行测试}}stage('Deploy') { // 第四阶段:部署项目steps {sh './deploy.sh' // 假设有一个名为deploy.sh的shell脚本来进行部署}}}post { // 定义在整个pipeline完成后要执行的操作always { // 不管pipeline的结果如何都会执行cleanWs() // 清理工作区}success { // 如果pipeline成功完成,则执行echo 'Pipeline completed successfully.'}failure { // 如果pipeline失败,则执行echo 'Pipeline failed.'}}
}
2.脚本式语法
node { // 定义将在哪个节点上运行这个pipeline,'node'关键字在脚本式Pipeline中用于指定执行环境stage('Clone repository') { // 使用stage来组织不同阶段的任务checkout scm // 通过scm步骤从源码管理系统检出代码,默认情况下会使用项目配置的SCM信息// 或者直接指定Git仓库:// git 'https://github.com/your-repo/your-project.git'}stage('Build') {def buildResult = sh(returnStdout: true, script: './build.sh').trim() // 执行构建命令并捕获输出echo "Build result: ${buildResult}"}stage('Test') {sh './test.sh' // 运行测试脚本}stage('Deploy') {try {sh './deploy.sh' // 尝试执行部署脚本} catch (Exception e) {currentBuild.result = 'FAILURE' // 如果部署失败,设置当前构建结果为失败throw e // 重新抛出异常以停止Pipeline}}stage('Post Actions') { // 模拟post部分的功能if (currentBuild.result == null || currentBuild.result == 'SUCCESS') {echo 'Pipeline completed successfully.'} else {echo 'Pipeline failed.'}// 清理工作区cleanWs()}
}
3.流水线语法文档
pipeline的语法有点复杂,不知道怎么写的话,在“流水线语法 -> 片段生成器”可以协助生成pipeline语句。
同时,还有在线文档可以查询。
4.Jenkins脚本文件
前面的Jenkins的Pipeline脚本都是写在web页面里的,这样比较麻烦,不方便做版本控制。
可以在项目根目录新建Jenkinsfile的文件,并将其推送到Git仓库中。
在流水线设置中选择“Pipeline script from SCM”,意思是pipeline脚本来自版本控制系统。
填写好Git仓库地址及凭证。
系统就会默认去根目录拉取Jenkinsfile文件进行执行了。
(三)构建触发器
前面的项目都是手动触发构建,持续集成至少要做到全自动化。也就是说,开发人员提交代码并审查完成后,代码就应该全自动部署到服务器中运行。
当然,建议测试环境全自动运行,生产环境手动触发比较好。
Jenkins内置4种构建触发器:
- 触发远程构建
- 其他工程构建后触发(Build after other projects are build)
- 定时构建(Build periodically)
- 轮询SCM (Poll SCM)
1.触发远程构建
如图,选择”触发远程构建“选项,这里的身份验证令牌应该填一个加密字符串。
为方便演示,我直接填了123456
。
接着通过浏览器访问http://你的服务器IP/job/pipeline-test/build?token=123456
就可以触发构建了。
2.其他工程构建后触发
有时候Jenkins项目之间有前后依赖关系,则可以在前置工程构建时,自动触发下游工程的构建。
3.定时构建
如果有需要每天凌晨趁没人用系统的时候部署更新代码,而又不想加班,可以选择定时构建代码。
这里需要填一个变种的cron表达式。
cron表达式表示如下:
分 时 日 月 周
cron表达式编写示例(H代表形参):
# 每十五分钟一次(可能在:07, :22, :37, :52):
H/15 * * * *
# 每小时的前半段每十分钟执行一次(三次,可能在:04, :14, :24):
H(0-29)/10 * * * *
# 每个工作日从早上9:45到下午3:45,每两小时执行一次(即9:45 AM, 11:45 AM, 1:45 PM, 3:45 PM):
45 9-16/2 * * 1-5
# 每个工作日在8 AM到4 PM之间的每两个小时内随机时间执行一次(可能在9:38 AM, 11:38 AM, 1:38 PM, 3:38 PM):
H H(8-15)/2 * * 1-5
# 每月的1号和15号每天执行一次,除了12月:
H H 1,15 1-11 *
4.轮询SCM
轮询SCM意思是每隔一段时间去轮询Git仓库的整个项目代码有没有变化,若有变化就执行构建,没有则不构建。
因为若项目很大会严重影响性能,所以一般不推荐这种方式构建。
这里也是填写cron表达式来定期轮询。
5.Gitlab Hook钩子
前面轮询SCM的方式也无法做到提交代码才执行构建,所以我们需要安装一下Gitlab Hook钩子插件。