Jenkins的学习与使用(CI/CD)

文章目录


前言

阅读本文前请注意最后编辑时间,文章内容可能与目前最新的技术发展情况相去甚远。欢迎各位评论与私信,指出错误或是进行交流等。


背景

传统的软件开发在系统上线的时候需要手动进行,这个过程可能相对繁琐和容易出错,发布过程如下:

  1. 代码构建:开发人员在本地环境中编写代码,并手动进行代码编译、打包等操作,生成可执行的软件包或者部署文件,比如jar包或者war包。
  2. 手动集成和测试:开发人员需要手动将代码变更集成到主干代码库中,并在集成后手动运行测试来确保代码的质量和稳定性。
  3. 手动部署:一旦代码通过了测试,开发人员可能需要手动将软件部署到目标环境中,比如测试环境、预发布环境或者生产环境。
  4. 手动备份:发布前,开发人员需要手动备份历史版本,如果出现问题,可能需要回滚到之前的稳定版本。

这种手动的发布过程存在以下问题:

  • 容易出错:人为操作容易出现错误,比如遗漏某个步骤或者配置错误,导致发布失败或者软件出现问题。
  • 耗时耗力:手动操作需要花费大量的时间和人力资源,尤其是在大型项目或者频繁发布的情况下。
  • 不可追溯:手动操作缺乏可追溯性,难以记录和回顾发布过程中的细节和问题,影响后续的改进和优化。
    随着持续集成和持续交付的理念的兴起,Jenkins (GitLab CI/CD 、 GitHub Actions)等持续集成工具的出现填补了这一空白,帮助团队实现了自动化的集成、构建、测试和部署,提高了发布的效率和质量。

CI/CD

CI/CD 是持续集成(Continuous Integration,CI)、持续交付(Continuous Delivery,CD)与 持续部署(Continuous Deployment,CD)的简称,注意CD对应了两个名词。

CI/CD是实现敏捷开发和Devops理念的一种方法,具体而言,CI/CD 可让持续自动化和持续监控贯穿于应用的整个生命周期(从集成和测试,到交付和部署)。这些关联的事务通常被统称为CI/CD 管道(Pipeline),由开发(RD)、测试(QA)、运维(OP)团队以敏捷方式协同支持。

  • 持续集成(Continuous integration):每次代码变更后,自动构建和测试。
  • 持续交付(Continuous delivery):在 CI 的基础上,自动化部署到预生产环境,确保代码随时可发布。
  • 持续部署(Continuous deployment):在 CD 的基础上,进一步自动化部署到生产环境,实现无缝发布。

Jenkins简介

Jenkins是一个基于Java开发的开源软件项目。提供一个开放易用的软件平台,使软件项目可以自动化地进行构建、测试和部署。

官方地址:https://www.jenkins.io

官方文档(很详细):https://www.jenkins.io/zh/

Jenkins特性

  • 易安装。有多种安装方式,可以在线安装,也可以下载安装包安装,也可以运行war包。
  • 集成了Email等工具,可以在集成或部署时通知工作人员。
  • 可扩展性:Jenkins具有丰富的插件生态系统,提供了各种各样的插件,涵盖了几乎所有领域,包括版本控制、构建工具、部署工具、通知等。这使得Jenkins能够满足不同团队的需求,并支持各种不同的工作流程。
  • 易用性:Jenkins提供了直观的用户界面,使得用户可以轻松地设置和管理各种构建任务和工作流程。它还支持基于Web的配置,使得用户可以通过浏览器轻松地访问和管理Jenkins实例。
  • 分布式构建:Jenkins支持在多台计算机上执行构建任务,这样可以更快地完成大型项目的构建过程。它还支持在不同操作系统和环境中运行构建任务。
  • 日志和报告:Jenkins会生成详细的构建日志和报告,包括每个构建的输出、测试结果、代码覆盖率等信息,帮助团队跟踪和分析构建过程中的问题。

安装

注意:本文在linux系统上,以Java项目为例,会用到 jdk、maven、git、docker等工具。其他开发语言项目仅作参考

从 Jenkins 的入门指南 中可以了解到

可以 通过java -version命令来检查是否已经安装了 Java,如果有打印出 Java 的版本信息则表示已经安装过了。

如何在 Linux 上安装 Java,具体步骤可参考博客:https://blog.csdn.net/xhmico/article/details/123083940(或者自行查阅其他资料)

准备介绍 Jenkins 在 Linux 上构建 Java 项目,可先安装一下 maven,可参考博客:https://blog.csdn.net/xhmico/article/details/136450882

