某莔の异次元空间
Drone - 从零开始的 CI 生活
更新于:8 个月前 标签:UbuntuCI

以前,我的一些 Project 的部署流程基本都是纯手动的。

1、push to the repository (GitHub / Bitbucket)
2、connecting via SSH to server
3、clone the repository
4、install dependencies
5、stop old service and run the new project

之后,我在合作项目中接触到了持续集成流水线的概念,使得一个应用程序从构建、部署、测试到发布整个过程实现自动化,觉得甚是好用,便决定在自己的项目中尝试一把CI

本文将较为全面地介绍Drone的概念、安装、使用和一些可能遇到的坑。

Drone

Drone is a self-service Continuous Delivery platform for busy development teams.

Drone是一个Golang技术栈的CI解决方案,功能和Jenkins之类的CI工具类似。

优点

  • Golang 编写,镜像体积小,搭建容易,运行时占用资源小
  • 支持主流代码托管平台Webhook沟通
  • 构建运行时采用image优先,保证在不同平台的构建结果一致
  • 支持插件化,提供强大的功能支持
  • 现代化UI设计,操作简单明了

缺点

  • 年轻,常改版
  • 官方的各种文档写的太烂了
  • 功能和完善程度不及一些老牌 CI

架构

由 1 台 Server 通过Webhook跟代码托管平台做沟通,接收到事件后启动Runner来处理 Server 上产生的任务。Runner可以在同一台主机上,也可以分散在多台不同的主机上。

核心概念

pipeline

pipeline可以帮助完成自动化软件交付过程中的步骤,例如启动代码构建、运行自动化测试以及部署到测试或生产环境。pipeline的执行由源代码储存仓库repository触发。代码更改会触发Webhook从而与Drone沟通,后者便开始运行相应的pipeline

pipeline的种类不止一种,例如:

  • Docker:在临时的 Docker 容器中执行命令,保证在不同平台的构建结果一致
  • exec:直接在主机上执行 shell 命令而不隔离,对于不支持容器(如 macOS)的操作系统和体系结构,此运行程序尤其有用
  • ssh:使用 ssh 协议在远程服务器上执行 shell 命令

platform

使用platform配置目标操作系统和体系结构,并将pipeline路由到适当的运行器。如果未指定,则系统默认为Linux amd64。

workspace

Drone会自动创建一个临时卷,称为工作区,在其中 clone repository。工作区是管道中每个步骤的当前工作目录。

steps

steps定义为一系列的 shell 命令。这些命令在 git 仓库的根目录(工作区)中执行,工作区由管道中的所有步骤共享。

一个特定的steps由多个step组成,供pipeline执行,例如:

  • clone、安装依赖、单元测试、生成静态文件、拷贝静态文件

condition

condition决定了当前step的触发条件。

触发条件有多种,例如:

  • 根据 Branch:e.g. master/beta
  • 根据 Event:e.g. push/pull_request
  • 根据 Reference:e.g. refs/heads/feature-*
  • 根据 Repository:e.g. octocat/hello-world
  • 根据 Instance:e.g. drone.instance1.com/drone.instance2.com
  • 根据 Status:e.g. success/failure
  • 更多请参考文档

trigger

trigger决定了当前pipeline的触发条件。

触发条件有多种,基本和condition一致。

安装 & 使用

Server

1、创建 OAuth 应用(以 Bitbucket 为例)

在 Bitbucket 上新建一个 OAuth 应用,Callback URL 填写 Server 配置的登陆地址 http(s)://{{drone_host}}/login,权限配置如图所示:

OAuth1

点击 Save 后获取 Key 和 Secret 以用于Drone授权访问 Bitbucket resources。

OAuth2

2、启动 drone

Docker 启动非常容易,我使用Docker Compose,配置 docker-compose.yml 如下:

version: '3'

services:
    drone-server:
        image: drone/drone:1
        ports:
            - 5000:80
        volumes:
            - /var/lib/drone:/data # SQLite 数据库存储地址
        restart: always
        environment:
            - DRONE_BITBUCKET_CLIENT_ID={{DRONE_BITBUCKET_CLIENT_ID}} # 刚才获取的 Key
            - DRONE_BITBUCKET_CLIENT_SECRET={{DRONE_BITBUCKET_CLIENT_SECRET}} # 刚才获取的 Secret
            - DRONE_RPC_SECRET={{DRONE_RPC_SECRET}} # 可由 openssl rand -hex 16 命令生成
            - DRONE_SERVER_HOST=drone.fix.moe
            - DRONE_SERVER_PROTO=https
            # - DRONE_LOGS_TRACE=true # 日志追踪

