首发于平等的黑

快速理解持续集成工具 Drone CI 核心概念

本文以 docs.drone.io/ 的内容和相关实践为基础,快速过一遍 drone 的核心概念,简述一些功能点的实现原理,旨在让有一定使用经验用户可以更透彻的了解 CI 配置过程,不再把 drone 当成一个未知的黑盒系统。

一、架构部署篇

这里可以讲的地方不多,主要是运维和配置的参数。


首先要对 drone-server 和 drone-agent 有个感性的认知,大概了解它们的职责。比如 .drone.yml 的 parsing 发生在 drone-server,具体的 steps 跑在 drone-agent. 这样很容易推理出 environment/build_args关键字是不影响 .drone.yml 文件本身环境变量的解析替换。

drone 目前支持四种 git 托管服务(github, gitlab, gogs, gitea) 而 drone-server 预先知晓了对应托管服务的 API,drone 的很多功能比如拉取 git repo list/add webhook to repo 都是通过这些 API 完成的。

还有 drone 并不维护 user 这个概念,它把 user 的管理委托具体的托管服务。以 gogs 为例,我们在登录 drone 时,实际上相当于 drone 把用户名密码传给了 gogs(委托鉴权)。同样由于这个原因,激活某个 repo 的构建(给repo加webhook) 能否成功取决于你这个账号在 gogs 里是不是该 repo 的管理员。

二、使用篇

Webhooks

前文已经介绍过,drone调用 gogs 的 API 给 repo 增加一个 webhook,当 repo 触发相应事件(push, tag, pull request)时,gogs 发起 http 请求回调 drone 触发构建。

Workspace

利用 docker volumn 特性,在一次具体的构建生命周期里,映射一个路径跨越所有 steps ,这个关键字不需要显示配置。

Pipelines

核心概念,drone-agent 以自上而下的顺序依次执行 pipeline 关键字下面声明的步骤。
可以通过设置 group 关键字让某几个不相互依赖的 step 并行执行。

Services

用类似docker-compose 的语法,提供服务作为 CI/集成测试过程中的支撑。

Plugins

核心概念,drone 除了build命令之外的功能基本都通过插件完成,可以做到 docker容器构建、自动部署、FTP上传 IM通知等很多事情。其中用于构建镜像的 docker plugin 的文档(plugins.drone.io/drone-)一定要精读一遍。

Matrix Builds

矩阵构建,更适用于开源项目和 libs 维护者。可以为同一个环境变量声明多组值,笛卡尔积后进行交叉构建。Matrix Builds 是唯二可以在 .drone.yml 文件里注入环境变量的手段。

Environment

环境变量可以按照生效位置(drone-server/drone-agent)分为两大类,具体到多个使用场景。这里要细说一下。

1) .drone.yml 本身的变量

一共有两处,这两处的变量可以在 .drone.yml 文件中直接以 ${XX_XX_XX} 的格式使用,并在 parsing 阶段被替换为具体值。这个行为发生在 drone-server 里,属于构建周期的最早期阶段。

它们分别是:

这两类环境变量暴露出的信息很有限,matrix builds 只能是常量。drone的预设变量里只有 DRONE_COMMIT_MESSAGE 可控。drone 会对其前后插入双引号,末尾加换行符,内容里的特殊字符加转移等方式保证 .drone.yml 文件的安全性和防注入。


2) CI 容器端的变量

这几处变量是作用在 drone-agent 端。包括:

  • pipeline 部分的 environment 关键字,类似 docker-compose. 影响 CI 执行容器的运行时环境变量。等效于在容器里执行 export XX_ENV=XXX
  • build_args 关键字,影响 Dockerfile 文件本身的环境变量。在 docker build 过程中生效。等效于 Dockerfile 里声明 ARG 关键字,也等效于构建命令 docker build --build-arg variable_name=value_a . 常用场景主要是 http_proxy 变量

另外 build_args(ARG) 引申出的话题属于 docker 本身的范畴,需要对 Dockerfile 的 ARG 关键字和 ENV 关键字要有所区分。它们大致上是差不多的,区别是变量的生效周期,前者在 docker build 执行期间。而后者还会 persist 到产物 image 里。


三、常见坑

Registry Credentials

registry credentials 会影响 agent 端能否从私有镜像仓库里 pull 镜像。典型的位置是 `.drone.yml` 文件中声明的 docker image (e.g. build 步骤的基础构建镜像,或者其他步骤的插件镜像比如 image: drone/docker )

在开源版里,这个参数配置粒度是 per Repo,所以用户要为每一个 Repo 都分别 add 一组配置。简单的方式是修改 drone-server 的源码,自己编译一个企业内部的专用版。或者额外暴露一个 env 变量用于全局配置。

Secrets

secrets 最主要的一个作用是在 pipeline (build image and push) 这一步,用于存放私有 docker-registry 的用户名和秘钥。跟 registry credentials 类似,在开源版的 drone 里面,配置粒度也是 per repo.

由于 secrets 参数是插件镜像(plugin image) 专有语法里用到的,所以这个不得不配置在 .drone.yml 文件里,通过 .drone.yml 的配置语法,传入插件镜像。也就是说,通常情况下,secret的使用一定会侵入 yml,只是它对应的密文,对能查看这个 git repo 的用户不可见。可以通过修改 `github.com/drone-plugin` 这个工程,重新构建属于企业私有的专用镜像来规避。既能简化配置语法(简化掉私有仓库地址,insecure=true, registry的username和password等四个参数) 也能免去开源免费版里需要在每个repo里独立配置的繁琐。


多扯两句,总有人觉得这两个可以是一个东西。不过在 drone 的视角下,不能这样假设。drone 在设计中,把这两个配置分离开来,可以让 pull image 跟 push image 两个步骤对应两个不同的 private docker registry.

编辑于 2018-09-03

文章被以下专栏收录