Day29 - GitLab CI 如何让工作流程流水线跑快一点?之三 让 Runner 执行更快一点

上一篇谈到从 .gitlab-ci.yml 开始建立关卡及工作,而後依序分派到工作伫列,等待 GitLab Runner Server 上的 Runner 来承接工作的这段过程,可以怎麽让流水线跑得更快一些。接下来将继续往下谈,当 Runner 接到工作之後,可以怎麽让它更快地完成工作?

首先,可以先思考,当 GitLab Runner 承接到工作後,直到工作执行完成,期间它做了哪些事情?

一、以 Docker Runner 为例,从接到工作开始,到完成工作做了些什麽事情?

在官方的文件上寻觅了许久,一直没能找到谈论各种 GitLab Runner 在承接工作後做了哪些事情的生命周期 (Lifecycle) 描述,所以这边挑了个人比较熟悉的 Docker 作为 Runner executor ,手动作了一个简单的实验,把目前已知在 .gitlab-ci.yml 上有配置设定後,Runner 上就需要跟着做一些工作的流程全都加在一起,像是下载工作成品、建立工作成品、重置快取、建立快取等等的都凑在一个工作之中(有兴趣可以直接查看执行结果)。

一个 Docker 承接工作之後可能有这些工作需要完成

如上图的工作程序,在这个 Runner 承接了工作之後,总共有这几个阶段:

  • Resolving secrets
  • Preparing the “docker” executor:配置 docker 执行环境,包含下取得 docker image
  • Preparing environment:启动 docker
  • Get source from Git repo:从 Git Repository 取得原始码
    • fetching change:更新 Git 原始码纪录
    • checking out xxx as master:清理原始码的环境
    • submodules setup:如果有 submodule 则下载及配置
  • Restoring cache:如有配置 cache 则重置回来
  • Download artifacts:如有工作成品则下载并且解压缩
  • Executing before script:执行前置 Script
  • Executing script:执行主要 Script
  • Executing after script:执行後置 Script
  • Saving cache:储存 Cache
  • Uploading artifacts:上传工作成品
  • Cleaning up file base variables:清除档案型态变数

有了这些程序的过程,就可以逐一讨论这每一个阶段可以怎麽加速:

二、每个阶段可以怎麽加速?

1. 最重要的网路环境状况是否可以更好?(Network Performance)

当 GitLab Runner 承接工作之後,仅只是在该 Runner 上执行工作,这些工作可能还需要一些外部支援,以 Docker Executor 来说,如果执行的环境没有工作需要的 Docker Image,那就必须透过网路将 Docker 下载回来;如系统定义的快取档案不放在 Runner 本地,也需要再次的从网路下载,这些都需要透过网路连线,因此 Runner 与需要的外部资源间的网路环境、品质会影响到整个 Runner 完整将工作执行完成的速度。

2. docker image 是否可以小一点? (Docker image size)

如上一段提到的,当本地没有使用到的 Docker image 的暂存系统就需要再次的从 Docker registry 上面取得,除网路环境好可以加速取得的速度外,使用的 Docker Image 如果也可以小一点,那麽对於整个 Runner 的执行效率也是有帮助的。

image 大小的对照

在这边以 GitLab 官方提供的免费 Runner 为例,其提供的通常预设是 ruby:2.5 的 Docker Image,如执行的 Docker Image 可以替换成如 ubuntu:20.04 执行速度上就会有一个层级的差异,如下图,执行相同 script,仅差别在用不同 Docker Image 的两个工作,ruby:2.5 执行了 43 秒,但使用 ubuntu:20.04 仅花费 19 秒。

速度的比较

3. Git Repo 的尺寸大小影响?

在小型的专案中 Git 物件可能不多,一旦变成大型专案光是 Git Commit 的数量动辄上万个,这样的专案如要完整的 clone 可能都需要花费很长一段时间,如果需要在较大型的 Repo 上建立建立 CI 流程,那麽 Runner 从 Git Repo 上取得原始码的这段时间就必须要重视。

Git shallow clone 选项画面

在 GitLab 的「Settings -> CI/CD -> General pipelines」段落下,有一个 「Git shallow clone」选项,其就是在设定,每次只取得该分支最後的几个变更,GitLab 目前预设为 50 个,如果是可以调整的。

4. 相依套件的大小 Dependence Package Size ?

现阶段许多程序语言都会有自己的相依套件管理工具,在 Script 执行时都会再次的执行套件下载动作,使用的套件们的大小也关系着工作完整执行完成的速度。因此也可以思考:

  • 使用到的套件是否都是必要的?
  • 这些套件是否可以套用快取机制?
  • 如果使用了快取机制,快取存放在哪边?怎麽存放?下载及重置快取的速度会不会比没使用快取还慢?

快取的设定可以参考:Day 24

5. 工作再次拆分,或平行化处理

有些时候,执行的工作是可以考虑拆组後使用 GitLab 的平行化执行处理的。像是大型的单元测试案例,像是单元测试,小专案数量不多的测试案例可能无感,但专案持续的变大如果单元测试数量多到全部执行完成需要一小段时间,那麽就可以开始思考,这些单元测试是否可以拆分?是否都是必要执行的测试?如可以拆分,则可以思考,使用的单元测试是否可以套用 GitLab 提供的平行化处理机制。

平行处理可以参考:Day 17

总结

GitLab Runner 上面调教的方法其实还有蛮多还没谈论到的,在这篇会持续的更新,把各种可以让 Runner 跑得更快的方法统一记录在这里,也期待如果有朋友有其他的想法也欢迎分享。

我是墨嗓(陈佑竹),期待这系列的文章能够让人有些帮助。

参考资料:


<<:  第29天:解构语法、余集(...)

>>:  故事二十九:今晚,简单练习就好!

Day 23 - p5的WebGL应用 3D 设定

3D场景的基础 基础的要素:物体、光源、材质与摄影机 基础几何形状 平面 plane() 长方体 b...

网页表单-30天学会HTML+CSS,制作精美网站

表单在网页上有不同呈现的功能,像是网路投票、注册、购物、问券、搜寻等,用来收集浏览者的资讯,增加与使...

Day20 - ImageView(二)

昨天已经学会把ImageView图片设为Android内建的图片 但说实话 内建的图片ICON我到目...

第 28 集:Bootstrap 客制化 component 元件样式

此篇会介绍如何修改 Bootstrap 元件样式。 事前准备 须先了解变数设置、通用类别设置,再继...

Proxmox VE 启用客体机复写及搭配迁移功能使用

当客体机在 Proxmox VE 节点上运作且客体磁碟储存於节点的本机储存即区时,若想要让客体机的...