Jenkins是一个基于 MIT License协议的开源软件项目,是基于Java开发的一种持续集成(CI)工具,用于监控持续重复的工作,它可以集成各种插件完成持续编译、部署、测试,并将Job运行结果通过邮件发送给相关人员或者展示相关数据报告。
提到持续集成免不了谈及Hudson,Hudson是由 Sun Microsystems 开发的一个非常流行的开源的基于Java 的持续集成工具,后来Sun被Oracle收购,从Hudson 源代码的分支诞生了Jenkins。
重要概念持续集成:是一个开发的实践过程,软件开发过程中往往需要开发人员定期集成代码到共享存储库(SVN/GIT/Maven等),集成时必须要做相关的构建以消除发现的问题。持续集成要求开发人员有频繁的构建,一般情况下每当一个代码提交时,构建应该被手动或自动触发。
特性
- 开源的java语言开发持续集成工具,支持CI,CD。
- 易于安装部署配置:可通过yum安装,或下载war包以及通过docker容器等 快速实现安装部署,可方便web界面配置管理。
- 消息通知及测试报告:集成RSS/E-mail通过RSS发布构建结果或当构建完成时通过e-mail通知,生成JUnit/TestNG测试报告。
- 分布式构建:支持Jenkins能够让多台计算机一起构建/测试。
- 文件识别:Jenkins能够跟踪哪次构建生成哪些jar,哪次构建使用哪个版本的jar等。
- 丰富的插件支持:支持扩展插件,你可以开发适合自己团队使用的工具,如git,svn,maven,docker等。
产品发布流程:
产品设计成型 -> 开发人员开发代码 -> 测试人员测试功能 -> 运维人员发布上线
CI/CD 持续集成(CI)什么是持续集成?
软件开发中,集成是一个很可能发生未知错误的过程。持续集成是一种软件开发实践,希望团队中的成员频繁提交代码到代码仓库,且每次提交都能通过自动化测试进行验证,从而使问题尽早暴露和解决。
持续集成的好处是什么?
持续集成可以使问题尽早暴露,从而也降低了解决问题的难度,正如老马所说,持续集成无法消除bug,但却能大大降低修复的难度和时间。
如何做到持续集成?
首先,持续集成需要:
-
单一的代码仓库,团队成员都像该仓库提交代码;
-
自动化构建且构建过程需要包含自动化测试;
-
有单独的集成机器用于构建;
-
保证构建速度不要太慢(曾经有一个项目构建需要20分钟,就会很痛苦);
-
在类产品环境进行测试;
-
能够方便获取最新的可执行程序;
-
可视化,大家都能看到构建过程及结果;
-
自动化部署。
其次,我们通过以下步骤进行持续集成:
-
程序员将代码下载到本地,并在完成修改后提交代码;
-
CI服务器监测代码库,并在有提交时自动触发;
-
CI服务器对代码进行构建,运行单元测试和集成测试;
-
CI服务器发布可部署的artefact用于后续测试,并加上本次构建版本的标签。
-
CI服务器通知团队构建成功或者失败;失败发生时团队需要尽快修复,以免耽搁后续的持续集成过程,因为失败时处于持续集成的暂停阶段。
最后,需要就团队责任达成共识:
-
频繁提交;
-
提交之前确保测试通过;
-
不在持续集成失败时提交代码;
-
提交代码后保证持续集成成功。否则得加班
什么是持续交付?
持续交付是持续集成的扩展,指的是将通过自动化测试的软件部署到产品环境。持续交付的本质是把每个构建成功的应用更新交付给用户使用。在持续交付的世界里,我们对完成的定义不是测试完成,而是交付到客户手中。这里需要注意的是,CD代表持续交付(Continuous Delivery)而不是持续部署(Continuous Deploy),因为部署也包括部署到测试环境,而持续交付代表的是功能的上线,交付给用户使用。
持续交付的好处是什么?
持续交付的好处在于快速获取用户反馈;适应市场变化和商业策略的变化。开发团队保证每次提交的修改都是可上线的修改,那么决定何时上线,上线哪部分功能则完全由产品业务团队决定。
虽然持续交付有显著的优点,但也有不成立的时候,比如对于嵌入式系统的开发,往往需要软硬件的配合。
如何做到持续交付?
-
保证每次提交的修改都是可上线的修改。
-
完善的测试(包括单元测试,组件测试,验收测试)来测试新功能和进行回归测试;
-
持续交付的前提条件是自动化的集成和部署;需要开发/测试/运维人员一起完成。
持续部署扩展了持续交付,以便软件构建在通过所有测试时自动部署。在这样的流程中, 不需要人为决定何时及如何投入生产环境。CI/CD 系统的最后一步将在构建后的组件/包退出流水线时自动部署。 此类自动部署可以配置为快速向客户分发组件、功能模块或修复补丁,并准确说明当前提供的内容。采用持续部署的组织可以将新功能快速传递给用户,得到用户对于新版本的快速反馈,并且可以迅速处理任何明显的缺陷。 用户对无用或者误解需求的功能的快速反馈有助于团队规划投入,避免将精力集中于不容易产生回报的地方。
持续部署意味着所有的变更都会被自动部署到生产环境中。持续交付意味着所有的变更都可以被部署到生产环境中,但是出于业务考虑,可以选择不部署。如果要实施持续部署,必须先实施持续交付。持续交付并不是指软件每一个改动都要尽快部署到产品环境中,它指的是任何的代码修改都可以在任何时候实施部署。持续交付表示的是一种能力,而持续部署表示的则一种方式;持续部署是持续交付的最高阶段。
最后我们再来看看上面是敏捷开发,这个称呼似乎还没有所谓的简称,而且这个称呼似乎在国内被滥用了。敏捷开发着重于一种开发的思路,拥抱变化和快速迭代。如何实现敏捷开发,目前似乎尚没有完善的工具链,更多的是一种概念性,调侃的说法“既想马尔跑得快,又想马儿不吃草”的另外一种说法。
上图揭示了敏捷开发的一些内涵和目标,似乎有点儿一本真经的胡说八道的意思。对于上面概念性的内容每个人的理解都有所不同。就好比CGI 这个词,即可以理解成CGI这种协议,也可以理解成实现了CGI协议的软件工具,都没有问题,咬文嚼字过犹不及。
使用Tomcat的部署环境来配置Jenkins
Tomcat部署
环境说明
环境准备
关闭防火墙
[root@localhost ~]# systemctl disable enable --now firewalld [root@localhost ~] [root@localhost ~]# setenforce 0
安装依赖包和工具
yum -y install java-17-openjdk* wget vim
下载Apache-tomcat包
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.54/bin/apache-tomcat-9.0.54.tar.gz
解压
[root@localhost ~]# tar xf apache-tomcat-9.0.53.tar.gz -C /usr/local/ [root@localhost ~]# cd /usr/local/ [root@localhost ~]# ls apache-tomcat-9.0.53 bin etc games include lib lib64 libexec sbin share src [root@localhost ~]# mv apache-tomcat-9.0.53 tomcat
启动Tomcat,查看web界面内容
[root@localhost ~]#cd /usr/local/tomcat/bin/ [root@localhost bin]#ls bootstrap.jar ciphers.sh daemon.sh setclasspath.bat startup.sh //启动脚本 version.bat catalina.bat commons-daemon.jar digest.bat setclasspath.sh tomcat-juli.jar version.sh catalina.sh commons-daemon-native.tar.gz digest.sh shutdown.bat tomcat-native.tar.gz catalina-tasks.xml configtest.bat makebase.bat shutdown.sh //停止脚本 tool-wrapper.bat ciphers.bat configtest.sh makebase.sh startup.bat tool-wrapper.sh 启动tomcat [root@localhost bin]# /usr/local/tomcat/bin/startup.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 bin]# 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 1 [::ffff:127.0.0.1]:8005 *:* LISTEN 0 100 *:8080 *:* LISTEN 0 128 [::]:22 [::]:*
ip+8080端口 访问Tomcat Web管理界面
以下 *** 作为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]# cd ROOT/ [root@localhost ROOT]# ls asf-logo-wide.svg bg-middle.png bg-upper.png index.jsp tomcat.css WEB-INF bg-button.png bg-nav.png favicon.ico RELEASE-NOTES.txt tomcat.svg [root@localhost ROOT]# rm -rf * [root@localhost ROOT]# ls [root@localhost ROOT]#
在/usr/local/tomcat/webapps目录下载jenkins包
[root@localhost webapps]# pwd /usr/local/tomcat/webapps [root@localhost webapps]# wget http://mirrors.jenkins.io/war-stable/2.303.2/jenkins.war ... [root@localhost webapps]# ls jenkins.war ROOT
重启服务
[root@localhost webapps]# /usr/local/tomcat/bin/shutdown.sh 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: NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED [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 -anlt State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 1 ::ffff:127.0.0.1:8005 :::* LISTEN 0 100 :::8080 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* //重启完成后发现压缩包已解压完成 [root@localhost webapps]# ls jenkins jenkins.war ROOT
使用ip+端口号+/jenkin(webapps目录下的解压目录) 访问Jenkins web界面
获取管理员密码
在所属主机上执行以下命令
[root@localhost secrets]# cat /root/.jenkins/secrets/initialAdminPassword 22c4618b501c4dbcbdc8e7d432d88eae
将该文件的内容复制到密码框中
安装插件
选择默认安装的插件
点击安装(等待安装完成)
创建管理员用户(设置完后点击右下角的保存并完成)
配置jenkins实例URl
完成
一、创建一个项目
在左侧菜单栏中选择新建item
进入到创建页面,然后输入item的名称(自定义)和item的类型(根据个人需求)我这里选择(流水线);最后单击确定。
点击确定后进入到定制页面,我这里,流水线之前的选项都设置为默认,
流水线选项设置如下图所示:
创建成功后,稍等30s,过后,点击状态选项卡,选择回放功能,打开"Hello word"的阶段视图
这样一个简单的项目就创建完成了。
Jenkins+gitee将java-tomcat发布至另一台主机的tomcat容器中
环境说明
环境准备
##jenkins //下载git命令 [root@jenkins ~]# yum -y install git .....安装过程略 //下载maven包提供mvn命令(打包命令) [root@jenkins ~]# yum -y install maven ......安装过程略 //拉取java项目 [root@jenkins ~]# git clone https://gitee.com/forgotten/tomcat-java-demo.git 正克隆到 'tomcat-java-demo'... remote: Enumerating objects: 558, done. remote: Counting objects: 100% (558/558), done. remote: Compressing objects: 100% (316/316), done. remote: Total 558 (delta 217), reused 558 (delta 217), pack-reused 0 接收对象中: 100% (558/558), 5.08 MiB | 560.00 KiB/s, done. 处理 delta 中: 100% (217/217), done. [root@jenkins ~]# ls anaconda-ks.cfg apache-tomcat-9.0.54.tar.gz tomcat-java-demo //java项目 //将java进行打包 [root@jenkins ~]# cd tomcat-java-demo/ [root@jenkins tomcat-java-demo]# ls db deploy.yaml Dockerfile jenkinsfile LICENSE pom.xml README.md src [root@jenkins tomcat-java-demo]# mvn clean package //使用此命令对当前目录下的文件进行打包 ...... [INFO] Processing war project [INFO] Webapp assembled in [799 msecs] [INFO] Building war: /root/tomcat-java-demo/target/ly-simple-tomcat-0.0.1-SNAPSHOT.war [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS //出现此反馈则代表构建成功 [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3:46.097s [INFO] Finished at: Tue Oct 19 14:24:07 CST 2021 [INFO] Final Memory: 31M/189M [INFO] ------------------------------------------------------------------------ [root@jenkins tomcat-java-demo]# ls db deploy.yaml Dockerfile jenkinsfile LICENSE pom.xml README.md src target //打包文件目录 [root@jenkins target]# ls classes ly-simple-tomcat-0.0.1-SNAPSHOT maven-archiver generated-sources ly-simple-tomcat-0.0.1-SNAPSHOT.war maven-status //做免密登录 [root@jenkins target]# ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:UE6HcbxQ29U95dLT3PXtSN07NW+kb69YPLMd7NenhUQ root@jenkins The key's randomart image is: +---[RSA 2048]----+ | +=+ ..=| | +oo.o . *X| | . ..... Eo#| | . . o **| | S +o+| | o.+.| | *o=| | o.B*| | . ++=| +----[SHA256]-----+ [root@jenkins target]# ssh-copy-id root@192.168.58.110 (tomcat 容器主机ip) /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" The authenticity of host '192.168.58.110 (192.168.58.110)' can't be established. ECDSA key fingerprint is SHA256:ccm1W51yPg8kN0kq/oD5YpPx/Ywgyn25uWXsWdQu8nY. ECDSA key fingerprint is MD5:be:f2:13:ac:df:7e:56:f6:c4:4c:ae:2e:3b:9f:4e:7f. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys root@192.168.58.110's password: Number of key(s) added: 1 //将打包好的文件修改名字后通过scp发送到tomcat(192.168.58.110)主机中 [root@jenkins target]# mv ly-simple-tomcat-0.0.1-SNAPSHOT.war myapp.war [root@jenkins target]# ls classes generated-sources ly-simple-tomcat-0.0.1-SNAPSHOT maven-archiver maven-status myapp.war [root@jenkins target]# scp myapp.war root@192.168.58.110:/usr/local/tomcat/webapps/ myapp.war 100% 17MB 36.4MB/s 00:00 [root@jenkins target]#
在tomcat主机中查看 启动服务查看服务是否正常
//重启服务 [root@tomcat webapps]# ls docs examples host-manager manager myapp.war ROOT [root@tomcat webapps]# /usr/local/tomcat/bin/s setclasspath.sh shutdown.sh startup.sh [root@tomcat webapps]# /usr/local/tomcat/bin/shutdown.sh 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: NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED [root@tomcat webapps]# ss -anlt State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* [root@tomcat 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@tomcat webapps]# ss -anlt State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 100 :::8080 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* [root@tomcat webapps]# ss -anlt //服务启动后myapp包自动解压 [root@tomcat webapps]# ls docs examples host-manager manager myapp myapp.war ROOT [root@tomcat webapps]# ss -anlt
访问网址如下图时,证明环境无误
Jenkins发布流程
对刚刚添加的项目设置进行修改
对脚本进行如下编辑
pipeline { agent any stages { stage('Build') { steps { // Get some code from a GitHub repository git 'https://gitee.com/jinchenghe92/tomcat-java-demo.git' // Run Maven on a Unix agent. sh "mvn -Dmaven.test.failure.ignore=true clean package" sh "mv target/ly-simple-tomcat-0.0.1-SNAPSHOT.war target/myapp.war" // To run Maven on a Windows agent, use // bat "mvn -Dmaven.test.failure.ignore=true clean package" } } stage("publish"){ steps{ //ssh root@192.168.58.110 'tar -Jcf /opt/backup/myapp-$(date +%Y%m%d).tar.xz /usr/local/tomcat/webapps/myapp' sh "scp target/myapp.war root@192.168.58.110:/usr/local/tomcat/webapps/" sh "ssh root@192.168.58.110 '/usr/localtomcat/bin/catalina.sh stop;sleep 3;/usr/local/tomcat/bin/catalina.sh start'" } } } }
修改后保存,然后在进行构建
构建
构建完成后,访问网站验证
扩展
如果拉取的是一个私有仓库的资源应该如何拉取
(进入gitee,找的相应的资源,模拟私有化仓库)
*** 作如下:
然后查看个人仓库即可发现,资源已经私有化
如果想到jenkins上能拉取本地仓库的资源时则需要,在jinkins中生成一个凭证
回到自己的个人仓库,复制自己的私有仓库链接
再到项目的设置中编辑脚本并对脚本进行优化
pipeline { agent any stages { stage('Build') { steps { // Get some code from a GitHub repository git credentialsId: 'e126e936-970e-4d5e-8490-6af8ba62a0e2', url: 'https://gitee.com/NBED/tomcat-java-demo.git' //将上面生成的凭证和仓库地址复制至此 // Run Maven on a Unix agent. sh ''' mvn -Dmaven.test.failure.ignore=true clean package mv target/ly-simple-tomcat-0.0.1-SNAPSHOT.war target/myapp.war ''' // To run Maven on a Windows agent, use // bat "mvn -Dmaven.test.failure.ignore=true clean package" } } stage("publish"){ steps{ sh ''' ssh root@192.168.58.110 'tar -Jcf /opt/backup/myapp-$(date +%Y%m%d).tar.xz /usr/local/tomcat/webapps/myapp' scp target/myapp.war root@192.168.58.110:/usr/local/tomcat/webapps/ ssh root@192.168.58.110 '/usr/local/tomcat/bin/catalina.sh stop' sleep 3 ssh root@192.168.58.110 '/usr/local/tomcat/bin/catalina.sh start' ''' } } } }
使用三个引号将命令括起来,对命令进行简化
运行
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)