侧边栏壁纸
博主头像
孔子说JAVA博主等级

成功只是一只沦落在鸡窝里的鹰,成功永远属于自信且有毅力的人!

  • 累计撰写 297 篇文章
  • 累计创建 134 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Jenkins入门教程-1:CICD和Jenkins

孔子说JAVA
2022-05-08 / 0 评论 / 0 点赞 / 158 阅读 / 7,812 字 / 正在检测是否收录...

Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于自动的构建(软件/代码的编译、打包、部署)、测试软件项目、监控外部任务的运行,可以持续集成、持续交付项目。自动化部署主要是为了解决项目多、环境多、持续集成慢、部署操作麻烦、手动操作易出错、自动化运维等问题。

  • Jenkins用Java语言编写的基于web界面的平台,可在Tomcat等流行的servlet容器中运行,也可独立运行。
  • Jenkins通常与版本管理工具(SCM)、构建工具结合使用。
  • 常用的版本控制工具有SVN、GIT。
  • 常用的构建/打包工具有Maven、Ant、Gradle。

相关资料

1、CI/CD是什么

最初是瀑布模型,后来是敏捷开发,现在是DevOps,这是现代开发人员构建出色的产品的技术路线。随着DevOps的兴起,出现了持续集成(Continuous Integration)、持续交付(Continuous Delivery) 、持续部署(Continuous Deployment) 的新方法。传统的软件开发和交付方法正在迅速变得过时。从历史上看,在敏捷时代,大多数公司会每月,每季度,甚至每年部署/发布软件。然而,现在,在DevOps时代,每周,每天,甚至每天多次是常态。当SaaS正在占领世界时,尤其如此,您可以轻松地动态更新应用程序,而无需强迫客户下载新组件。很多时候,他们甚至都不会意识到正在发生变化。开发团队通过软件交付流水线(Pipeline)实现自动化,以缩短交付周期,大多数团队都有自动化流程来检查代码并部署到新环境。

1.1 CICD介绍

CI(Continuous integration,中文意思是持续集成)是一种软件开发时间。持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。下图为CI的工作流程。

  • 持续集成的重点是将各个开发人员的工作集合到一个代码仓库中。通常,每天都要进行几次,主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作。

CI_20220422143312

CD(Continuous Delivery, 中文意思持续交付)是在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境的类生产环境中。比如,我们完成单元测试后,可以把代码部署到连接数据库的Staging环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境。下图反应的是CI/CD 的大概工作模式。

  • 持续交付的目的是最小化部署或释放过程中固有的摩擦。它的实现通常能够将构建部署的每个步骤自动化,以便任何时刻能够安全地完成代码发布(理想情况下)。

CICD_20220422143354

持续部署(Continuous Deployment)是一种更高程度的自动化,无论何时对代码进行重大更改,都会自动进行构建/部署。

1.2 CICD流程

互联网软件的开发和发布,已经形成了一套标准流程,假如把开发工作流程分为以下几个阶段:

编码 → 构建 → 集成 → 测试 → 交付 → 部署

1_20220422144953

正如你在上图中看到,持续集成(Continuous Integration)、持续交付(Continuous Delivery)和持续部署(Continuous Deployment) 有着不同的软件自动化交付周期。

1.3 持续集成(CI)

CICD流程中最重要的组成部分就是持续集成(Continuous integration,简称CI)。持续集成指的是:频繁地(一天多次)将代码集成到主干。将软件个人研发的部分向软件整体部分交付,频繁进行集成以便更快地发现其中的错误。

  • 持续集成并不能消除Bug,而是让它们非常容易发现和改正。
  • 持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。
  • 持续集成的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。

持续集成的好处:

  1. 快速发现错误。每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易;
  2. 防止分支大幅偏离主干。如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。

通过持续集成,开发人员能够频繁将其代码集成到公共代码仓库的主分支中。开发人员能够在任何时候多次向仓库提交作品,而不是独立地开发每个功能模块并在开发周期结束时一一提交。

