jekins 的入门操作
原生网址:https://zhuanlan.zhihu.com/p/56038065
Build great things at any scale.
快速上手
起源
一个项目比较完整的生命周期该是怎样的?
由开发的coding阶段和coding阶段的质量测试,再到多次发布投入使用阶段
而现代化的测试阶段并不是从coding结束后开始,而是和coding同步进行的,今天上午coding完成一个功能,下午就要投入测试
如何测试呢,也就是将开发者完成的代码,拉取到服务器A(一般是linux)上,按照开发者的部署文档搭建各种依赖服务(可能是mysql,redis,kafka等等),然后运行代码编译后的文件或者是运行脚本
如果我们测试得出开发者今天完成的新功能存在问题,我们需要提出bug,然后开发者解决这个bug,解决完之后呢?
如果开发者在bug解决文档中没有说明是依赖服务出现了问题导致的这个bug,那么A机器上的依赖服务我们是不用重新搭建的,无非就是启动和停止.
变化的往往都是开发者的功能的代码部分.对于java coder,一般是将开发者在git的指定分支上的代码pull下来之后编译打包,然后替换掉A机器上的编译后的包,重启服务,继续测试
每当需求发生变化,功能需要改进,bug等等问题的时候,代码就会发成变化,而将这种变化需要我们在测试机器上得以体现,可能就是替换代码包之类的,这个过程重复而且繁杂,也容易出现部署失误,这种需求背景下产生了自动化持续构建的概念.
而jenkins正是贯彻和发扬了这一理念的持续构建工具
The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project.
领先的开源自动化服务,jenkins中提供了众多的插件以支持使用自动化的方式构建和发布任何工程.
本文作者同大家一起开始步入jenkins的镜像世界,一步一步,深入jenkins,从入门到精通,从使用到理解掌握
为什么选择jenkins
既然都是为了实现自动化持续构建,难道就jenkins这一个选择吗
通常我会使用google trends(谷歌趋势),在涉足一个新的领域的时候帮助我了解这个领域哪些将会是趋势,哪些只是残留.
百度指数也可以起到到和谷歌趋势起到的效果,但是只能反映国内的一部分情况,而且,比如我在搜索eclipse的热度的时候,谷歌会有针对eclipse(日食)这一词义,还是针对名为eclipse的软件的搜索划分,这一点显然特别重要.
hudson/jenkins
hudson是jenkins的前称
TeamCity TeamCity是jet大脑的出品,百度搜索指数还未收录
Travis
Travis CI是最老的托管解决方案之一
其他
其他有如gitlab ci,bamboo由于存在关键词意义重叠的情况,目前还没有想到比较好的解决方案,这次不加入比较.
对比
1. Google Trends
2. 百度指数
结论
从上面的趋势图中无论是基数还是趋势,jenkins的学习性价比对比travis要高许多.
当你选择了一种语言,意味着你还选择了一组技术、一个社区
从二次开发的角度来看,jenkins开源,而且使用的语言是java,使用的框架为spring,两者分别为国内语言社区和框架社区中的顶级社区,发展的特别的好.
使用
我们将使用jenkins完成三个最为重要和基础的功能
- 拉取远程git库的代码到本地
- 使用编译工具本地编译拉取到的代码
- 将编译的结果部署到指定的机器上
1. 拉取远程git库代码到本地
主界面是这样的
为了规整,我们可以先创建一个文件夹(目录)
点击new任务,出现
点击文件夹,然后在输入框中输入文件夹的名字,后点击ok后进入了文件夹属性配置界面
不管这个界面,点击左上方的jenkins图标回到jenkins主页
发现此时多了一个文件夹
点击进入
点左上方的New item 和之前的new 任务页面类似
点击构建一个自由风格的软件项目 在输入框输入这个自动化任务的名称
点ok之后进入配置界面
在这个配置界面下拉到源码管理点击选中git
在Repository URL中输入需要maven构建的代码的仓库地址
Branch Specifier中输入需要构建的分支的名称,*/master表示构建分支名为master,*/你的分支的名字
接下来需要认证这个仓库,点击Credentials右边的add
出现了下拉,一个是jenkins,一个是我们的文件夹名称(githubTasks) 我们选择文件夹名称
选择githubTasks,意味着,我们即将添加的这个用户,将来只会在这个文件夹下使用
在弹出的窗口中类型选择为Username with password 然后输入你的登录到git仓库的用户名和密码
然后点击添加,在Credentials的无 下拉,有我们刚刚添加的账户
点击最下方的保存
点击左侧的立即构建
完成这个自动化构建任务的第一步,拉取远程git库的代码到本地(jenkins所在服务器,docker的话就是docker的容器内部)
我们可以看到是否拉取成功
左下方的Build History里面有一个 #1 点击进入
点击左侧栏的控制台输出进入
看到控制台里面的最近的提交记录,则说明git成功拉取代码
下一步查看拉取的代码在什么位置
注意这个位置是导航栏,这里我们可以随意跳转到主界面,文件夹界面或者是任务界面 jenkins是主界面,githubTasks是文件夹 compileGithub是任务界面
我们点击compileEms进入任务界面 点击工作空间
进入到了这个界面,里面可以看到我们的拉取的代码
可以看到这个界面的标题节点master上的工作空间,这个单词的意思和git没有任何关系,在之后的将代码编译后的成品发布到任意指定机器上的那部分,我会对节点,加以解释,现在这个built in节点指的就是jenkins所在的这台机器.
上面的工作完成了将代码从远程git仓库拉取到本地,接下来需要在本地编译这些代码
扩展
如果我经常需要拉取不同的分支的代码,也就是分支这个字符串,是经常需要改变的,难道我每次都要修改任务配置中的指定分支吗?
让我们返回到jenkins主页,这儿需要加入一个git参数动态化的插件
主页中点击manage jenkinss,点击manage plugins 然后点击available, 在search输入框中输入git parameter
筛选出来的插件中勾选 Git Parameter 点击install without restart之后
等到Git Parameter 图标为 Success即ok
点击返回首页,回到首页
点击导航栏任务compileGithubCode,没有的话先进入文件夹githubTasks,然后从这里点击compileGithubCode进入任务 点击左侧的配置 进入到了任务的配置界面
找到并勾选参数化构建过程
下拉选择Git Parameter
在name中为这个分支字符串变量起个名字,以后用$获取
Parameter Type下拉选择branch
接着,继续向下,找到一开始我们配置git仓库以及分支的那个地方,也就是源码管理
将指定分支右侧的输入框中的内容,换为$branchVar
点击左下角保存
这时候我们发现任务左侧边栏的开始构建没有了,取而代之的是Build With Parameters
点击Build With Parameters转到界面
这个列表会罗列出该git仓库的所有分支,我们选择点击选择一个,然后点Build就好了
2. 使用编译工具本地编译拉取到的代码
得到了远程库的代码,现在要在本地编译这些代码
java coder的话,使用maven编译打包
这个时候就要添加maven这一全局工具了
注意: 接下来是自动的在jenkins机器上安装了一个maven,但是如果你原本项目的maven编译依赖着.setting.xml中配置的maven私服或者是proxy代理的话,还需要别的操作,最粗暴不过进入到jenkins所在机器(这里是docker的容器内部),找到并配置maven的setting.xml,但是如果你想要更为规范的setting.xml的配置方式,这边文章中说的十分详细
导航栏点击jenkins进入到主界面
点击左侧manage jenkins进入到了
点击global tool configuration,然后下拉到
点击新增maven 在name中输入你给它起得名字,这里起了名字maven36来标识他是3.6.0版本
点击左下角的保存
然后回到了主界面,点击jenkins,点击文件夹githubTasks,点击任务compileGithubCode
点击左侧配置
其实可以注意到,这里也有导航栏
我们点击构建 然后点击增加构建步骤
选择 执行顶层Maven目标
出来的界面中 maven version 中下拉选择我们上一步在系统设置的全局工具配置中起得maven名称 目标输入框大部分都是clean install,clean package之类的maven编译命令
clean package -Dmaven.test.skip=true
点击左下方保存,ok
回到任务compileGithub界面,点击左侧 build with parameter
刷新一下当前页面 看到了左下方build history中标志着任务正在进行中的闪烁的图标
点击这个#3,进入到控制台输出界面
我们在系统设置的全局工具配置中配置了如何下载maven等,但是实际上它是类似于单例模式,在第一次运行的时候初始化,以后都能使用
由于没有配置中央仓库为国内maven镜像库,而且是maven第一次构建,所以我这里构建的特别慢,花了将近3min
构建完成后的日志
构建完成之后我们进入任务界面compileGithubCode
点击工作空间 进入到jar产生的target目录,发现成功编译得到了jar文件
但是以后比如别的人想从网页上下载这个编译好的jar,能不能直接从页面上下载下来,当然可以,点击这个jar就会下载下来
但是我们要明白这个任务的目的是什么,其实就是得到这个编译后的成果,过程怎么样是没人关心的,也就是这个任务应该对外完美暴露它的成功,也就是这个jar,不仅要方便大家从页面上下载这个jar,还有后面的任务可能会从这个任务上拿取jar
需要添加构建后操作,回到这个任务的配置页面,找到构建后操作, 下拉选择归档成品
![](https://pic1.zhimg.com/80/v2-2f48bcbd65ca053d75ae8cf4193265b8_1440w.webp)
在归档成品中填写需要暴露的jar的位置
![](https://pic3.zhimg.com/80/v2-381ed1b9f570a8e97130f9bb0e66c7ea_1440w.webp)
位置是可以从任务的工作空间中看到的
![](https://pic3.zhimg.com/80/v2-fa1642c53e23f82a59b1678206332c12_1440w.webp)
然后我们回到任务主页,点击开始Build with parameter,选择分支,build
build成功后,我们进入该任务的主页
![](https://pic2.zhimg.com/80/v2-54588411b8afd46cb62dc1f182d98e69_1440w.webp)
发现多了一个最后一次成功的构建结果,这样就可以很方便的从页面上下载这个jar,而不用担心忘了编译后的成果在什么文件夹位置的情况.
注意: 这一步是必备的,不然下面的发布的任务会无法从这个任务中自动化的获取jar
至此完成了本地编译从远程库pull下来的代码的阶段.
3. 将编译的结果部署到指定的机器上
接下来我们需要理解jenkins中节点的概念
jenkins安装在一台机器,所有的jobs都在这台机器上运行,如果超过太多jobs去运行,会形成等待,节点存在就是解决这个问题提高效率,安装jenkins的机器称为master机,而其它机器就属于master的分支,成为slave;而要利用其它机器用执行jenkins的jobs,则需要一些配置,形成两台机器互通,当然下面的例子你用本机当做slave也是可以的
从机节点的建立意味着这台从机就是master的一个复刻,master能执行的任务它都能干
也就是完整的发布过程是这样的,master机器访问从机B,向B发送 拉取代码到本地 的命令,master机器做的仅仅是发送命令,然后干别的,等到B将远程代码pull到了B的本地
jenkins实现远程发送执行命令的原理 使用了ssh的方式 详见
本地编译代码的过程也是如此
而现在我们就是需要从机得到代码,编译,然后在本地执行启动服务的脚本,如果是tomcat应用的话(外置),可能是将编译后的war放入webapps下,然后启动tomcat的startup.sh
那我们先完成第一步,建立从机节点,说白了,就是我作为master,怎么访问从机,用户名加密码也好,ssh认证也好
3.1 建立从机节点
为了方便用户管理,我们最好不要使用使得master访问从机的root用户,比如这里,我们使用用户jenkins用户
连接到一台从机(root用户)
useradd -d /home/jenkins -m jenkins
接下来需要输入jenkins用户的密码,要求比较严格,密码要求为至少8位的非简单字符串
密码定位itszt19jenkins
然后我们切换到jenkins用户
su - jenkins
pwd
jenkins的~目录在/home/jenkins
因为jenkins是用java写的后台,需要注意这台从机机器需要有java环境
which java
得到的路径地址会在后面配置节点信息的时候用到
接下来我们进入jenkins主页,点击左侧manage jenkins,然后下拉找manage nodes and cloud,点击之后是这样的
![](https://pic3.zhimg.com/80/v2-159f50a280041ed1edc7412ce4a73a32_1440w.webp)
注意到已经有了一个节点built in node,就是我们安装jenkins的机器,我们点击左边的New Node
在输入框中输入我们给这个节点机器起得名字 并勾选固定节点
![](https://pic1.zhimg.com/80/v2-c1ecdaa60cd4256c06a52177593981b4_1440w.webp)
切记这里的节点名不能包含中文字符,不然之后的操作会无法识别这个节点,如果已经发现了问题,可以在节点的设置中修改名称.
点击ok后展开页面
![](https://pic4.zhimg.com/80/v2-b550a3efb30474faeb6875343385932f_1440w.webp)
远程工作目录中输入你的从机的用户的~地址 也就是我们的从机的jenkins用户的~,/home/jenkins
然后下拉用法,切换到 only job with this lable ...
启动方式修改为 Launch agents via ssh
Host输入这台节点的ip
注意,要确保在master机器上能够ping通这个ip
然后下拉Host Key Verification Strategy,选择Manually trusted key Verification Strategy
随后点击Credentials右侧的add,点击下拉出现的jenkins,出现界面
![](https://pic4.zhimg.com/80/v2-1967e43df4a6d49e465f8ffd92253fab_1440w.webp)
在username中输入节点机器的用户名jenkins,在password中输入这个用户的密码,然后点击添加
![](https://pic1.zhimg.com/80/v2-5743f927efe9722abfc7673659aec78c_1440w.webp)
随后在Credentials的下拉中选择我们刚刚添加的用户密码信息
点击启动方式下方的高级按钮,这里唯一要做的是填写java路径,也就是我们在节点机器上新建用户的时候说到的which java得到的java路径
注意: 如果ssh端口暴露的是36000,记得这里修改port的22为36000,不然启动日志会报错
![](https://pic4.zhimg.com/80/v2-e468a54fc49d538297da7b8148f8ca8b_1440w.webp)
点击左下方Save完成节点的配置.此时跳转到了节点管理界面.
![](https://pic1.zhimg.com/80/v2-8daa8b850291e4aca6285766becb2634_1440w.webp)
可以看到此时的节点处于未启动状态,因为启动需要一段时间,主机会将服务的相关代码copy到从机的/home/jenkins下
可以点击节点 测试机器1jenkins用户,进入后的界面点击启动;也可以稍等一会儿,它会自动去启动,启动成功后可以看到这个节点管理界面发生了变化,这样表示成功建立了节点
![](https://pic1.zhimg.com/80/v2-4e2a7c6e46a18816975a735d7b00a344_1440w.webp)
至此完成了从机节点的配置.
提示: 可以登录到从机机器上,切到jenkins用户,切换到~目录下,ls后可以看到名为remoting.jar和remoting文件夹
3.2 在节点上部署服务
接下来让我们收货最终的成果,在节点机器上发布应用
这时候我们需要什么?
我们需要在从机机器上运行我们的代码编译完成的jar
那么第一步就是取得我们的jar
如何取得我们的代码的jar,我们已经在任务compileGithub中得到了远程代码,并编译了它,现在我们需要它的编译结果
有这么一个插件需要我们添加,来帮助我们在一个新的任务中拉取另一个任务的编译结果
回到jenkins首页,左侧系统管理,之后点插件管理,在 avaliable的 filter中输入:Copy Arti
勾选筛选出来的插件Copy Artifact
点击install without restart
Copy Artifact变为success之后
点击Go Back to the top page,完成插件的添加.
回到jenkins主页,进入githubTasks文件夹,点击左侧New Item,输入任务名称,比如deployMyCode,然后选择构建一个自由风格的软件项目,点OK
勾选限制项目的运行节点,输入框中输入我们之前新建的节点的名字,输入了MachineTest1就已经有了提示,选中它
![](https://pic3.zhimg.com/80/v2-5140bdeca4f6f1e3779f5bb13136dbae_1440w.webp)
这样就相当于是会让这个机器执行发布任务
接下来我们获取之前的任务构建的jar
![](https://pic2.zhimg.com/80/v2-74bfd13257d6bf2d507d168f58d11ff1_1440w.webp)
然后在Project name中输入我们之前的拉取代码并本地编译的任务名称 compileGitHubCode,
Artifacts to copy中输入vertx-api/target/*.jar,这个就是我们的任务compileGitHubCode执行完后在工作空间中能找到的jar的位置.
提示: 这个在前面提到了编译代码后的保存构建生成物操作
Target directory中输入packages
![](https://pic4.zhimg.com/80/v2-854741696ef3f45f5edcf740ffae07c3_1440w.webp)
之后再次点击构建中的,添加构建步骤, 我们创建一个shell
![](https://pic3.zhimg.com/80/v2-ab9d3585c5d25d521d0d3dec2e14f80a_1440w.webp)
注意顺序,这个添加的shell应该在Copy artifacts from another project的下面
按道理我们应该在这个shell脚本中执行我们获得的jar,完成类似这样的发布任务的,但是为了熟悉一下这个脚本的执行环境,我们先运行一个简单的脚本
#!/bin/bash
deploy_testMachine() {
touch test.log
}
deploy_testMachine
![](https://pic3.zhimg.com/80/v2-0fdd2c335c70817748df4052aee36ba2_1440w.webp)
然后点击左下方的Save,回到了任务的主页面,我们点击左侧栏的立即构建
点击左下方的#5
![](https://pic4.zhimg.com/80/v2-ec9b82ba6e241753c4861395fd9462e7_1440w.webp)
然后点击左侧的Console Output
![](https://pic3.zhimg.com/80/v2-aad24b4685ddfe538c35fcb1256ea98a_1440w.webp)
可以从日志中发现一些端倪
Building remotely on MachineTest1UserJenkins in workspace /home/jenkins/workspace/githubTasks/deployMyCode
也就是我们经常说的任务的工作空间实际是:
/home/jenkins也就是我们的节点用户
/workspace是我们的所有的工作空间的最上级
/githubTasks我们之前的文件夹
/deployMyCode是我们的这次任务
切入到/home/jenkins/workspace/githubTasks/deployMyCode
#!/bin/bash
deploy_testMachine() {
sh /home/jenkins/apache-tomcat-8.5.82/bin/shutdown.sh
cp packages/target/*.war /home/jenkins/apache-tomcat-8.5.82/webapps
sh /home/jenkins/apache-tomcat-8.5.82/bin/startup.sh
}
deploy_testMachine
这样我们就明白了,这个脚本的执行目录在/home/jenkins/workspace/githubTasks/deployMyCode下,也就是我们的脚本实际上是在这个目录下被执行的
之后我们回到这个任务的配置界面,将我们的脚本修改为
#!/bin/bash
deploy_testMachine() {
java -jar ./packages/*.jar
}
deploy_testMachine
然后回到任务主页,立即构建,即可完成类似服务的发布这种
如果你需要每次删除上次残留在节点中的旧的代码,需要进入到任务的配置,在Build Environment下勾选Delete workspace before build starts即可
![](https://pic4.zhimg.com/80/v2-3d96511899b2b20143545b3e7a398563_1440w.webp)
至此完成从编译产物到产物发布的过程
深度好文,也可以了解一下DHorse(github.com/tiandizhigua), 是一个开源的基于k8s的发布平台。
有用,比csdn的好多了
也可以了解一下DHorse(github.com/tiandizhigua), 是一个开源的基于k8s的发布平台。
坐下方的Build History里面有一个 #1 点击进入
![[酷]](https://pic4.zhimg.com/v2-c96dd18b15beb196b2daba95d26d9b1c.png)
这是一个错别字吧
谢谢