(或者自行查阅其他资料)

进入 Jenkins 的 官方下载页面

LTS 是长期支持的版本,是稳定的版本

在下载安装包之前要先确定应该下载哪个版本的 Jenkins,Jenkins 的版本依赖于 Java 的版本,可在 Jenkins-Java Support Policy 中进行查看

如果你下载的 Jenkins 版本与本地 Java 不支持,那么 Jenkins 是无法安装成功的,比如服务器上 JDK 的版本是 1.8.0_311,也就是 Java 8,那么只能安装 2.346.1 或者该版本之前的,在 Past Releases 上可以查看到历史版本

页面如下 :

下载合适版本的 jenkins.war 文件

下载完成之后就把该 war 包上传至服务器

上传成功之后就可以直接用 java -jar 命令启动起来,可以通过 httpPort 来指定端口号

cpp 复制代码
java -jar jenkins.war --httpPort=8080

首次启动会比较慢,因为需要初始化和存放一些文件到 .jenkins 的目录下

在启动过程中会打印出 管理员账户密码

这个时候就可以去游览器上访问下 ip:port,ip 是服务器的 ip 地址,port 是启动 jenkins 的端口,比如:192.163.10.12:8080 ,如果你用的是 云服务器,可别忘了在云服务器上开放该端口号

在浏览器上展示页面如下,就可以进行初始化了

将 管理员账户密码 复制到对应的地方,点击 继续

这里建议点击 选择插件来安装,在点击 无 ,不安装任何插件,再点击 安装,因为我们没有配置镜像,安装插件是从外网下载

过来的,会比较慢,并且下载的插件可能会出现不兼容等状况,导致失败率很高。

进入到创建管理员页面,填写账户信息后 保存并完成

进入以下页面配置 jenkins 的 url ,一般使用默认的就行了,保存并完成

初始化完成

可以点击 开始使用 Jenkins 直接登录进入 Jenkins

Jenkins工作流程(仅供参考)

程序员在先把代码利用git提交到版本仓库(其中分支合并一般是由leader进行手动集成操作),然后通过Jenkins将Java项目通过maven去构建(生成jar包),随后部署到服务器上,测试人员可通过浏览器访问该项目进行手工测试(或者在服务器上运行脚本来测试)。

在部署之前进行同样的操作,但可以使用docker将jar包和环境build成一个镜像(或者使用挂载jar包的方式)运行容器进行部署,方便开发环境、预生产环境、测试环境的统一。假如服务器上有多个项目在运行,使用docker也能安全的将他们隔离开来。(关于docker的安装与使用可参考另外一篇博客)

安装maven和其他插件

已有一个示例项目放在了代码仓库中

如果要让Jenkins通过maven进行构建项目,需要在Jenkins中安装插件。点击Manage Jenkins->Manage Plugins


输入 Maven Integration,勾选并点击下方的 Install without restart按钮。同理,还需安装 publish over ssh 插件。(后续会用到)

此外,那么同学们还可以再安装一个中文插件:如下图,输入chinese就可以看到。

新建任务

装好插件后,返回首页。开始新建第一个任务(Job)

新建一个任务,任务名称自行决定。点击下方的构建一个maven项目(如果不是Java项目,或者不使用maven可选择freestyle project)

随后进入项目配置页面,Jenkins为项目提供了大量的配置选项,并且这些配置选项还可以通过插件进一步扩展。

General:对项目进行介绍,填写介绍信息。

任务源码管理

在任务配置中的源码管理这一部分,项目是使用git进行管理的,所以选择git,随后在第一行填入要拉取的仓库地址。Credentials是git凭证,如果项目是私有的,Jenkins使用git拉取项目需要进行身份验证,需要点击添加按钮,添加用户名和密码来进行身份验证。或者通过SSH密钥的方式进行验证。关于SSH密钥的生成方式请自行查阅资料,可参考文章:https://blog.csdn.net/lzc2644481789/article/details/124888223

这里填写要拉取仓库中的哪一个分支

配置maven

将任务拉到Buid这一部分,看到有提示。意思是指 Jenkins不知道maven安装在哪,我们系统中是安装了maven。并在Jenkins中安装了maven的插件,但插件是帮我们调用maven的,还得先配置一下maven的路径才能使用。点击the tool configuration,或者回到首页->Manage Jenkins->Global Tool Configuration

NAME这一行自行起个名字,MAVEN_HOME中填写maven的安装路径。点击保存