CI 的目标是将集成简化成一个简单、易于重复的日常开发任务,这将有助于降低总体构建成本,并在周期的早期发现缺陷。要想有效地使用 CI 必须转变开发团队的习惯,要鼓励频繁迭代构建,并且在发现 bug 的早期积极解决。

持续集成(CI)目前已成为许多软件开发团队在整个软件开发生命周期内侧重于保证代码质量的常见做法。它是一种实践,旨在缓和和稳固软件的构建过程。并且能够帮助开发团队应对如下挑战:

1)软件构建自动化

配置完成后,CI系统会依照预先制定的时间表,或者针对某一特定事件,对目标软件进行构建。

2)可持续的自动化检查

CI系统能持续地获取新增或修改后签入的源代码,也就是说,当软件开发团队需要周期性的检查新增或修改后的代码时,CI系统会不断确认这些新代码是否破坏了原有软件的成功构建。这减少了开发者们在检查彼此相互依存的代码中变化情况需要花费的时间和精力。

3)构建可持续的自动化测试

构建检查的扩展部分,构建后执行预先制定的一套测试规则,完成后触发通知(Email,RSS等等)给相关的当事人。

4)生成后续过程的自动化

当自动化检查和测试成功完成,软件构建的周期中可能也需要一些额外的任务,诸如生成文档、打包软件、部署构件到一个运行环境或者软件仓库。这样,构件才能更迅速地提供给用户使用。

部署一个CI系统需要的最低要求是,一个可获取的源代码的仓库,一个包含构建脚本的项目。

1.4 持续交付(CD)

持续交付(Continuous delivery)指的是,频繁地将软件的新版本,交付给质量团队或者用户,以供评审。如果评审通过,代码就进入生产阶段。

  • 持续交付在持续集成的基础上,是 CI 的扩展,将集成后的代码部署到更贴近真实运行环境的「类生产环境」(production-like environments)中。持续交付优先于整个产品生命周期的软件部署,建立在高水平自动化持续集成之上。CD 集中依赖于部署流水线,团队通过流水线自动化测试和部署过程。此流水线是一个自动化系统,可以针对构建执行一组渐进的测试套件。CD 具有高度的自动化,并且在一些云计算环境中也易于配置。在流水线的每个阶段,如果构建无法通过关键测试会向团队发出警报。否则,将继续进入下一个测试,并在连续通过测试后自动进入下一个阶段。流水线的最后一个部分会将构建部署到和生产环境等效的环境中。这是一个整体的过程,因为构建、部署和环境都是一起执行和测试的,它能让构建在实际的生产环境可部署和可验证。

1.5 持续部署(CD)

持续部署扩展了持续交付,以便软件构建,在通过所有测试时自动部署。在这样的流程中,不需要人为决定何时及如何投入生产环境。CI/CD 系统的最后一步将在构建后的组件/包退出流水线时自动部署。此类自动部署可以配置为快速向客户分发组件、功能模块或修复补丁,并准确说明当前提供的内容。

  • 采用持续部署的组织可以将新功能快速传递给用户,得到用户对于新版本的快速反馈,并且可以迅速处理任何明显的缺陷。用户对无用或者误解需求的功能的快速反馈有助于团队规划投入,避免将精力集中于不容易产生回报的地方。随着 DevOps 的发展,新的用来实现 CI/CD 流水线的自动化工具也在不断涌现。这些工具通常能与各种开发工具配合,包括像 GitHub 这样的代码仓库和 Jira 这样的 bug 跟踪工具。此外,随着 SaaS 这种交付方式变得更受欢迎,许多工具都可以在现代开发人员运行应用程序的云环境中运行,例如 GCP 和 AWS。最受欢迎的自动化工具是 Jenkins(以前的 Hudson),这是一个由数百名贡献者和商业公司 Cloudbees 支持的开源项目。Cloudbees 甚至聘请了 Jenkins 的创始人,并提供了一些 Jenkins 培训项目和附加组件。除了开源项目之外,还有一些更现代化的商业产品例如 CircleCI,Codeship 和 Shippable。这些产品各有优缺点,我鼓励开发人员在开发流程中一一尝试它们,以了解它们在您的环境中的工作方式,以及它们如何与您的工具、云平台、容器系统等协作。

