写在前面:
项目了使用公司的私有镜像仓库和GitLab以及已经搭建好的Drone 0.8,所以部署安装这部分跳过,本文着重讲解drone的配置部分。
另外Drone 0.8版本和1.0及以上在语法上有较大的差异,使用新版本的请参考官方文档
一、基本概念
什么是DRONE?
Drone是一个基于Docker容器技术的可扩展的持续集成引擎,用于自动化测试与构建,甚至发布。每个构建都在一个临时的Docker容器中执行,使开发人员能够完全控制其构建环境并保证隔离。 开发者只需在项目中包含 .drone.yml 文件,将代码推送到 git 仓库,Drone 就能够自动化的进行编译、测试、发布。
DRONE基本原理解析
Drone的部署分为Server(drone-server)和Agent(drone-agent),Server端负责后台管理界面以及调度,Agent则负责具体的任务执行。比如配置文件 .drone.yml 里的 parsing 发生在 drone-server端,而具体的步骤则在 drone-agent端里执行。也就意味着environment/build_args关键字是不影响 配置文件.drone.yml 本身环境变量的解析替换。
目前Drone 支持多种代码托管服务,几乎涵盖市面上主流的代码仓库,如Github, GitLab, Gogs, Gitea、Bitbucket Server等,且在drone-server 里预设了对应托管服务的 API,Drone 的很多功能比如拉取 git repo list/add webhook to repo 都是通过这些 API 完成的。另外 Drone的账户体系依赖于托管服务的账户系统, 并不存在维护账户这个概念。例如我们使用GitLab作为代码托管服务,我们在登录 Drone 时,实际上是 Drone 把用户名密码传给了 GitLab. 因此,激活某个 Repository (仓库) 的构建(为Repository 添加webhook) 能否成功取决于该账号在 GitLab 里是不是该 Repository 的管理员。
什么是Webhooks
Drone调用代码仓库的 API 给 Repository 增加一个 webhook ,当 Repository 触发相应事件(push, tag, pull request)时,代码仓库发起 http 请求回调 drone 触发构建。
Drone 通过 OAuth 认证或账号密码登录代码仓库后,获得完整的控制权。在 Drone 的 web后台管理页面激活 Repository 后,Drone调用代码仓库的 API 给 Repository 增加一个 webhook ,当 Repository 触发相应事件(push, tag, pull request)时,代码仓库发起 http 请求回调 drone 触发构建。
Webhooks 由代码仓库发送,用于触发 pipeline。代码仓库会在下面 3 种情况下,自动发送 Webhook 请求到 Drone:
- 代码被 push 到Repository
- 新建一个合并请求(pull request)
- 新建一个tag
二、开始DRONE
下面以一个最小的Flask项目为例,讲解drone的流程及配置
http://drone.iflytek.com/boyang6/drone_test
https://hub.iflytek.com/harbor/projects/621/repositories/drone-test%2Fdrone-test-app
https://git.iflytek.com/boyang6/drone_test
打通GitLab和Drone
Drone
- 在drone的前端页面Repositories配置里勾选你的项目,若不存在则点击Synchronize刷新;
- 设置Secret,
docker_username
、docker_password
分别保存hub仓库的账号密码,ssh_password
保存远程主机的登录密码; - 设置settings,Repository Hooks 只勾选tag,表示只有当代码提交tag的时候才会触发钩子;
- 复制Token里的Personal Token,备用。
GitLab
- 在项目设置里选择集成,使用现有集成Drone CI,配置如下:
Token使用上面Drone复制的Token,填写Drone url,测试无误后保存修改
HUB
- 创建镜像仓库,用于存储构建成功后的镜像
编写 .drone.yml
.drone.yml 文件放在项目的根目录下,与Dockerfile同级
# 定义矩阵变量,通过 ${VARIABLE} 方式引用变量
matrix:
IMAGE_REPO:
- hub.iflytek.com/drone-test/drone-test-app # 定义了一个镜像存储路径的全局变量
RESGISTRY:
- hub.iflytek.com # 定义镜像仓库地址
REPORT_EMAIL:
- boyang6@iflytek.com # CI/CD报告发送的邮件地址
# 手动配置克隆步骤,如果没有定义具体的克隆步骤,Drone 会自动配置
clone:
git:
image: plugins/git
depth: 50 # 当depth为1时,只克隆当前版本,不克隆当前版本以外的提交记录,如果该参数未指定,默认所有版本提交都克隆
tags: true
# drone流水线描述
pipeline:
# 构建和发布镜像
build:
image: plugins/docker # 使用 Docker 插件来构建和发布镜像
registry: ${RESGISTRY}
repo: ${IMAGE_REPO}
secrets: [docker_username, docker_password] # 引用Drone 的 web 页面添加的secrets进行认证
tags: # 同时构建两个镜像,标签为latest方便部署
- ${DRONE_TAG=latest}
- latest
dockerfile: Dockerfile
insecure: true # 启用对此 registry 的不安全通信
when: # 触发条件
event: [ tag ]
# 部署
deploy_staging:
image: appleboy/drone-ssh # 使用 drone-ssh 插件对远程服务器操作
host:
- 172.16.59.204
username: root
port: 22
secrets: [ ssh_password ] # 引用Drone 的 web 页面添加的secrets进行认证
command_timeout: 3m # 超时时间,必须带单位
script:
- docker pull ${IMAGE_REPO}:latest
- docker rm -f drone-test-app || true # 这里这样是因为如果不存在docker-demo,rm会报错
- docker run -itd -p 9080:9080 --name drone-test-app ${IMAGE_REPO}:latest
when:
event: [ tag ]
下面有更详细的注解:
- image:使用插件,指定当前步骤将在该容器内执行
- registry:向这个 registry 进行验证
- username:使用此用户名进行身份验证
- password:使用此密码进行身份验证
- repo:用于存储镜像的仓库名
- tags:用于镜像的仓库的 tag
- dockerfile:要使用的 dockerfile,默认是
Dockerfile
- auth:registry 的身份验证 token
- context:要使用的上下文路径,默认为 git 仓库的根目录
- target:要使用的构建目标,必须在 dockerfile 中定义
- force_tag=false:替换现有的匹配到的镜像的 tag
- insecure=false:启用对此 registry 的不安全通信
- mirror:使用 registry 镜像,而不是直接从 Docker 默认的 Hub 中获取镜像
- bip=false:用于传递 bridge IP
- custom_dns:为容器设置自定义 DNS 服务器
- storage_driver:支持 aufs,overlay 或 vfs 驱动程序
- build_args:自定义参数传递给 docker build
- auto_tag=false:根据 git 分支和 git 标签自动生成标签名称
- auto_tag_suffix:用这个后缀生成标签名称
- debug, launch_debug:以详细调试模式启动 docker 守护进程