最近跟开发研究给新业务搞一套完整的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
4docker 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
9docker 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
16root@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上的小扳手,然后overview
–runners
即可,如图:
至此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
41stages:
- 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
11stage: 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/CD
—Schedules
看到,如图:
参考资料
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