执行 docker-compose up -d,启动 drone-server。

3、同步仓库信息 & 激活代码库

如果步骤二没有问题,在浏览器打开 http(s)://{{drone_host}}/ 并授权登陆,完成后即可获得所有当前账号在 Bitbucket 内所拥有的代码库列表。

这时候账号下的项目都是未激活状态,需要点击面板上项目右边的 ACTIVATE 进行激活:

OAuth2

OAuth2

配置好后点击 SAVE 保存即可。经过这几个操作,Drone已经激活了对相应代码库的Webhook事件监听。

至此为止Drone本体的安装基本上完成了,后续只需要配置Runner便可让pipeline顺利执行。

Runner

服务器部分配置完成后,如果没有单独安装和运行Runner,服务器上所有触发的事件都会是 Pending 状态(不要问我怎么知道的)。

1、安装

Runner的安装方法见官方文档Runner也有不同的类型,这里我用Exec Runner举例:

$ curl -L https://github.com/drone-runners/drone-runner-exec/releases/latest/download/drone_runner_exec_linux_amd64.tar.gz | tar zx
$ sudo install -t /usr/local/bin drone-runner-exec

2、配置

Exec Runner需要手动在 /etc/drone-runner-exec/config 创建一个配置文件:

DRONE_RPC_PROTO=https
DRONE_RPC_HOST=drone.fix.moe
DRONE_RPC_SECRET={{DRONE_RPC_SECRET}} # 和上文 drone-server 填写一样
DRONE_LOG_FILE=/var/log/drone-runner-exec/log.txt # log 存储目录,需要自行建立
DRONE_RUNNER_CAPACITY=2 # limits the number of concurrent pipelines that a runner can execute
DRONE_RUNNER_NAME=drone-runner
DRONE_RUNNER_PATH=/usr/local/bin:/usr/bin:/usr/sbin:/sbin # sets the PATH variable for all pipeline steps
DRONE_TRACE=true # 日志追踪

3、启动服务

$ drone-runner-exec service install
$ drone-runner-exec service start
cat /var/log/drone-runner-exec/log.txt

如果日志中有 msg="successfully pinged the remote server",则表明服务启动成功。

结合 .drone.yml 使用

在项目的根目录加入 .drone.yml 文件。以部署本博客为例,原本手动部署流程于本文最上方所示。

---
kind: pipeline
type: exec
name: deploy-master

platform:
  os: linux
  arсh: amd64

steps:
- name: copy
  commands:
  - cp -rf ./ /srv/fix.moe

- name: install
  commands:
  - source /root/.nvm/nvm.sh
  - cd /srv/fix.moe
  - npm install

- name: run
  commands:
  - source /root/.nvm/nvm.sh
  - export PM2_HOME=/root/.pm2
  - cd /srv/fix.moe
  - pm2 stop fix.moe
  - pm2 delete fix.moe
  - pm2 start npm --name fix.moe -- run start

trigger:
  branch:
  - master
  event:
  - push

ok,现在测试一下,对博客做修改,commitpush一气呵成!

OAuth2

0 error(s), 0 warning(s) -> (虽然失败了 N 次)

踩坑

  • 跑流水线无法运行,提示 Pending

    • 检查Runner日志,是否成功连接 Server
    • 检查Server数据库文件是否成功创建
    • 检查.drone.yml配置参数是否正确,type 是否与Runner type 一致
    • 关于 Pending,可以看下官方的一篇帖子:Builds are Stuck in Pending Status
  • 跑流水线时终止在 xxx: command not found

    • pipeline 运行时的 PATH 不同于用户自身的 PATH,需要在配置文件中设置好 DRONE_RUNNER_PATH
    • 根据开发者的回答,commands 默认使用 /bin/sh
  • pm2提示 Spawning PM2 daemon with pm2_home=/drone/xxx/.pm2

    • 想让Drone尝试连接到默认的 daemon path(守护进程路径) ~/.pm2/。需运行 export PM2_HOME=/root/.PM2 ,让用户有权读取此文件夹/文件,就可以列出在根目录下运行的进程。
  • 使用 source xxx.sh 命令提示 source: command not found

    • 在 Ubuntu 里,/bin/sh 默认使用 /bin/dash,而 /bin/dash 不支持 source 命令,如果要使用该命令可尝试以下命令:
      $ ls -l `which sh` # /bin/sh -> dash
      $ sudo dpkg-reconfigure dash # Select "no" when you're asked
      $ ls -l `which sh` # /bin/sh -> bash
      
点评一下
Powered By AraComment
快来抢沙发吧~
次元物语

Ex - ploooosion !

-「为美好的世界献上祝福」