暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Gitlab CI/CD 实现自动化集成部署 应用

小王学长的笔记 2021-08-20
251

一、需求来源

提出需求:当提交代码到git仓库的时候 开发环境可以自动实现集成部署。

解决方案:最简单的方法是 每次git push的时候就会自动执行 git仓库 的钩子文件,钩子文件去执行 开发环境的 同步、部署代码的 脚本即可。

当然我们这里使用的要复杂一点,利用 Gitlab CI 去实现该功能。

在介绍 GitLab CI 之前,我们先看看一些持续集成相关的概念。


二、相关概念

2.1 Pipeline

一次 Pipeline 其实相当于一次构建任务,里面可以包含多个流程,如安装依赖、运行测试、编译、部署测试服务器、部署生产服务器等流程。任何提交或者 Merge Request 的合并都可以触发 Pipeline。

2.2 Stages

Stages 表示构建阶段,说白了就是上面提到的流程。我们可以在一次 Pipeline 中定义多个 Stages,这些 Stages 会有以下特点:

  • 所有 Stages 会按照顺序运行,即当一个 Stage 完成后,下一个 Stage 才会开始

  • 只有当所有 Stages 完成后,该构建任务 (Pipeline) 才会成功

  • 如果任何一个 Stage 失败,那么后面的 Stages 不会执行,该构建任务 (Pipeline) 失败

2.3 Jobs

Jobs 表示构建工作,表示某个 Stage 里面执行的工作。我们可以在 Stages 里面定义多个 Jobs,这些 Jobs 会有以下特点:

  • 相同 Stage 中的 Jobs 会并行执行

  • 相同 Stage 中的 Jobs 都执行成功时,该 Stage 才会成功

  • 如果任何一个 Job 失败,那么该 Stage 失败,即该构建任务 (Pipeline) 失败

2.4 GitLab Runner

2.4.1 简介

理解了上面的基本概念之后,有没有觉得少了些什么东西 —— 由谁来执行这些构建任务呢?答案就是 GitLab Runner 了!

想问为什么不是 GitLab CI 来运行那些构建任务?一般来说,构建任务都会占用很多的系统资源 (譬如编译代码),而 GitLab CI 又是 GitLab 的一部分,如果由 GitLab CI 来运行构建任务的话,在执行构建任务的时候,GitLab 的性能会大幅下降。

GitLab CI 最大的作用是管理各个项目的构建状态,因此,运行构建任务这种浪费资源的事情就交给 GitLab Runner 来做拉!因为 GitLab Runner 可以安装到不同的机器上,所以在构建任务运行期间并不会影响到 GitLab 的性能~

2.4.2 安装

安装 GitLab Runner 太简单了,按照着 官方文档 的教程来就好拉!下面是 Debian/Ubuntu/CentOS 的安装方法,其他系统去参考官方文档:

# For Debian/Ubuntu
$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash
$ sudo apt-get install gitlab-ci-multi-runner

# For CentOS
$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash
$ sudo yum install gitlab-ci-multi-runner

2.4.3 注册 Runner

安装好 GitLab Runner 之后,我们只要启动 Runner 然后和 CI 绑定就可以了:

打开你 GitLab 中的项目页面,在项目设置中找到 runners

点开 Runners 查看 CI的URL 和Token

注册方式1

运行 sudo gitlab-ci-multi-runner register
输入 CI URL
输入 Token
输入 Runner 的名字
选择 Runner 的类型,简单起见还是选 Shell 吧
完成

注册方式2

