Automate Software Testing and Delivery Drone is a self-service Continuous Delivery platform for busy development teams.git
Drone是一个为繁忙的开发团队提供的自助式连续交付平台。github
除了Drone目前作的比较成熟的还有Gitlab-CI、Jenkins、最近新推出的Github-Actions等。由于Drone占用的资源比较少,而且喜欢它的容器即插件的理念,(是我大Golang写的)因此选择用它来体验一下CI。golang
!可是不得不吐槽的是Drone的文档作的很烂。。因此但愿这篇文章能让你少走弯路😇web
本文用的是Drone最新版本,不是网上不少1.0以前的版本,根据这个教程走下去应该不会有什么问题。sql
整个CI流程须要经过 git hook
来触发,Drone支持Github、GitLab、Gitea、Gogs、Bitbucket Cloud、Bitbucket Server几种SCM(source control management),期初我是使用gogs来搭建的,因为https证书问题产生的x509错误最终放弃了gogs方案,最终使用的是github+drone。docker
Drone和Github交互须要经过OAuth进行鉴权,因此要先申请一个OAuth应用。数据库
打开github.com
点击头像,选择Settings / Developer settings / OAuth Apps
,而后点击New OAuth App
建立OAuth应用。bash
其中http://cici.xxxx.com
是你部署Drone的域名,注意callback url 不要填错。服务器
而后注册应用,记录下其中的ClientID
和ClientSecret
下面要用到网络
我这里是经过docker的方式安装的,docker-compose编排。
安装Drone须要一个drone-server
和drone-runner
,
drone-runner不是必选的,官方不推荐吧runner和server安装在一个实例上,若是你安装到一个实例上的话能够设置DRONE_AGENTS_ENABLED=false,drone-server将会做为默认的runner,我这为了演示,runner和server是在一个同服务器上的。
docker-compose.yml 文件:
version: '2'
services:
drone-server:
image: drone/drone:latest
container_name: drone-server
networks:
- dronenet # 让drone-server和drone-agent处于一个网络中,方便进行RPC通讯
ports:
- '10081:80' # Web管理面板的入口 PROTO=http 时使用该端口
- '10082:443' # Web管理面板的入口 PROTO=https 时使用该端口
- '10083:9000' # RPC服务端口
volumes:
- /var/run/docker.sock:/var/run/docker.sock # docker.sock [1]
- /var/data/drone/:/var/lib/drone # drone数据存放路径
environment:
- DRONE_AGENTS_ENABLED=true # 使用Runner
- DRONE_GITHUB_SERVER=https://github.com # github的地址
- DRONE_GITHUB_CLIENT_ID=${DRONE_GITHUB_CLIENT_ID} # 上一步得到的ClientID
- DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET} # 上一步得到的ClientSecret
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET} # RPC秘钥 [2]
- DRONE_SERVER_HOST=${DRONE_SERVER_HOST} # RPC域名(在一个实例上能够不用)
- DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO} # git webhook使用的协议(我建议http)
- DRONE_OPEN=true # 开发drone
- DRONE_DATABASE_DATASOURCE=/var/lib/drone/drone.sqlite # 数据库文件
- DRONE_DATABASE_DRIVER=sqlite3 # 数据库驱动,我这里选的sqlite
- DRONE_DEBUG=true # 调试相关,部署的时候建议先打开
- DRONE_LOGS_DEBUG=true # 调试相关,部署的时候建议先打开
- DRONE_LOGS_TRACE=true # 调试相关,部署的时候建议先打开
- DRONE_USER_CREATE=username:TheWinds,admin:true # 初始管理员用户
- TZ=Asia/Shanghai # 时区
restart: always
drone-agent:
image: drone/agent:latest
container_name: drone-agent
networks:
- dronenet # 让drone-server和drone-agent处于一个网络中,方便进行RPC通讯
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock # docker.sock [1]
environment:
- DRONE_RPC_SERVER=http://drone-server # RPC服务地址
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET} # RPC秘钥
- DRONE_RPC_PROTO=${DRONE_RPC_PROTO} # RPC协议(http || https)
- DRONE_RUNNER_CAPACITY=2 # 最大并发执行的 pipeline 数
- DRONE_DEBUG=true # 调试相关,部署的时候建议先打开
- DRONE_LOGS_DEBUG=true # 调试相关,部署的时候建议先打开
- DRONE_LOGS_TRACE=true # 调试相关,部署的时候建议先打开
- TZ=Asia/Shanghai
restart: always
networks:
dronenet: # 让drone-server和drone-agent处于一个网络中,方便进行RPC通讯
复制代码
openssl rand -hex 16
这个命令随机生成秘钥.env文件:
DRONE_GITHUB_CLIENT_ID=your_github_client_id
DRONE_GITHUB_CLIENT_SECRET=your_github_client_secret
DRONE_RPC_SECRET=your_rpc_secret
DRONE_SERVER_HOST=cici.xxxx.com
DRONE_SERVER_PROTO=http
DRONE_RPC_SERVER=rpc.cici.xxxx.com
DRONE_RPC_PROTO=http
复制代码
将docker-compose.yml
和.env
文件上传至服务器同一目录,而后执行
docker-compose up -d
复制代码
启动服务,一块儿顺利的话打开你的域名你将会看到
OAuth的受权页面,进行受权以后就能够看到管理面板了 💜
基本使用基本上参考https://docs.drone.io/上面的文档就能够了,没什么好说的,下面我主要想说一下Secret管理和私有仓库的使用方法。
CI工做流编排是写在仓库中的.drone.yml
中的,若是咱们想进行一些私有的操做(好比ssh_key,用于通知的帐号密码…)就要把这些敏感信息写在yml里,而这些私有信息的暴露确定是不容许发生的。因此这些秘密信息通常在构建过程当中由CI工具注入到环境变量中的。
drone支持多种secret管理方式,最基本和最方便的方式就是直接经过Web后台进行管理。
打开Repositories/your_repo_name/settings
找到Secrets选项卡,输入Secret Name和Secret Value就能够添加Name=>Value的秘钥键值对了,这些秘钥将在构建过程当中被注入。
下面就来试一下
.
├── .drone.yml
└── main.go
复制代码
package main
import (
"fmt"
"os"
"strings"
)
func main() {
aSecret := os.Getenv("A_SECRET")
fmt.Println(aSecret)
fmt.Println(reverseString(aSecret))
}
func reverseString(s string) string {
r := []rune(s)
sb := strings.Builder{}
for i := len(r) - 1; i >= 0; i-- {
sb.WriteRune(r[i])
}
return sb.String()
}
复制代码
---
kind: pipeline
type: docker
name: default
steps:
- name: build
image: golang
environment:
A_SECRET:
from_secret: a_secret
commands:
- echo $$A_SECRET
- go run . > test_secret.txt - cat test_secret.txt 复制代码
a_secret = terces elbakaepsnu
▶ git commit --allow-empty
[master 0460b0d] test push
▶ git push
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 179 bytes | 179.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To github.com:TheWinds/drone_test_pub.git
0ccca9b..0460b0d master -> master
复制代码
4.构建结果
从活动流里能够看到,已经成功进行了克隆和构建,首先是进行了默认的clone步骤,而后进行的build步骤。
从build的执行结果来看,咱们 echo $A_SECRET
的时候获得的是一个掩码********
,而后在main.go将 $A_SECRET进行反转后获得了unspeakable secret
说明已经成功获得了注入的Secret。
经过查看Drone-Runtime的源码能够看到,运行的时候对于要显示在控制台的内容,都会把Secret Value 加入到string replacer中,统一被替换为掩码********
。然而这并无什么卵用,经过字符串操做就能使其输出未进行掩码的Secret,而后就能进行还原了。。
Drone默认会有一个Clone的步骤,要克隆私有仓库要把这个步骤关闭。
而后把Github该仓库的 deploy_key
对应的私钥设为Secret注入到 SSH_KEY 环境变量中。
接下来建立一个clone的步骤,我这里使用的是alpine/git的镜像,经过echo "$$SSH_KEY" > /root/.ssh/id_rsa
吧私钥写入到id_rsa中,git clone 填写你的私有仓库ssh地址就能够进行克隆了。
deploy_key相比github的全局sshkey,能够控制到仅克隆仓库的权限,适合进行部署操做,具体怎么去设置我就再也不赘述了
生成一对sshkey能够用
ssh-keygen -t rsa -b 4096 -C "your_email"
这个命令
---
kind: pipeline
type: docker
name: default
clone:
disable: true
steps:
- name: clone
image: alpine/git
environment:
SSH_KEY:
from_secret: ssh_key
commands:
- mkdir -p /root/.ssh/
- echo "$$SSH_KEY" > /root/.ssh/id_rsa - chmod -R 600 /root/.ssh/ - ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts - git clone -v git@github.com:TheWinds/drone_test.git . - name: build
image: golang
commands:
- go run . > hello.txt - cat hello.txt 复制代码
DroneCI断断续续搞了将近一周的时间,期间由于文档不清楚找不到问题还放弃了几回🙃。可是都开始了,就很难放弃,查了不少资料看了一下源码后终于整好了。
祝你好运。