部门决定从SVN迁移到GIT之初,我们暂定的是使用Jenkins作为CI/CD的实现,不过秉承实用的思想我们最终决定直接启用GitLab内置的GitLab-CI作为我们目前的CI/CD实现。
GitLab-CI 即为 GitLab Continuous Integration,也就是GitLab自带的持续集成工具。其思想就是每次用户push代码到gitlab上时触发执行.gitlab-ci.yml
脚本,脚本的内容包括了测试,编译,部署等一系列自定义的内容。
与 Jenkins Pipeline 相比,GitLab-CI 更轻,更方便。它直接通过简单 yaml 文件定义 pipeline,相比与 jenkins 复杂的 groovy 语法,GitLab-CI 更简单。正如官方宣传的"Don’t let your tools slow you down"。
想要使用GitLab-CI,我们需要安装一些额外的组件GitLab-Runner。GitLab服务本身只负责任务的派发,具体的执行还是得交给Runner,这也符合最基本的设计准则——调度中心和执行分开,避免相互影响,方便迭代更新,也方便扩容。
GitLab Runner可以跑在一个单独的机子上。只需要这个机器需要能够访问GitLab服务本身。不过笔者建议进行单独安装,避免搅和在一起相互影响。软件开发是一个整体,前期偷的那点懒,之后会成倍地还回来。
这里以CentOS为例:
######## 准备工作
# 操作系统版本
$ rpm -q centos-release
centos-release-7-7.1908.0.el7.centos.x86_64
# 更改hostname, 让CI执行日志更有辨识度
$ sudo hostname 252Server
######## 安装
# 下载可执行包
wget -O /usr/local/bin/gitlab-runner https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-ci-multi-runner-linux-amd64
# 赋予执行权限
chmod +x /usr/local/bin/gitlab-runner
# 创建runner用户
useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
######## 注册Runner (目的是实现GitLab-Runner与GitLab-CI之间的信息互注册。Runner知道了自己需要操作哪个项目,CI也知道了该runner的存在。刷新Runners settings就可以看到新注册的Runner了。)
# 注意以下输入项大部分是可以在之后进行界面化修改的, 所以不用过分担心.
$ gitlab-runner register
Running in system-mode.
# 以下URL, TOKEN的来源参见下方截图
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://XXX.XXX.XXX.XXX/ # 注意这里使用默认端口80, 笔者经过尝试发现这里即使你特意配置了端口, 之后Runner拉取代码的时候依然是使用默认的80端口. 即使配置了clone_url也无效; 有知道的同学非常欢迎留言, 不甚感激.
Please enter the gitlab-ci token for this runner:
XXXXXXXXXXXXXXXX
Please enter the gitlab-ci description for this runner:
[localhost.localdomain]: XxxGoodName # 取个好名字, 方便自己, 也方便他人.
Please enter the gitlab-ci tags for this runner (comma separated):
pioneer,maven # 使用逗号分割.
Whether to run untagged builds [true/false]: # 默认值为false。这句话的意思是:是否在没有标记tag的job上运行,如果选择默认值false,那没有标记tag的代码提交是不会触发gitlab runner的,如果做测试,最好填true。
[false]: false
Whether to lock Runner to current project [true/false]:
[false]: false
Registering runner... succeeded runner=ZXxxxx
Please enter the executor: docker, shell, virtualbox, docker+machine, docker-ssh+machine, docker-ssh, parallels, ssh, kubernetes:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
######## 安装Runner并作为服务运行
gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
gitlab-runner start
# 查看服务状态
service gitlab-runner status
Runner大体分为两类:
配置文件路径
/etc/gitlab-runner/config.toml on *nix systems when GitLab Runner is executed as root (this is also path for service configuration)
~/.gitlab-runner/config.toml on *nix systems when GitLab Runner is executed as non-root
./config.toml on other systems
工作目录/home/gitlab-runner/
/home/gitlab-runner/
.bash_history
.bash_logout
.bash_profile
.bashrc
builds
cache
.m2
.oracle_jre_usage
.ssh
.gitlab-ci.yml
这里直接给一个测试成功的SpringBoot应用编译, 打包, 部署的配置模板。
# 缓存服务, 如果有文件需要多个stages共用,例如jar/war包
cache:
paths:
- target/
variables:
USERNAME: "Xxxx"
PASSWORD: "Xxxx"
IP: "xx.xx.xx.xx"
# 本次构建的阶段:build package deploy
stages:
- build
- package
- deploy
# 构建 Job
build:
stage: build
tags:
- maven
script:
- echo "=============== 开始编译构建任务 ==============="
- mvn clean compile
# 打包
package:
stage: package
tags:
- maven # 这里和上面我们在注册Runner时候输入的maven tag对应
script:
- echo "=============== 开始打包任务 ==============="
# 这里的 ./ 路径指代项目根目录, 即: /home/gitlab-runner/builds/a9240569/0/root/projectName/
- mvn package -Dmaven.test.skip=true -P product -Dbuild.assemblySavePath=./target/
# 部署
deploy:
stage: deploy
tags:
- maven
script:
- echo "=============== 开始部署任务 ==============="
# 测试,是否能够通过 ssh 连通远程服务器
- sshpass -p $PASSWORD ssh -o StrictHostKeychecking=no $USERNAME@$IP
- echo "=============== 将 war 包部署到远程服务器上 ==============="
- sshpass -p $PASSWORD scp -o StrictHostKeychecking=no target/projectName-bin.zip $USERNAME@$IP:/root/projectName-bin.zip
- echo "=============== 开始执行 ==============="
# 执行shell脚本的时候必须要用命令:source xx.sh,如果只是单纯的执行命令./xx.sh,则切换目录命令cd不会被执行
- sshpass -p $PASSWORD ssh -o StrictHostKeychecking=no $USERNAME@$IP "cd /root && source ./deploy.sh"
我们有必要对GitLab中的一些组件进行了解。
这个是在git项目的根目录下的一个文件,记录了一系列的阶段和执行规则,包含一系列的执行脚本和指定的runner名称。GitLab-CI在push后会解析它,根据里面的内容调用runner来运行。
GitLab-Runner是.gitlab-ci.yml
脚本的运行器,Gitlab-Runner是基于Gitlab-CI的API进行构建的相互隔离的机器(或虚拟机)。GitLab Runner 不需要和Gitlab安装在同一台机器上,但是考虑到GitLab Runner的资源消耗问题和安全问题,也不建议这两者安装在同一台机器上。
可以分类两种类型:Shared Runner和Specific Runner。
Pipelines是定义于.gitlab-ci.yml
中的不同阶段的不同任务。
我们把Pipelines理解为流水线,流水线包含有多个阶段(stages),每个阶段包含有一个或多个工序(jobs),比如先购料、组装、测试、包装再上线销售,每一次push或者MR都要经过流水线之后才可以合格出厂。而.gitlab-ci.yml
正是定义了这条流水线有哪些阶段,每个阶段要做什么事。
任何提交或者merge request的合并都可以触发pipeline。
stages
stages表示构建阶段。一次pipeline可以定义多个stages,他们特点如下:
job
jobs表示构建工作,表示某个stage里面执行的工作。我们可以在stages里面定义多个jobs,这些jobs会有以下特点:
当Pipelines执行完成,会生成徽章,你可以将这些徽章加入到你的README.md文件或者你的网站。