maven配置完毕后,回到任务配置项Build中,第一行的Root POM是根据git项目的根目录进行查找的,需要根据项目文件结构进行修改。

如图,项目文件结构为demo文件夹和README,pom.xml文件在demo文件夹中。

配置git(非必需)

参考前面的maven 配置,如果发现Jenkins无法调用git,也需要让我们进行Global Tool Configuration设置,那么可按照下图进行设置。

尝试手动构建jar包

回到首页面板,点击任务的build(绿色箭头)按钮,手动的对该任务进行执行构建任务。

我们可以看到该任务正在构建中,点击该任务名称,可以查看详细信息。

点击控制台输出,可以查看在构建过程中的详细信息。

上图只截取了一部分,总结一下所有的信息是,Jenkins先调用了git拉取了项目代码到 /root/.jenkins/workspace/first/demo-1。

随后调用maven对pom.xml进行解析,下载了依赖包后进行构建。构建了一系列文件,其中

jar包存放在 /root/.jenkins/workspace/first/demo-1/target/demo-1-0.0.1-SNAPSHOT.jar

cpp 复制代码
# 在Jenkins服务器上
# 测试构建的jar包能否运行
# Jenkins占用了8080端口 所以换一个端口
java -jar demo-1-0.0.1-SNAPSHOT.jar --server.port=8088

可能遇到的错误

cpp 复制代码
yum install -y java-devel

使用maven构建时,maven如果没有配置镜像源的话,会从官方处拉取,网络速度慢最终导致构建失败。请各位自行搜索maven配置国内镜像源文章。

发布到远程服务器

假如需要将该应用运行在远程的服务器上,那么就需要将构建完成的jar包发送过去,并执行运行jar包的命令。远程服务器上只需要额外安装java环境即可,用于运行jar包。

发送jar包和命令需要使用 publish over ssh 插件进行运作。

回到任务的配置页面,Post Steps部分,选择 Send files or execute commands over SSH。(通过SSH发送文件和执行命令,发生在构建完成后)

在选完之后,就需要让我们对远程服务器进行配置。

回到首页,Manage Jenkins-> Configure System -> Publish over SSH


点击高级,输入用户密码或者设置SSH密钥、配置端口等信息。点击Test Configuration 测试能否连接到远程服务器

随后回到任务配置页面,选择配置好的服务器。

填写,要传输的源文件路径。传输到远程服务器的具体位置,并去掉了路径前缀,并执行 nohub java -jar /root/xxoo/demo*.jar >mylog.log 2>&1

命令。

点击保存,回到首页进行构建,Jenkins会进行 拉取git代码 利用maven构建 将jar传输到远程服务器上 通过命令运行jar包 的操作。

前置清理工作

如果后续再进行构建的时候,远程服务器上已经有一个jar包在运行了,那么将新构建的jar包传输过去,则无法运行起来。

因此,我们需要做一些前置清理工作。

回到任务配置页面,在Pre Steps部分选择 Send files or execute commands over SSH,在构建之前发送文件或执行命令。

由于前置清理工作的命令较多,因此将这些命令全部都写在 远程服务器上的 x.sh 脚本中 并传入参数 demo,该脚本如下

cpp 复制代码
#!/bin/bash

# 删除历史文件
rm -rf xxoo

# 获取传入参数 jar包的名字
# echo "arg:$1"

# 获取正在运行jar包的pid
pid=`ps -ef | grep $1 | grep 'java -jar' | awk '{printf $2}'`

# 如果pid为空 则提示 否则 杀死进程
if [ -z $pid ]; 
	then 
		echo "$appname not start"
	else
		kill -9 $pid
		echo "$appname stopping"
# 检查一下 是否真的杀死了进程
check=`ps -ef | grep -w $pid | grep java`
if [ -z $check]; 
	then 
		echo "$appname stop"
	else
		echo "$appname stop fail"
fi

构建触发器

前面介绍的jar包的构建都是手动点击的,并不符合自动构建的想法。因此,需要设置触发器来进行自动构建。

git钩子

回到任务配置页面,Jenkins提供了多种触发器,这里主要介绍两种方式。

勾选触发远程构建,在设置了一个身份验证令牌后,远程调用URL则可触发该项目构建。

URL:http://192.168.44.101:8080/job/first/build?token=123123

http://192.168.44.101:8080 这是Jenkins服务的URL

first是任务名

token是设置的身份验证令牌

随后我们安装插件 Build Authorization Token Root

在git仓库中设置Webhooks勾子