总的来说,持续集成、持续交付、持续部署提供了一个优秀的 DevOps 环境。对于整个开发团队来说,能很大地提升开发效率,好处与挑战并行。无论如何,频繁部署、快速交付以及开发测试流程自动化都将成为未来软件工程的重要组成部分。

2、jenkins的简单应用

Jenkins是一个开源的、可扩展的持续集成、交付、部署(软件/代码的编译、打包、部署)的基于web界面的平台。允许持续集成和持续交付项目,无论用的是什么平台,可以处理任何类型的构建或持续集成。jenkins是流程化工具。

Jenkins自动化部署实现原理

858186-20190804162611917-80438542

2.1 Jenkins用处

  1. 持续、自动地构建(打包发布)、测试软件项目。
  2. 监控一些定时执行的任务。

2.2 Jenkins特性

  1. 开源的java语言开发持续集成工具,支持CI,CD;
  2. 易于安装部署配置:可通过yum安装,或下载war包以及通过docker容器等快速实现安装部署,可方便web界面配置管理;
  3. 消息通知及测试报告:集成RSS/E-mail通过RSS发布构建结果或当构建完成时通过e-mail通知,生成JUnit/TestNG测试报告;
  4. 分布式构建:支持Jenkins能够让多台计算机一起构建/测试;
  5. 文件识别:Jenkins能够跟踪哪次构建生成哪些jar,哪次构建使用哪个版本的jar等;
  6. 丰富的插件支持:支持扩展插件,你可以开发适合自己团队使用的工具,如git,svn,maven,docker等。

2.3 Jenkins的安装部署

你可以选择将jenkins服务直接安装到服务器上,也可以选择将jenkins服务通过容器运行在服务器上,下面分别简单介绍了这2种部署方式。

1)jenkins部署到tomcat服务器

安装tomcat服务器

//安装jdk环境
[root@localhost ~]# yum -y install java-11-openjdk*

//下载tomcat
[root@localhost ~]# cd /usr/src/
[root@localhost src]# wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.53/bin/apache-tomcat-9.0.53.tar.gz

//解压部署
[root@localhost src]# ls
apache-tomcat-9.0.53.tar.gz  debug  kernels
[root@localhost src]# tar xf apache-tomcat-9.0.53.tar.gz -C /usr/local/
[root@localhost src]# cd /usr/local/
[root@localhost local]# ln -s apache-tomcat-9.0.53/ tomcat

//启动tomcat
[root@localhost ~]# /usr/local/tomcat/bin/catalina.sh start

部署jenkins

将tomcat的配置web配置文件删除,替换成Jenkins包

[root@localhost ~]# cd /usr/local/tomcat/webapps/
[root@localhost webapps]# ls
docs  examples  host-manager  manager  ROOT
[root@localhost webapps]# rm -rf docs/ examples/ host-manager/ manager/
[root@localhost webapps]# ls
ROOT
[root@localhost webapps]# rm -rf ROOT/*
[root@localhost webapps]# 

下载jenkins并启动tomcat服务

//下载jenkins
[root@localhost webapps]# wget http://mirrors.jenkins.io/war-stable/2.303.2/jenkins.war
[root@localhost webapps]# ls
jenkins  jenkins.war  ROOT
[root@localhost webapps]# /usr/local/tomcat/bin/catalina.sh  start
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
[root@localhost webapps]# ss -antl
State       Recv-Q      Send-Q                Local Address:Port             Peer Address:Port      
LISTEN      0           128                         0.0.0.0:22                    0.0.0.0:*         
LISTEN      0           100                               *:8080                        *:*         
LISTEN      0           128                            [::]:22                       [::]:*         
LISTEN      0           1                [::ffff:127.0.0.1]:8005                        *:*         

2)jenkins通过容器运行

docker run \
  -d \
  --rm \
  -u root \
  -p 8080:8080 \
  -v jenkins-data:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v "$HOME":/home \
  jenkinsci/blueocean

2.4 登录Jenkins

