Gitlab搭配Gitlab-runner实现流水线自动化部署

最近跟开发研究给新业务搞一套完整的CI/CD流程,据说drone很猛,在github上势头很高。不过缺点也很明显:文档不全+错误提示不到位,于是还是选择了Gitlab,这次不同于以往的Gitlab+jenkins,而是采用了Gitlab+runner。

名词解释,我这里就不多说了,可以去看https://segmentfault.com/a/1190000007180257 ,讲解的很全。

环境介绍:阿里云Centos7 + Docker + Gitlab,gitlab里准备了一个测试用的project。

配置gitlab-runner

很多地方都说gitlab-runner是一个比较吃内存的进程,而且处于安全角度考虑都很不推荐它跟gitlab装在一起,不过本文是展示测试而已,我手头也没有其他的服务器了,于是就先装在同一台服务器上。

用容器装gitlab-runner很简单,语句如下:

1
2
3
4
docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest

如果你想玩骚的,可以通过一个存储卷容器来保存gitlab-runner的数据,语句如下:

1
2
3
4
5
6
7
8
9
docker run -d --name gitlab-runner-config \
-v /etc/gitlab-runner \
busybox:latest \
/bin/true

docker run -d --name gitlab-runner --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
--volumes-from gitlab-runner-config \
gitlab/gitlab-runner:latest

此时docker ps -a情况如下:
抱光妹

来到gitlab的WEB页面,进入测试用的project,然后左侧栏里选择settings—-CI/CD—点击runner,就会看到配置的相关信息,如图:
抱光妹

保持这个界面不要动,我们返回命令行进入gitlab-runner容器里,需要把runner注册到我们的gitlab上,执行命令gitlab-runner register,然后就是如下交互对话:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@4512a92c8cb2:/# gitlab-runner register
Runtime platform arch=amd64 os=linux pid=26 revision=de7731dd version=12.1.0
Running in system-mode.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/): #这里输入gitlab的域名,如果不是域名就http://IP的形式
http://GITLAB的IP
Please enter the gitlab-ci token for this runner:
刚刚页面里的token
Please enter the gitlab-ci description for this runner: #这里写一个注释
[4512a92c8cb2]: test
Please enter the gitlab-ci tags for this runner (comma separated):
my-tag #打一个标签,注意这个标签不能乱写,下面会细说
Registering runner... succeeded runner=fvyoASC8
Please enter the executor: docker, parallels, virtualbox, kubernetes, custom, shell, ssh, docker+machine, docker-ssh+machine, docker-ssh:
shell #选择执行方式,我写了shell,如果你写的是docker,那么会让你填写一个镜像地址,然后默认就会去拉这个镜像地址
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

返回gitlab的web页面刷新一下,就看到刚刚填写的runner已经成功注册上了,如图:
抱光妹

可以看到注释和tag,如果点击小锁头旁边的编辑按钮,就可以编辑刚才命令行里的配置,所以tag啥的写错了请放心。

如果说想要看到runner的一个概览,那么就点击gitlab上的小扳手,然后overviewrunners即可,如图:
抱光妹

至此gitlab-runner已经配置完成!

搭配GItLab CI

要想在合并请求或者push的时候出发CI流水线,那么就在项目仓库的根目录添加.gitlab-ci.yml文件,for instance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
stages:
- test
- build
- deploy

# 增加名为test-check的任务
test-check:
stage: test
tags: # 指定使用有 my-tag 标签的runner运行该任务
- my-tag
# 开始运行之前的操作
before_script:
- echo 'runner begin...'
script:
- hostname && date
- whoami
allow_failure: true #job失败了,pipline将会置绿或者置成功显示,可以继续往下走,但是commit页面或者job页面看到一条“CI build passed with warnings”的警告信息

test-check2:
stage: test
tags:
- my-tag2
script:
- echo "嘎嘎"
- echo "哈哈哈哈哈"
- echo "--------job2----------"
after_script:
- echo "FINISH!"

test-deploy:
stage: deploy
tags:
- deploy
environment: #这个环境设定主要是回滚的时候用得到
name: chentest
url: https://test.example.com
script:
- echo "部署啦!!"
- echo "啦啦啦啦!"
- echo "--------job3----------"
- echo "finish" >> /tmp/test.txt

然后触发一下git push,就会在gitlab的页面里看到commit:passed的绿色小勾,如图:
抱光妹

点击这个绿色小勾就能看到status下面的状态是passed,然后可以在pipiline里看到具体的流水线情况:
抱光妹

然后点击对应的job,就能看到了执行的详情,如图:
抱光妹

可以看到整个过程是在gitlab-runner这个容器里操作的,如果失败了也可以在这里查看具体的原因。注意!.gitlab-ci.yml的任何对文件操作都是在gitlab-runner这个容器内部进行的,而不是它所在的宿主机!也就是说在上面例子里job3最后的/tmp/test.txt是容器里的而不是宿主机的。

还有一个地方要注意,stage判断结果成功与否的标志是最后一个命令是否返回非零结果($?),也就是说你的script内容是执行一个shell脚本,假如这个shell脚本中间有某些命令执行失败,但最后一个命令执行成功,stage最终结果也会是成功的。所以推荐shell命令行后面都加上|| { exit 1; },这样可以避免坑。

.gitlab-ci.yml的语法非常丰富,详情可见官方文档https://docs.gitlab.com/ce/ci/yaml/README.html 或者是https://segmentfault.com/a/1190000010442764 ,已经总结的非常全面了。

高阶玩法

上面只是gitlab-runner搭配cli的一个小小demo而已。在现实工作中,我们会创建很多个runner,然后给不同的runner分配各自的tag:编译、测试、打包和发布,然后在配合.gitlab-ci.yml文件操作。

如果想要jobs并发,先进入gitlab-runner容器里,将/etc/gitlab-runner/config.toml文件里的concurrent = 1酌情调大,重启容器生效。

如果说不想push都触发所有的jobs,而想要某个jobs在merge的时候才执行,可以在.gitlab-ci.yml里对应的job段落改成如下的格式:

1
2
3
4
5
6
7
8
9
10
11
stage: build
script:
- xxxxx
artifacts:
paths:
- xxxxx
tags:
- xxxx
only: #only后面可以跟分支或者标签
- /^issue-.*$/ # 该job将会只在issue-开头的refs下执行
- merge_requests # 只有merge才会触发!

如果在触发流水线执行job的时候被提示:job is stuck check runners,那么请检查一下gitlab-ci.yml里是不是没有写明tag。

除了上面push/merge人为触发之外,gitlab还支持定时触发流水线作业。可以在web界面里的CI/CDSchedules看到,如图:
抱光妹

参考资料

https://triplecc.github.io/2018/06/23/2018-06-23-ji-gitlabcide-ci-shi-jian/
http://jiangbai333.github.io/2018/10/30/gitlab-runner%E5%AE%89%E8%A3%85%E4%B8%8E%E4%BD%BF%E7%94%A8/
http://walterinsh.github.io/2016/04/18/using-gitlab-ci.html
https://www.chenshaowen.com/blog/gitlab-ci-configuring-runner.html
https://zhuanlan.zhihu.com/p/33633217
https://segmentfault.com/a/1190000011890710

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------