用GitLab-Runner打造锋利的CI/CD

原文链接:https://juejin.im/post/5cb5309cf265da034c701d74

一、前言

本文介绍的内容包含:

  • 理解CI/CD及其必要性
  • gitlab-runner安装与注册
  • gitlab-ci配置说明
  • ssh免密登录
  • rsync部署文件
  • 多环境发布与回滚
  • 高频出现的问题并解决

阅读本文需要你:

  • 有一定的ssh知识基础,一份SSH操作指南
  • gitlab ci/cd概念基础
  • 花10min左右的时间

二、CI/CD科普

2.1 CI与CD

<font color="#ff502c">持续集成(Continuous Integration)</font>指开发人员在特性分支(频繁)提交代码,立即执行构建和单元测试,代码通过测试标准后集成到主干的过程。强调的是分支代码的提交、构建与单元测试,这个过程的产出是单元测试报告。

image

说明:这里的 test 是指unit test(图片来源见文末参考链接)

<font color="#ff502c">持续交互(Continuous Delivery)</font>是在持续集成的基础上,将构建的代码部署到「类生产环境」,完成QA测试之后手动部署到生成环境的过程。强调代码部署,这个过程产出测试报告。

image

说明:这里的 test 是真的test

<font color="#ff502c">持续部署(Continuous Deployment)</font>是持续交互的下一步,强调部署生产环境代码的过程自动化,同时可以处理上线通知等操作。

image

说明:与持续交互主要就是手动跟自动的区别。

2.2 CI/CD的必要性

以一言概之的话我想应该是:机械的事情让机器做。一个开发团队,没有CI/CD,我想可能是这样子的:无法管理代码多人多地协作(git repository也是CI的一部分),系列的shell需要人工处理,代码的发布需要登录服务器等等;相反,拥有CI/CD,这些事情都交给机器去完成,腾出的碎片时间去做更有意义的事情(比如摸鱼放松下)。

2.3 理想的CI/CD开发流应该是怎样的?

我认为理想的CI/CD开发流应该包含三个阶段:builddeploynotify。build阶段专注做代码构建与单元测试,deploy阶段专注做test/gray/prod环境的代码部署,notify阶段专注做上线通知,如下图;

image

以下内容围绕build和deploy两个阶段完成从<font color="red">0到1的部署</font>。笔者的系统环境:<font color="red">Ubuntu 18.04.1 LTS</font>

三、Gitlab-Runner安装并注册

3.1 安装runner

sudo apt-get install gitlab-runner

官网文档 install gitlab-runner

3.2 注册runner

sudo gitlab-runner register

之后是QA式操作,按照提示语输入信息即可,可参考官网操作,需要注意:

①. gitlab host和token在你的gitlab项目上找,页面路径是:Settings >> CI/CD >> Runners

②. runner执行器选择 docker,image(镜像)输入 node:8.11.2-stretch

注册成功后,我们就能在:Settings >> CI/CD >> Runners下看到我们注册的runner


image

四、Gitlab-Runner配置

在项目根目录下新建 .gitlab.yml文件,加入如下内容:

image

unit_testcompiledeploy_test是自定义的job名字,另外几点配置说明:

  • cache
    cache设置缓存文件,这里缓存node_module依赖包,提高job构建效率,定义在全局,对所有的job生效;
  • stage
    设置build和deploy两个阶段
  • artifacts
    下载文件。定义compile产出的dist文件夹缓存到gitlab服务器,提供下载(gitlab web页面下载)或者在同一个stage的各job之间共享;
  • only
    定义job的触发条件,可以指定分支名、tags(打tag时触发)等(这些条件是或的关系,满足其中一个即触发);
  • when
    定义job的触发时机,值可以为:on_successalwaysmanual等;
  • dependencies
    定义当前job所要依赖的job;
  • environment
    定义当前job所属的环境,对<font color="red">回滚操作非常有用</font>,后面详述;
  • deploy_test这个job的 before_script 有很长一段内容,这里的作用是配置ssh免密登录,后面详述。

五、ssh免密登录

5.1 为什么需要免密登录?

  • 构建产出的dist文件要传输到目标服务器(测试机/生成机),要么基于http网络协议、要么基于ssh协议(或其他文件传输协议?)
  • 基于http需要写文件接收接口,这里直接使用基于ssh传输文件的rsync,简单、安全!
  • runner内定义的一系列script是在一个docker容器内执行的,无法人工干预,那么登录服务器就要做成免密。

先在本机(注册runner所在的机器)配一遍免密登录服务器的流程:

5.2. 生成一对公私钥

使用rsa作为非对称加密方式:

