Jenkins实现CICD之自动化构建webhook触发器
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
目录
一. 周期性构建和SCM构建
1 周期性构建概述
周期性构建这是一种基于cron类型的构建机制,按照预定义的时间周期性启动任务。
对于期望能够基于代码变更进行触发的CI场景来说,周期性构建并非其最佳选择,但对于有些类型的任务,它却也能够通过精心编排的周期性构建来避免资源冲突。
周期性构建分为定时构建和轮训构建。
- 定时构建:
按时间周期性的触发构建。
- 轮训SCM(Source Code Management)
指的是定期到代码仓库检查代码是否有变更,存在代码变更时就运行pipline,为了能够从CI中得到更多的收益,轮训操作越频繁越好。
显然,这会给SCM带去无谓的压力(比如夜晚未提交代码时,依旧要轮训检查),所以构建的触发由SCM构建负责通知和Jenkins最为理想。
但在外部的SCM无法通知局域网的Jenkins时,可以采轮训SCM方式倒也不失为一种选择。
温馨提示:
这种周期性构建如果有大量任务并发的时候并不是很好的选择,最好错开高峰期。
2 Jenkins定时构建
2.1 Jenkins定时构建概述
Jenkins cron语法遵循Unix cron语法的定义,但在细节上略有差别。
一项cron的定义包含由空白字符或Tab分隔的5个字段,用于定义周期性的时间点。
H符号可用于任何字段,且它能够在一个时间范围内对项目进行散列值("hash")计算出一个唯一的偏移量,以避免所有配置相同cron值的项目在同一时间启动。
举个例子:
- 0 0 * * *
每天的0点0分执行任务。如果所有的任务都统一这样调度,肯定会引发资源争抢的问题。
- H H(0-7) * * *
每天00:00~7:59任意一个时间范围内执行任务。这样就可以将所有的任务不集中执行,而是在这个时间范围内打散执行。
- H * * * *
每小时构建一次。
- H/15 * * * *
每15分钟执行一次任务。
- H(0-29)/10 * * * *
每小时触发3次任务,分别是在0-29分钟内,每间隔10分钟触发一次。
- H H(8-15)/2 * * 1-5
每个工作日(1-5)的上午8点到下午4点(严格意义是15:59)期间,每2小时触发一次任务。
- H H 1,15 1-11 *
除了12月份外,每个月的1-15每天执行一次任务。
2.2 配置每分钟定时构建一次任务(不使用H)
2.2.1 新建任务
如上图所示,新建一个任务名称。
2.2.2 配置定时构建
如上图所示,我们每分钟执行一次shell命令。
定时构建:
* * * * *
执行shell:
date +%F_%T_%s >> /tmp/cron_date.log
2.2.3 查看定时构建结果
如上图所示,我们无需构建,就发现该任务会定期执行哟~
2.3 配置每五分钟构建一次任务(使用H)
2.3.1 配置每五分钟构建一次
2.3.2 查看定期构建结果
如上图所示,不难发现的确是每五分钟构建一次哟。
3 SCM构建
3.1 新建任务
如上图所示,新建一个名为“yinzhengjie-scm-demo”任务。
3.2 配置源码管理
如上图所示,我配置了源码管理,目的是让Jenkins每次构建都拉取代码,然后啥也不需要做。因为我测试的是scm。
3.3 配置scm构建
如上图所示,我让其每间隔10分钟触发一次构建。
如下图所示,我发现等了44分钟,貌似就第一次触发了构建。因为在44分钟内我始终没有推送代码到gitlab,说着说该项目从未变更。
3.4 修改gitlab的项目代码
(1)拉取代码到本地
[root@centos10.yinzhengjie.com tmp]# git clone https://www.yinzhengjie.com/dev/go-demo.git
Cloning into 'go-demo'...
Username for 'https://www.yinzhengjie.com': jasonyin2020
Password for 'https://jasonyin2020@www.yinzhengjie.com':
remote: Enumerating objects: 20, done.
remote: Total 20 (delta 0), reused 0 (delta 0), pack-reused 20
Receiving objects: 100% (20/20), 5.37 KiB | 5.37 MiB/s, done.
Resolving deltas: 100% (8/8), done.
[root@centos10.yinzhengjie.com tmp]#
(2)修改go代码并提交本地仓库
[root@centos10.yinzhengjie.com go-demo]# vim main.go
[root@centos10.yinzhengjie.com go-demo]#
[root@centos10.yinzhengjie.com go-demo]# git commit -am 'update version'
[master 95acfec] update version
1 file changed, 1 insertion(+), 1 deletion(-)
[root@centos10.yinzhengjie.com go-demo]#
(3)推送代码到远程仓库,推送成功后,如上图所示
[root@centos10.yinzhengjie.com go-demo]# git push origin master
Username for 'https://www.yinzhengjie.com': root
Password for 'https://root@www.yinzhengjie.com':
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 306 bytes | 306.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
To https://www.yinzhengjie.com/dev/go-demo.git
240ce3d..95acfec master -> master
[root@centos10.yinzhengjie.com go-demo]#
3.5 查看Jenkins的项目是构建信息
如上图所示,当我们修改gitlab代码后,需要等待一端时间后,这个时间取决于scm的周期执行时间。
3.6 scm构建总结
经过案例演示,不难发现使用scm构建并不会立刻去拉取代码编译,而是要根据周期性任务间隔时间去坚持gitlab代码是否发生变化后再判断是否构建。
综上所述,对于scm这种定期构建,的确可以有效的减少不必要的构建,但是对于构建项目的及时性并不是很友好,因此推荐大家使用webhook进行构建。
4 禁用周期性任务
4.1 禁用任务
如上图所示,我们进入到配置页面后,点击右上角的禁用按钮即可。
在早期版本,我们需要在Jenkins的配置界面点击"关闭构建"按钮哟~
4.2 任务关闭完成
如上图所示,我们已经成功禁用该项目了,如果有需要可以点击“启用”。
4.3 查看任务列表
如上图所示,不难发现,被禁用的项目有两列是由明显变化的哟!
二.构建webhook触发器
1 构建触发器(webhook)概述
构建触发器(webhook):
也称为钩子,实际上是一个http回调,其用于在开发人员向gitlab提交代码后能够触发Jenkins自动执行代码构建操作。
常见的场景:
只有在开发人员向develop分支提交代码的时候会自动触发代码构建和部署至测试环境,而向主分支提交的代码不会自动构建,需要运维人员手动部署代码到生产环境。
webhook触发构建方式:
- 触发远程构建:
此方式无需安装插件。早期是可行的,但新版本貌似该方法不太好用了。
- Build when a change is pushed to Gitlab. Gitlab webhook URL:
需要安装插件。
2. 手动测试Jenkins的webhook的远程构建
2.1 新建项目
如上图所示,我们将之前的"yinzhengjie-bird"项目的配置复制一份,然后为其加上webhook功能。
2.2 配置token
如上图所示,选择"触发远程构建",就会让我们自定义一个token,我设置为的"jasonyin2020"。
webhook触发URL的公式:
JENKINS_URL/job/yinzhengjie-bird-webhook/build?token=TOKEN_NAME
举个例子:
http://jenkins12.yinzhengjie.com:8080/job/yinzhengjie-bird-webhook/build?token=jasonyin2020
2.3 手动测试
如上图所示,咱们基于webhook的远程构建手动测试成功啦!
注意请求URL要传递用户名和密码哟:
curl http://admin:yinzhengjie@jenkins12.yinzhengjie.com:8080/job/yinzhengjie-bird-webhook/build?token=jasonyin2020
3 为gitlab项目添加Jenkins的webhook
3.1 gitlab配置允许来自 web hooks 和服务对本地网络的请求(可暂时跳过)
如上图所示,按照步骤依次点击即可,主要是勾选"允许来自 web hooks 和服务对本地网络的请求"选项。
如下图所示,保存成功后回头提示哟。
此步骤可跳过,但是另一种方式就必须配置该行为哟!
3.2 gitlab添加Jenkins的webhook
如上图所示,进入到gitlab的项目后,依次按照上图所示的步骤点击就可以添加webhook啦。
如下图所示,gitlab成功将Jenkins的webhook添加成功啦。
添加网址:(注意,密码是明文的哟!)
http://admin:yinzhengjie@jenkins12.yinzhengjie.com:8080/job/yinzhengjie-bird-webhook/build?token=jasonyin2020
3.3 gitlab手动测试Jenkins的webhook(新版本Jenkins明文密码会失败,可参考下一步解决方案)
如上图所示,我们可以在gitlab手动发起对Jenkins的测试。
如下图所示,测试时可能会报错:
Hook executed successfully but returned HTTP 403 <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/> <title>Error 403 No valid crumb was included in the request</title> </head> <body><h2>HTTP ERROR 403 No valid crumb was included in the request</h2> <table> <tr><th>URI:</th><td>/job/yinzhengjie-bird-webhook/build</td></tr> <tr><th>STATUS:</th><td>403</td></tr> <tr><th>MESSAGE:</th><td>No valid crumb was included in the request</td></tr> <tr><th>SERVLET:</th><td>Stapler</td></tr> </table> <hr/><a href="https://eclipse.org/jetty">Powered by Jetty:// 10.0.12</a><hr/> </body> </html>
如下图所示,早期的版本给出了两种解决方案: (但在新版本可惜都无法解决问题)
- 需要我们手动安装gitlab-hook插件。该插件就是大概意思就是支持以明文的方式设置用户名的密码。
很可惜,在新版本Jenkins中并没有该插件。
我个人觉得是官方处于安全的因素考虑,不想要设置明文的密码。要求用户使用API Token隐藏密码提高安全性。
- 修改Jenkins的配置文件(/etc/default/jenkins)的Java启动参数(JAVA_ARGS):
很可惜,这种方式在新版本也解决不了问题。我们也没有必要去多做尝试。
最终解决方案,就是不使用明文的密码方式来触发webhook,官方认为这是不安全的。我们可以使用API Token的方式来配置。
参考连接:
https://jenkins.io/security/advisory/2018-05-09/#SECURITY-263
https://www.jenkins.io/doc/book/security/csrf-protection/
4 在Jenkins配置API Token
4.1 进入到设置页面
如上图所示,进入到设置页面后,点击"添加新的Token"。
4.2 生成token
如上图所示,点击"生成"按钮就可以添加一个token信息啦。
如下图所示,点击复制按钮,就可以复制该token,稍后我们要用到该token。
11bbb326d3b34149610f7fea4b6b89d410
复制完成后请点击"保存"按钮,使得token会立即生效。
4.3 再次查看设置页面
如上图所示,token并不存在啦!
5 gitlab使用Jenkins的token登录验证
5.1 gitlab手动验证token是否能够触发构建
如上图所示,我们在gitlab手动发起webhook请求,不难发现触发成功啦。
测试代码:
curl http://admin:11bbb326d3b34149610f7fea4b6b89d410@jenkins12.yinzhengjie.com:8080/job/yinzhengjie-bird-webhook/build?token=jasonyin2020
5.2 gitlab项目添加webhook
如上图所示,我们添加了基于API Token的密码方式。
如下图所示,我们成功添加了webhook。
5.3 测试webhook
如上图所示,我们使用新添加的webhook进行测试。
如下图所示,我们测试成功啦。
6 推送代码到gitlab验证webhook
6.1 推送代码到gitlab
(1)拉取代码到本地
[root@centos10.yinzhengjie.com tmp]# git clone https://www.yinzhengjie.com/dev/bird.git
Cloning into 'bird'...
Username for 'https://www.yinzhengjie.com': jasonyin2020
Password for 'https://jasonyin2020@www.yinzhengjie.com':
remote: Enumerating objects: 39, done.
remote: Total 39 (delta 0), reused 0 (delta 0), pack-reused 39
Receiving objects: 100% (39/39), 90.76 KiB | 90.76 MiB/s, done.
Resolving deltas: 100% (13/13), done.
[root@centos10.yinzhengjie.com tmp]#
(2)修改代码并提交到本地仓库
[root@centos10.yinzhengjie.com tmp]# cd bird/
[root@centos10.yinzhengjie.com bird]#
[root@centos10.yinzhengjie.com bird]# vim index.html
[root@centos10.yinzhengjie.com bird]#
[root@centos10.yinzhengjie.com bird]# git commit -am 'webhook test'
[master f30b1e8] webhook test
1 file changed, 1 insertion(+), 1 deletion(-)
[root@centos10.yinzhengjie.com bird]#
(3)将代码推送到远程仓库,成功推送后如上图所示
[root@centos10.yinzhengjie.com bird]# git push origin master
Username for 'https://www.yinzhengjie.com': root
Password for 'https://root@www.yinzhengjie.com':
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 302 bytes | 302.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
To https://www.yinzhengjie.com/dev/bird.git
f63f8ef..f30b1e8 master -> master
[root@centos10.yinzhengjie.com bird]#
6.2 查看查看Jenkins的控制台输出
如上图所示,我们在没有点击构建按钮的情况下,发现Jenkins自动触发构建啦!
如下图所示,查看Jenkins的控制台输出不难发现本次触发是基于远程gitlab的IP地址触发的哟!
三 Build when a change is pushed to Gitlab. Gitlab webhook URL
1 新建项目
如上图所示,我们基于之前的项目新建一个新的项目哈。
如下图所示,我们取消"触发远程构建"的勾选,而是选择"Build when a chanage is pushed ..."
2 生成token
如上图所示,选择"高级"设置。
如下图所示,在高级设置中,我们可以生成token。
3 gitlab配置webhook
如上图所示,我们可以将Jenkins提供的配置直接复制到gitlab的webhook即可。
Jenkins项目地址:
http://jenkins12.yinzhengjie.com:8080/project/yinzhengjie-bird-webhook-job2
Jenkins的token:
8210bc4eec1c358f422f90ef68b27549
如下图所示,我们成功添加webhook。
温馨提示:
(1)上面的网址和token请根据您的环境稍作修改即可;
(2)添加webhook时必须让gitlab配置允许来自"web hooks"和服务对本地网络的请求;
4 测试webhook
如上图所示,我们可以点击"测试"按钮,选择"Push events",如下图所示,成功触发Jenkins构建啦。
注意哟,此方法必须安装"gitlab"插件,但很明显,该插件我们早就安装过啦,不然我们怎么能够拉取gitlab代码呢?
5 提交代码到gitlab
(1)拉取代码到本地
[root@ubuntu11.yinzhengjie.com tmp]# git clone https://www.yinzhengjie.com/dev/bird.git
Cloning into 'bird'...
Username for 'https://www.yinzhengjie.com': jasonyin2020
Password for 'https://jasonyin2020@www.yinzhengjie.com':
remote: Enumerating objects: 42, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 42 (delta 0), reused 0 (delta 0), pack-reused 39
Receiving objects: 100% (42/42), 92.40 KiB | 18.48 MiB/s, done.
Resolving deltas: 100% (13/13), done.
[root@ubuntu11.yinzhengjie.com tmp]#
(2)修改代码并提交代码到本地仓库
[root@ubuntu11.yinzhengjie.com tmp]# cd bird/
[root@ubuntu11.yinzhengjie.com bird]#
[root@ubuntu11.yinzhengjie.com bird]# vim index.html
[root@ubuntu11.yinzhengjie.com bird]#
[root@ubuntu11.yinzhengjie.com bird]# git commit -am 'modify index.html testing webhook2'
[master 4122f66] modify index.html testing webhook2
1 file changed, 1 insertion(+), 1 deletion(-)
[root@ubuntu11.yinzhengjie.com bird]#
(3)推送代码到远程仓库,如上图所示,推送成功啦
[root@ubuntu11.yinzhengjie.com bird]# git push origin master
Username for 'https://www.yinzhengjie.com': root
Password for 'https://root@www.yinzhengjie.com':
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 309 bytes | 309.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
To https://www.yinzhengjie.com/dev/bird.git
f30b1e8..4122f66 master -> master
[root@ubuntu11.yinzhengjie.com bird]#
6 查看Jenkins的控制台输出
如上图所示,我们成功推送代码到gitlab后,就会发现其会自动触发任务到Jenkins进行构建哟。
如下图所示,我们查看Jenkins的控制台输出,不难发现任务的确是被gitlab时间触发的哟!
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/18606275,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。