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时间触发的哟!

posted @ 2024-12-14 06:38  尹正杰  阅读(485)  评论(0)    收藏  举报