ssh-keygen -t rsa -C "$(whoami)@$(hostname)-$(date -I)"

说明:一路enter就好了,切记 Enter passphrase 时直接enter,这样就是 no passphrase。如果你非要加个password,对不起,没救了!

5.3. 定义ssh config内容

在~/.ssh/config文件写入以下内容(文件不存在直接创建):

Host any_name
  Port your_port
  HostName server_ip
  User user
  IdentityFile ~/.ssh/id_rsa

说明:定义ssh的config文件是为了快捷访问,就像你配置host一样,没有hostname,你只能访问ip。配置后你就可以通过 ssh any_name 登录服务器了。当然,不出意外,会要求你输入服务器的登录密码。

5.4. 免密登录

免密登录的精髓就是:<font color="red">把本机的公钥存储到目标服务器的authorized_keys文件内</font>(该文件服务器上不存在可以直接创建。)

ssh-copy-id -i ~/.ssh/id_rsa.pub username@ip

特别地:如果你的端口不是默认的22端口,则加上端口号 -p PORT

5.5. 验证登录

ssh any_name

不出意外,你应该可以直接登录服务器了。那么,我们回到gitlab的配置上~

六、gitlab上定义ssh配置信息

我们进入gitlab页面位置:Settings >> CI/CD >> Environment variables下定义 .gitlab.yml 上出现的几个变量:

image

  • SSH_PRIVATE_KEY:把本机(runner所在机器)的私钥复制过来:~/.ssh/id_rsa
  • TEST_CONFIG:把刚才ssh config定义的信息复制过来:~/.ssh/config
  • TEST_KNOWN_HOST:定义这个变量是为了让ssh对服务器进行身份确认(不然会被ssh认为是一个不被信任的环境),变量值使用以下命令生成:
ssh-keyscan -p PORT IP

七、使用rsync传输文件

rsync -rve ssh dist/ user@hostname:project_path/dist

说明hostname就是你在ssh config定义的Host值。rsync操作指南

八、定义environment

设置environment的好处是可以对各发布环境进行管理,特别是线上发布,出现bug可以及时操作回滚。
在gitlab web页面位置:Operations >> environments 可以查看当前项目下的environments,点击其右侧的预览按钮即可<font color="red">查看</font>对应环境的<font color="red">发布</font>效果

image

点击其中一个environment:test_env,可以查看当前环境下的所以发布记录,右侧的按钮可以执行<font color="red">回滚操作</font>。
image

九、踩坑小记

在整个搭建过程,很多都是关于ssh登录服务器的问题,择几个高频出现的问题说明下:

9.1. Host key verification failed

当我们初次使用ssh登录服务器的时候,ssh会要求验证远程服务器的身份,通过身份验证之后才允许连接。解决该问题有两种方式:

  • 设置免身份认证
    在ssh config配置中加一段StrictHostKeyChecking no,如此.gitlab.yml配置中就可以去掉关于known_hosts的设置了;
  • 通过远程服务器的公钥指纹进行身份认证
ssh-keyscan -p PORT IP

将脚本输出的结果保存在~/.ssh/known_hosts文件中(<font color="#ff502c">@gitlab上定义ssh配置信息</font>部分有提及),这样ssh在登录之前会从该文件中拿到目标服务器的公钥指纹进行身份确认。

9.2. Permission denied, please try again

出现这个问题是没有配置「ssh免密登录」,配置操作见<font color="#ff502c">@免密登录</font>部分

9.3. rsync: Failed to exec a: No such file or directory

这个问题一般情况下并不会出现,但却是个实实在在的坑。我在deploy的job里面通过rsync将构建生成的dist目录上传至服务器,抛出不存在该目录的错误。

我在compile这个job执行后,list出根目录下的文件/夹(gitlab-runner的输出):

image

在本机查看根目录下的文件/夹:
image

可以看见,gitlab-runner执行构建后实实在在是生成了dist目录,但进入下一个job的时候却提示不存在!问题出在:
dist目录并不是由构建直接生成的文件夹,而是release-[timestamp]目录的<font color="red">软链接</font>(笔者用的是Ubuntu,在webpack配置里面设置了个骚操作:每次构建产出一个release-[timestamp]目录,同时建立一个软链。软链不是一个目录,它的内容就是目标文件夹的地址)。
在我的.gitlab.yml配置里面,artifacts缓存的是dist,没有把实际的文件夹release-[timestamp]缓存,那么进入下一个job的时候,自然就提示不存在该目录了。解决办法是:

cp dist public

compile这个job里面,构建之后复制一份dist目录,再将public目录交由artifacts缓存。

参考文章

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容