运行jenkins容器之后,访问服务器ip:8080就能跳转到jenkins登录页面,第一次会让你输入一个密钥,这个密钥在服务器运行Jenkins容器的时候控制台上就会显示(如果没有加上-d参数)。

  • 如果用tomcat部署,路径后面还需要加上/jenkins(webapps目录下的解压目录)
  • 默认端口为8080

或者通过下面的命令查看jenkins的密钥

//查看登录密码
[root@localhost webapps]# cat /root/.jenkins/secrets/initialAdminPassword
6341c79406e7459f98818832cb277b5a

1_20220426194044

填入密钥之后就会跳转至jerkins页面,首次登录它会提示你安装推荐的插件,点击需要的安装即可。然后会引导你创建一个登录jerkins的用户,输入用户名,密码和邮箱等信息完成创建,之后访问服务器ip:8080就会提示你输入用户名和密码进行登录jenkins。

1_20220426194328

2.5 新建任务

点击左侧新建任务,输入你的任务名称,如wood-app-backend,选择构建自由风格的项目。

1_20220426194501

接着会跳转至Jenkins项目配置区,选择源码管理项,Git选项,输入你Git仓库的地址,然后在Credentials处添加你Git仓库的用户名和密码,并且选择监听master分支(默认就是)。

1_20220426194513

我们需要的效果是一旦git仓库发生变化就要自动构建镜像,并且部署新的镜像容器,所以在构建触发器项下选择轮询SCM,使用corn表达式控制Jenkins监听git仓库的频率为每分钟一次。

1_20220426194648

下面是最核心的操作,jenkins要做的事我们已经知道了,那jerkins怎么知道呢?需要通过shell脚本指定,这里的shell就是Jenkins在监听到git仓库的master分支发生变化时要做的事情,包括删除已创建的容器(因为端口被旧容器占用,需要强制删除),构建新的镜像,运行新的容器

1_20220426194805

if docker ps -a|grep -i wood-app-backend;then
   docker rm -f wood-app-backend
fi
#删除已建的容器,防止容器名,端口冲突
sleep 1
docker build -t baize1998/wood-app-backend:latest .    #根据dockerfile生成镜像
sleep 1
docker run -d -p 5000:5000 --name wood-app-backend baize1998/wood-app-backend:latest    #运行镜像生成容器

2.6 删除旧镜像任务

上面的shell命令中有删除旧容器的命令,但是没有删除旧镜像的命令(每次构建同名新镜像,旧的镜像就会变成none,但是依旧占据空间,需要回收)

1_20220426194923

但是直接在shell中编写删除镜像的命令在回收时可能会发生错误,所以额外创建一个定时任务去回收这些旧的镜像,这里指定清理镜像的任务的执行频率是每天的凌晨一点钟(可以自行控制)

1_20220426195025

shell脚本用于判断是否存在<none>状态的镜像,并对它们进行回收

echo ---------------Clear-Images...------------------
clearImagesList=$(docker images -f "dangling=true" -q)
if [ ! -n "$clearImagesList" ]; then
echo "no images need  clean up."
else
docker rmi $(docker images -f "dangling=true" -q)
echo "clear success."
fi

2.7 测试CI/CD

CI–持续集成(一旦push之后,新的镜像会构建),CD–持续部署(一旦push之后,新的容器会依据新的镜像运行,提供最新的服务),下面修改我们的项目接口,然后push到远程仓库的master分支

1_20220426195152

一分钟后,访问服务器ip:5000看到jenkins已经完成项目镜像构建以及新项目容器的运行,提供了最新的服务,之后便可以进行敏捷的开发了!

1_20220426195246

2.8 CICD自动触发/手动触发

  • 开发环境采用手动触发:因为对于开发环境,提交代码比较频繁,而且有时候提交到git也并不想触发CICD。可以采取每晚定时自动触发CICD,便于异常代码及时抛出。
  • 测试环境采用自动触发:因为测试代码的 git 分支合并是有条件限制的,合并频率比较少。
  • 生产环境采用手动触发:因为生产环境的发布,有严控发布时间的,手动触发控制力强。
0

评论区