如何使用GitLab的CI/CD进行持续集成和部署

Gitlab CI/CD与Docker的简单集成

Gitlab是使用Ruby On Rails编写的GIT版本控制软件,原生提供了CI/CD的支持。接下来我们看看如何使用CI/CD将项目部署在Docker上。

什么是CI和CD

CIContinuous Integration)是一种软件开发的实践,开发人员每次将代码PUSH到仓库中,都会进行一次构建和测试,这样的流程每天会发生很多次。

CDContinuous Delivery)是一个软件工程方法论,描述了在软件开发的周期中,尽可能的不需要人工参与的进行持续集成、自动测试和自动部署的能力。

开始集成

只需要简单的两步即可让项目支持CI/CD:

  1. 在项目根目录中增加.gitlab-ci.yml文件
  2. 配置一个runner

创建一个.gitlab-ci.yml文件

什么是.gitlab-ci.yml

在这个文件中,配置了CI/CD过程中都需要做哪些事情,每次PUSH代码到仓库中,GITLAB会首先检索这个文件,然后根据配置选择一个runner,去执行配置的脚本。

创建一个简单的.gitlab-ci.yml文件

.gitlab-ci.yml是一个YAML格式的文件

下面是一个简单的示例

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
image: docker:latest
before_script:
- echo "Before script section"
- echo "For example you might run an update here or install a build dependency"
- echo "Or perhaps you might print out some debugging details"
after_script:
- echo "After script section"
- echo "For example you might do some cleanup here"
build1:
stage: build
only:
- branches
script:
- echo "build1 is done."
tags:
- tag1
- tag2
test1:
stage: test
script:
- echo "Do a test here"
- echo "For example run a test suite"
tags:
- tag1
- tag2
deploy1:
stage: deploy
script:
- echo "Do your deploy here"
tags:
- tag1
- tag2

.gitlab-ci.ymlPUSH到仓库中

1
2
3
git add .gitlab-ci.yml
git commit -m "Add .gitlab-ci.yml"
git push origin master

配置一个runner

本文简单的使用一个docker container来作为runner,安装方式可以参考官方指南

共享?or专用?

runner分为共享的和专用的,共享的runner可以被所有项目使用,如果项目的配置是允许使用共享的runner,专用的runner只能被指定的项目使用。创建不同的runner是根据token来指定的

  • 创建专用runner:项目Master可以在项目的Settings -> CI/CD Pipelines界面中找到Specific Runners一栏,找到该项目对应的Token和CI的URL
  • 创建共享runner:管理员可以在Admin -> Runners界面中看到Token

然后在gitlab-runner的容器中运行以下命令进行注册:sudo gitlab-ci-multi-runner register

runner的executor

这里套用官方的一个表格

Executor Shell Docker Docker-SSH VirtualBox Parallels SSH Kubernetes
每次构建都使用新环境 no no
迁移runner no 部分 部分 no
0配置支持并发构建 no (1) no
复杂的构建环境 no (2) ✓ (3) ✓ (3) no
调试构建信息 容易 中等 中等 困难 困难 容易 中等
  1. 可以支持,但是在大多数场景下,如果构建中使用runner所在机器上安装的服务,则会出现问题。
  2. 需要手工安装所有依赖
  3. 需要安装额外的软件,如使用Vagrant

本文使用的executor是Docker

.gitlab-ci.yml主要参数详解

before_script

在每个Job执行之前都会执行before_script中定义的命令

after_script

在每个Job执行之后都会执行after_script中定义的命令

stages

定义Job所使用的阶段,如果不显示的指定,默认的阶段是:buildtestdeploy,按照顺序依次执行。

每个阶段中的Job是并行执行的,当一个阶段的所有JOB都成功执行之后,会顺序的执行下一个阶段中定义的Job。

如果Job不指定stage参数,默认属于test阶段。

Jobs

允许定义无限多个Job,每一个Job必须有一个唯一的名字,不能用关键字参数作为名字。

Job的参数列表

参数 是否必须 说明
script 定义一个用来执行的shell脚本
image 使用的docker image
services 使用的docker service
stage 定义该Job的所属阶段(默认是:test
type stage的别名
variables 在Job范围内定义变量
only 定义一个用来创建该Job的git refs列表
except 定义一个不会创建该Job的git refs列表
tags 定义一个用来选择runner的标签列表
allow_failure 允许该Job失败,失败的Job不会在提交状态上体现出来
when 定义何时会执行该Job,取值范围:on_successon_failurealwaysmanual
dependencies 定义该Job依赖的其它Job,可以在这些Job之间传递artifacts
artifacts 定义Job的artifact列表
cache 定义在接下来的Job中应该被缓存的文件列表
before_script 覆盖全局定义的before_script命令
after_script 覆盖全局定义的after_script命令
environment 定义当前Job用来完成部署的环境变量名称
coverage 定义该Job的代码覆盖设置
script

一个被runner执行的shell脚本,可以是单个命令或者命令数组

only 和 except

onlyexcept是两个用来定义何时需要创建Job的参数:

  1. only定义一组用来创建Job的分支名称或者标签名称
  2. except定义一组不会创建Job的分支名称或者标签名称

有一些规则来定义refs:

  • onlyexcept可以同时使用
  • onlyexcept允许使用正则表达式
  • onlyexcept允许使用指定的关键字:branchestagstriggers
  • onlyexcept允许指定一个远程仓库的地址用来过滤fork的Job

下面这个示例,Job只会在以issue-开头的refs有提交的时候运行

1
2
3
4
5
6
7
job:
# use regexp
only:
- /^issue-.*$/
# use special keyword
except:
- branches

下面这个示例,Job只会在被创建tag的分支上运行,或者被API请求触发

1
2
3
4
5
job:
# use special keywords
only:
- tags
- triggers
tags

tags参数用来选择runner,必须全部匹配一个runner的tag。以数组的形式表示。

allow_failure

表示允许该Job失败不影响阶段最终的运行的结果。

查看项目的CI/CD结果

在项目的Pipelines界面可以看到每一次构建的执行过程和执行结果。