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斷斷續續搞了將近一週的時間,期間由於文檔不清楚找不到問題還放棄了幾回🙃。可是都開始了,就很難放棄,查了不少資料看了一下源碼後終於整好了。
祝你好運。