填入该URL,然后选择合适的事件。例如合并请求事件,这样在git仓库中合并分支后会调用勾子 访问填入的URL,该URL会触发Jenkins的构建动作,拉取git仓库的变化并进行构建。

定时触发器

勾选Poll SCM,填入参数,参数仿照Jenkins提供的corn表达式书写即可。设置完成之后,Jenkins会按照参数设定,定时的去检查git仓库中的分支是否有更新,如果发现有更新则会进行构建任务。

容器部署方式

前文我们是将项目(jar包)放到服务器上,并在服务器上安装了对应的构建环境或者运行环境来部署的。接下来介绍容器部署的方式

挂载jar包目录方式

准备了一台linux服务器,已经安装好了docker并拉取了官方jdk的镜像。

Jenkins中其他配置不变,仍然是从git拉取代码,并构建。但在构建之前,我们需要将服务器上的旧文件删除,并且停止已经在运行的容器。

cpp 复制代码
# 在任务配置的Pre Steps中填写命令
rm -rf *
docker stop demo

随后进行构建,构建完成后将文件传输到服务器上,然后启动容器。

cpp 复制代码
# 在任务配置的Post Steps中运行shell 脚本
# shell脚本可以放在项目里面一起传输过去,或者提前放在服务器上。
# shell脚本内容如下(仅供参考)

# if [[ "$(docker inspect [容器名] 2> /dev/null | grep '"Name": "/[容器名]"')" != "" ]]; 
if [[ "$(docker inspect [demo] 2> /dev/null | grep '"Name": "/[demo]"')" != "" ]]; 
	then
		# 如果容器存在则启动
		docker start demo
	else
		docker run -d -p 8080:8080 --name demo -v /root/jarfile/demo-1-0.0.1-SNAPSHOT.jar:/demo.jar openjdk:11 java -jar demo.jar
		# 如果容器不存在 生成名为demo的容器 挂载jar包目录 利用openjdk:11镜像创建 创建后并运行命令 java -jar demo.jar
fi

将jar包build成镜像方式

准备了一台linux服务器,已经安装好了docker。

Jenkins中其他配置不变,仍然是从git拉取代码,并构建。但在构建之前,我们需要将服务器上的旧文件删除,停止并删除正在运行的容器,删除docker旧镜像。

cpp 复制代码
# 在任务配置的Pre Steps中填写命令
rm -rf *
docker stop demo
docker rm demo
docker rmi demo

构建镜像需要dockerfile,可以将其放在项目里面,利用git去管理。dockerfile内容如下:

cpp 复制代码
FROM openjdk:11
EXPOSE 8080

WORKDIR /root
ADD jarfile/demo*.jar /root/app.jar
ENTRYPOINT["java","-jar","/root/app.jar"]

除了jar包,记得将dockerfile文件也传输到服务器上

随后再加入命令,创建docker镜像,并生成容器。

cpp 复制代码
docker build demo-image .
docker run -d -p 8080:8080 --name demo demo-image

Jenkins并发构建简介(仅供参考)

集群化构建可以有效提升构建效率,尤其是团队项目比较多或是子项目比较多的时候,可以并发在多台机器上执行构建。

Jenkins首页->Manage Jenkins->Manage Nodes and Clouds

这是目前运行Jenkins服务的节点,也就是一台运行Jenkins的服务器。

点击左侧的新建节点,自行输入节点名称,点击创建后进行节点配置。

远程工作目录:在该节点的哪个目录下进行构建任务

标签:节点标签名 用于区分节点

连接远程节点的方式,利用SSH方式 用户名和密码访问的方式,当然也可以配置SSH密钥。(仅供参考)同样的,再新建一个节点jenkins-03

回到Job配置页面,General部分,勾选,保存。随后 手动构建几次 进行测试

提醒:次节点需要完整的构建环境 安装maven、jdk、git,Jenkins只有在主节点上安装并运行即可

如图,在不同节点上 均有任务在进行构建。

pipeline

流水线(pipeline)

流水线既能作为任务的本身,也能作为jenkinsfile

使用流水线可以让我们的任务配置从ui手动操作,转换为代码,像docker的dockerfile一样。这样更适合大型项目,可以让团队其他开发者同时参与进来,同时也可以编辑开发Jenkinswebui不能完成的更复杂的构建逻辑,作为开发者可读性也更好。

完整语法

5个必备的组成部分

pipeline:整条流水线

agent:指定执行器

stages:所有阶段

stage:某一阶段,可有多个

steps:阶段内的每一步,可执行命令

案例:用pipeline进行自动化构建(仅供参考)

创建一个pipeline任务