gitlab-runner register --name A --url http://B/ --registration-token C
WARNING: Running in user-mode.
WARNING: The user-mode requires you to manually start builds processing:
WARNING: $ gitlab-runner run
WARNING: Use sudo for system-mode:
WARNING: $ sudo gitlab-runner...

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
[http://B/]:
Please enter the gitlab-ci token for this runner:
[C]:
Please enter the gitlab-ci description for this runner:
[A]:
Please enter the gitlab-ci tags for this runner (comma separated):
A
Whether to run untagged builds [true/false]:
[false]:
Whether to lock Runner to current project [true/false]:
[false]:
Registering runner... succeeded runner=S
Please enter the executor: shell, virtualbox, docker+machine, docker-ssh+machine, kubernetes, docker, docker-ssh, parallels, ssh:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

当注册好 Runner 之后,可以用 sudo gitlab-runner list 命令来查看各个 Runner 的状态:

sudo gitlab-runner list检查

$ sudo gitlab-runner list
Listing configured runners ConfigFile=/etc/gitlab-runner/config.toml
my-runner Executor=shell Token=cd1cd7cf243afb47094677855aacd3 URL=http://mygitlab.com/ci

gitlab-runner验证
此命令检查已注册的运行程序是否可以连接到GitLab,但它不验证GitLab Runner服务是否正在使用运行程序。示例输出是

$ sudo gitlab-runner verify
Running in system-mode.

Verifying runner... is alive runner=5_tVnBmx

三、编写.gitlab-ci.yml

配置好 Runner 之后,我们要做的事情就是在项目根目录中添加 .gitlab-ci.yml 文件了。当我们添加了 .gitlab-ci.yml 文件后,每次提交代码或者合并 MR 都会自动运行构建任务了。

还记得 Pipeline 是怎么触发的吗?Pipeline 也是通过提交代码或者合并 MR 来触发的!那么 Pipeline 和 .gitlab-ci.yml 有什么关系呢?其实 .gitlab-ci.yml 就是在定义 Pipeline 而已拉!

3.1 基本写法

我们先来看看 .gitlab-ci.yml 是怎么写的:

# 定义 stages
stages:
- build
- test

# 定义 job
job1:
stage: test
script:
- echo "I am job1"
- echo "I am in test stage"

# 定义 job
job2:
stage: build
script:
- echo "I am job2"
- echo "I am in build stage"

用 stages 关键字来定义 Pipeline 中的各个构建阶段,然后用一些非关键字来定义 jobs。每个 job 中可以可以再用 stage 关键字来指定该 job 对应哪个 stage。job 里面的 script 关键字是最关键的地方了,也是每个 job 中必须要包含的,它表示每个 job 要执行的命令。

回想一下我们之前提到的 Stages 和 Jobs 的关系,得出运行结果如下。

I am job2
I am in build stage
I am job1
I am in test stage

根据我们在 stages 中的定义,build 阶段要在 test 阶段之前运行,所以 stage:build 的 jobs 会先运行,之后才会运行 stage:test 的 jobs。

3.2 实战:实现代码同步

# .gitlab-ci.yml 内容如下
stages:
- update
update:
stage: update
script:
- echo "Now, CI is begin"
- /A/update.sh
- echo "Now, CI is end!"
only:
- dev
tags:
- update

注意:我这里只有一个stage是update。only指定了只有在dev分支push的时候才会被执行。tags是为注册runner的时候的tags。

update.sh脚本内容如下

#!/bin/bash
cd /A/
git pull --rebase;
cp -rf B/* /C/

在本人在开发机器上 push代码到Gitlab后,CI自动进行Piplines, 结果图如下

以上在本人在开发机器上 push代码 没问题,但是多人协作,其他人在自己的机器提交代码后,就会出现了权限不足的等一系列报错,如下所示。

insufficient permission for adding an object to repository database .git/objects

这个时候就需要 进阶版,使用SSH登录后在进行代码同步更新。

四、配置SSH实现免密登录

4.1 添加变量

gitlab项目/群组 -> 设置 -> CI/CD -> 变量

如上图 CI.png 的红框 6和7对于的功能,进行添加变量

SSH_USER = root
SSH_HOST = 服务器ip
SSH_KNOWN_HOSTS = 文件 ~/.ssh/known_host 有你服务器ip的一行
SSH_PRIVATE_KEY = 文件 ~/.ssh/id_rsa 里的内容

4.2 编辑.gitlab-ci.yml

stage:
- Deploy
Deplpy:
stage: Deploy
only:
- master
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
when: manual #手动确认之后才能构建
script:
- pwd
- ls -l
#主要同步代码的命令,可以在这里排除一些文件,同步权限,配置服务器的项目路径等。重点参考rsync命令的用法。
- rsync -aztp --exclude ".gitlab-ci.yml" ./ $SSH_USER@$SSH_HOST:/xxx

如此即可大功告成!!!

有不懂得可以,在本文评论或者私信我。

关于我


大家好,我是你们的小王学长,毕业于华五高校。

我曾在校期间,获得过头条、阿里、腾讯等多家大厂的SSP。因为追求Geek精神,选择加入商汤担任研究员。


目前我在商汤也是一位面试官,可以带实习生。(名额方面不确定,有的话,我会发公众号或朋友圈!目前我手下有4个实习生。)


欢迎大家加我私信(坑位不算多),星标微信公众号"小王学长的笔记",第一时间收到我所更新的信息。


如果您觉得本文还不错的话,欢迎赞赏哈~




    微信号 sagewang666

微信公众号 | 小王学长的笔记



文章转载自小王学长的笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论