General,构建触发器部分与freestyle project、maven项目类似。

主要是流水线部分,书写jenkinsfile。(也可以将jenkinsfile放在代码仓库中,由git来管理)

基础的hello world

cpp 复制代码
pipeline {
    agent any  	

    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
            }
        }
        // 这里的hello2 是我加的,就是说明,这是stages下的第二个任务 ,就是在pipeline中加单行注释 用 // 就行
        stage('Hello2') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

保存测试一下(保存以后点立即构建)

我们来看一下日志

我们的项目要经历几个步骤,1、从git中拉取;2、maven打包;3前置清理工作 4、docker生成镜像并运行

点击下方蓝色的 流水线语法 ,可以使用Jenkins的代码生成器帮我们书写Jenkinsfile(推荐)。

在代码生成器中,我们可以选择已安装的插件(如图git插件),并和之前采用相同的方式填写配置信息,最后点击生成流水线脚本。

cpp 复制代码
pipeline {
    agent any
    stages {
        stage('拉取代码') {
            steps {
                git credentialsId: '93f024b8-6456-4c98-a131-9a5ee9f42027', url: 'https://gitee.com/i-dont-recognize-you/school-page.git'
                echo '拉取成功'
            }
        }
    }
}

引入maven

需要在全局工具配置里面配置maven

利用maven进行构建

前置清理工作。使用片段生成器,选择 Publisher over SSH插件,进行配置,生成对应的流水线脚本,用于执行命令。

注意:第一次构建的时候 会失败 因为一开始没有这个容器。(此处偷了个懒,shell脚本应该写的更完整,仅供参考)

cpp 复制代码
rm -rf *

docker stop demo
docker rm demo
docker rmi demo

再使用片段生成器,选择 Publisher over SSH插件,进行配置,生成对应的流水线脚本,用于传输构建好的jar包 生成容器 运行jar包。

创建多分支Job(仅供参考)

在上面提到的Blue Ocean插件,我们可以安装并使用该插件进行多分支的pipeline构建。

场景:

一个项目 在git仓库中有多个分支,我们需要对不同的分支使用Jenkins进行构建、部署。

在Jenkins的Blue Ocean中 创建流水线,选择git代码仓库,并配置。

点击创建流水线

对流水线进行配置,设置jenkinsfile的路径。(我们将jenkinsfile放在项目代码中,由git来管理)

两个分支配备不同的jenkinsfile,随后进行构建。查看结果,可以看到对该项目的两个分支都进行了构建


参考目录

https://www.bilibili.com/video/BV17i4y1d7SS

https://www.bilibili.com/video/BV1G24qeHEwV

https://www.bilibili.com/video/BV18wXrYMEhq

https://www.bilibili.com/video/BV11B4y1W7eH

https://www.bilibili.com/video/BV11awpeTEDT

https://www.bilibili.com/video/BV1jJtWexEuT

https://www.bilibili.com/video/BV1bS4y1471A

https://www.bilibili.com/video/BV14Y4y1j7s4

https://www.bilibili.com/video/BV1ds4y1k7QM

https://www.bilibili.com/video/BV1pF411Y7tq

https://blog.csdn.net/xhmico/article/details/136535498

https://blog.csdn.net/qq_41889508/article/details/137428625

https://blog.csdn.net/m0_63004677/article/details/139350534

https://blog.csdn.net/lzc2644481789/article/details/124888223

https://blog.csdn.net/qq_57581439/article/details/126281020

相关推荐
一介草民丶10 小时前
Jenkins | Jenkins构建成功服务进程关闭问题
运维·servlet·jenkins
小黄人软件17 小时前
jenkins脚本查看及备份
运维·servlet·jenkins
一介草民丶18 小时前
Jenkins | Linux环境部署Jenkins与部署java项目
java·linux·jenkins
我科绝伦(Huanhuan Zhou)1 天前
保姆级Elasticsearch集群部署指导
大数据·elasticsearch·jenkins
试剂界的爱马仕1 天前
软珊瑚成分 CI-A:靶向口腔癌细胞的 “氧化利剑” 与 ERK 密码
网络·人工智能·科技·机器学习·ci/cd·ai写作
用户26834842239591 天前
前端搭建 CI/CD 工作流指南
前端·ci/cd
星释2 天前
如何编写GitLab-CI配置文件
ci/cd·gitlab
It's Q2 天前
从测试角度看待CI/CD,敏捷开发
ci/cd·自动化·敏捷流程
t198751283 天前
jenkins结合gitlab实现CI
ci/cd·gitlab·jenkins