三分鐘學會Drone ,CI/CD輕鬆上手!
三分鐘學會Drone ,CI/CD輕鬆上手!
搭好!
最近因為專案需求,需要導入ci/cd流程,開始接觸到drone這套軟體,這是一套開源的持續整合框架,可以幫工程師節省非常多上版的時間,從測試、包版、image化到部屬全部一條龍服務,而且非常容易上手,易於維護,本篇的目標就是要讓大家認識drone,希望可以透過這套工具增進工作效率,let’s get it started!
第一分鐘 drone的概觀:
drone 是一套以GO語言開發的開源專案,可以在github上看到原始碼,也有提供企業版,就我個人的體驗呢,開源版本就已經很好用了啦。
可以參考官方網站的文件:https://docs.drone.io/。
個人列出五大推薦使用drone的原因:
1.drone 支援各大git repository,github,gitlab,bitbucket,gittea等等,只要你的專案是使用git版控,你就可以輕鬆整合drone。
2.drone 的ci流程是以yml檔描述的,非常好理解,且可以靈活調整,只要有使用過docker-compose的經驗應該都可以快速上手。
3.drone 本身是以Go語言打造的,服務啟動速度非常快。
4.drone 是一個docker base的服務,可以快速移植到不同平台上運行,尤其非常適合在k8s叢集的環境中運行。
5.drone drone的社群上已經有各種插件可以使用,也可以用各種語言自製客製化插件,只要包裝成image就能輕鬆加入ci流程當中,非常方便。
最常見的版本有1.x版本以及0.8版本,兩種版本在啟動參數以及pipeline的寫法都差很多,本文使用現在最新的1.6.5版本,以bitbucket為例,demo一個spring boot的CD流程。
*注:0.8版已不支援bitbucket的OAuth格式,請用1.0.0以上版本
第二分鐘:drone的安裝:
drone的架構,分為drone server drone runner, server負責收集git repo的事件,當偵測到pipeline中定義好的條件時,比如說某個branch push,就會觸發pipeline的流程,分派給runner執行。
runner(agent)是實際執行pipeline的容器,可以跟server部屬在不同台機器上,drone runner分成五種,
,適用於不同的情境,分別為:
Docker runner :是drone最常見的用法,pineline中的每一個step都起一個獨立的container運行特定任務,本文即是採用docker runner。
Kubernetes runner:跟docker runner 的功能相似,只是改成Kubernetes 版本,如果你的服務要搭建在k8s上,就用這個。
Exec runner:用於你的專案不適合跑在容器內的狀況EX:MacOs專案。
SSH runner:直接以ssh 連線到遠端以default shell 執行pipeline流程,需要使用openssh 7.9 以上版本。
Digital Ocean runner :用於當你的pipeline需要權限可以操作整台虛擬機的情況,且不適合跑在容器內。
一個server可以接多個runner分別處理不同的pipeline ,如果你的專案很複雜,也可以將一個pineline的各個step分配給多個runner,最後再整合再一起。
另外還有drone cli:以command line的方式操作drone server ,如果你在drone server的ui畫面找不到你要設定的東西,那肯定是要用drone cli設定。
在安裝drone 之前要先做兩件事:
1.那因為drone 整個服務都是依賴docker 所以在安裝drone之前一定要先裝docker (最好也要有docker-compose,比較方便)
如果是還沒有使用過docker的讀者,我推薦你可以先參考這篇 ,所有你需要知道的docker的知識都在裡面: https://yeasy.gitbooks.io/docker_practice/introduction/
2.取得bitbucket的OAuth ID 跟SECRET
(1)登入bitbucket點選左下角有你名子的小圈圈,然後點選bitbucket settings
(2)點選setttings畫面的OAuth
(3)點選add consumer
(4)callback URL設定為你的https://<你的domain || ip+port>/login (0.8版請用 /authorize)
bitbucket不接受localhost或是127.0.0.1,所以要開ngrok
權限設定照著勾就可以了。
還不認識ngrok的讀者,可以參考官方網站:https://dashboard.ngrok.com/get-started
簡單來說就是載一個ngrok.exe 啟動後在cmd介面上輸入 ngrok http <你想對外開放的port號>,它就會把你的port開放給全世界
官方推薦用docker run 的方式來安裝drone,我將官方的docker run 指令寫成docker-compose.yml 如下:
version: '2'
services:
drone-server:
image: drone/drone:1
ports:
- 8081:80 #drone sever http port
volumes:
- ./:/data # sqlite的檔案,裡面存一些drone server的訊息
restart: always
environment:
- DRONE_USER_CREATE=username:<你的bitbuckert帳號的username>,machine:false,admin:true # 建立admin權限的使用者 cli登入用
- DRONE_SERVER_HOST=xxxx.ngrok.io # 指定Drone server URL(domain || ip+port)
- DRONE_SERVER_PROTO=https # 指定Drone server URL連線協議(http || https)
- DRONE_TLS_AUTOCERT=false# 自動生成 ssl 證書,並接受 https 連線,默認為false
- DRONE_RPC_SECRET=<自訂一個SECRET># PRC連線密鑰
# BITBUCKET Config
- DRONE_BITBUCKET_CLIENT_ID=<你的OAuth ID> # OAuth 的 Application ID
- DRONE_BITBUCKET_CLIENT_SECRET=<你的 OAuth Secret> # OAuth 的 Secret
# log
- DRONE_DEBUG=true # 開啟debug mod
- DRONE_LOGS_PRETTY=true # 開啟log pettify
- DRONE_LOGS_COLOR=true # 開啟log區分顏色
- DRONE_LOGS_TRACE=true # 開啟日誌
drone-runner:
image: drone/drone-runner-docker:1
restart: always
ports:
- 3000:3000
depends_on:
- drone-server # 指定在drone-server啟動之後才會啟動drone-runner
volumes:
- /var/run/docker.sock:/var/run/docker.sock # 將本機docker的sock mount給內部docker
environment:
- DRONE_RPC_HOST=xxxx.ngrok.io # 指定Drone server URL(與drone-server設定一致即可)
- DRONE_RPC_PROTO=https # 指定與Drone server 的連線協議(http || https)
- DRONE_RPC_SECRET=<上面server設定的SECRET> # PRC連線密鑰(須與drone-server設定一致)
- DRONE_RUNNER_CAPACITY=3 # 可以同時執行的任務數
- DRONE_LOGS_TRACE=true # 開啟日誌
- DRONE_RUNNER_NAME=dev_depoly #Optional string value. Sets the name of the runner
*注:drone 1.0以後支援單機版本,就是drone-server可以同時擔任runner的腳色,
配置的話就把上面的drone-runner區塊刪掉,然後在drone-server區塊加入一些原本在runner的參數:
environment:
- DRONE_AGENTS_DISABLED=true
- DRONE_RUNNER_CAPACITY=3
volumes:
- /var/run/docker.sock:/var/run/docker.sock
*注:drone的sqlite是用來儲存user,bulid log之類的資訊,也可以改存在mysql或Postgres
environment:
- DRONE_DATABASE_DRIVER=mysql
- DRONE_DATABASE_DATASOURCE=root:password@tcp(1.2.3.4:3306)/drone?parseTime=true
*注:如果某帳號已經登入過了,DRONE_USER_CREATE不會在新建一個使用者,必須要以cli登入。
更多配置可以參考:https://docs.drone.io/server/reference/
docker-compose.yml配置完成之後,以cmd cd 到該yml所在目錄 輸入 docker-compose up -d指令
如果沒有意外,應該可以看到兩個綠綠的done,就表示安裝完成了。
如果沒起起來,可以往以下幾個方面排查:
1.先確認docker 可以正常運作
2.在win10上執行,docker desktop要開啟share drives 的設定
3.配置有誤,看看yml檔有沒有多打tab,各參數是否都正確
4.確認port號是否已經被占用(用檢查一下 netstat -nao |find "0.0.0.0:8081")
5.如果有奇怪的錯誤,可以上社群看有沒有人問過同樣的問題:https://discourse.drone.io/
6.如果有些設定沒有如預期中生效,也可以搜尋一下drone 的changelog,看是不是已經改參數但文檔還沒更新:https://github.com/drone/drone/blob/master/CHANGELOG.md
OK 如果server 順利啟動,打開瀏覽器輸入剛剛設定host url 就會出現一個授權畫面,按下confirm然後你就會跳轉到首頁:
這邊就會列出你在bitbucket裡面所有的專案,選擇一個你想要加入CI/CD流程的專案按下active (你必須要有此專案的admin權限),然後進入專案
然後你會看到一些設定,project setting trusted一定要勾起來,不然會沒辦法進行cache操作,其餘設定的基本上不用去更改,用default值就可以了
這邊可以看到configuration指定的是.drone.yml,意思是drone server會去讀取這個檔案,決定你的專案pipeline的流程怎麼跑
假如你有特殊需求,你也可以設多個yml檔,讓每個server 跑不一樣的pipeline。
網頁上的設定蠻陽春的,如果想了解更多可以參考appleboy大大的這部影片:https://www.youtube.com/watch?v=OlucMSF1Xss
其他更多的設定都需要cli才可以使用。
第三分鐘:drone 的pipeline
OK, 接下來我們開始寫.drone.yml,也就是drone的精華所在
這邊就是看你的專案需要什麼CI/CD的步驟就加什麼步驟近來
以我的專案來說,最基本的需求,我需要自動化 測試 -> 打包 -> 佈署
看起來就會像醬子:
kind: pipeline
name: dev_depoly
steps:
#1.maven 測試
- name: maven-test
image: maven:3.6.1-jdk-8
commands:
- cd ./MyProject
- mvn test
#2.maven 打包
- name: maven-build
image: maven:3.6.1-jdk-8
commands:
- cd ./MyProject
- mvn clean package -DskipTests=true -Dmaven.javadoc.skip=true -B -V
#3.upload jar file
- name: scp
image: appleboy/drone-scp
settings:
host:
from_secret: host_ip
username:
from_secret: host_user
password:
from_secret: host_password
port: 22
command_timeout: 2m
target:
- <yourPath>
source:
- <yourTargetPath>/<yourProjectFinalName>.jar
#4.deploy
- name: ssh commands
image: appleboy/drone-ssh
settings:
host:
from_secret: host_ip
username:
from_secret: host_user
password:
from_secret: host_password
port: 22
script:
- echo ====开始部署=======
- cd <yourPath>
- kill $(cat ./pid.file)
- java -jar <yourProjectFinalName>& echo $! > ./pid.file &
- echo ====部署成功======
trigger:
branch:
- master
event:
- tag
- push
================================
pipeline一樣是一個yml格式
kind:可以填三種值,pipeline,secret,signature
分別代表三種物件類型
signature: 是透過cli指令生成,用來保護你的pipeline不要被隨意串改用的。
secret: 類似宣告變數概念,用來儲存一些可變動的資訊
大概長這樣
如果資訊你不希望被別人看到,你可以把secret存在drone server上:
pipeline: 是最常用的,用來定義流程
有分成五種type,對應前面介紹的五種runner,預設用type為docker。
name:可以指定runner name,表示此pipeline分派給特定runner執行,defualt會隨機指派。
step:定義pipeline流程的各個步驟
有一個預設的step會先自動clone 你的專案下來,放在runner image的工作目錄,不用寫他也會執行。
一般的step,只要三個參數就可以work
name(單一pipeline內不重複),
image:<imageName>:<tag>,
command:在image內部執行指令
如範例的maven-test
這樣runner 就會起一個image,並且將image工作目錄mount 到runner image的工作目錄。
pipeline 過程中就是透過這個機制傳遞每個階段的執行結果。
另外step 還可以設定,volumes跟environment,作用就跟docker run -e -v 參數的效果一樣
,比較特別的是使用volumes還需寫要在pipeline底下加一個volumes屬性,volume可以設多個以不同的name區分,範例如下。
.......
steps:
- name: Maven install
image: maven
volumes:
- name: cache
path: /root/.m2
commands:
- mvn clean install
- name: ...
...
...
volumes:
- name: cache
host:
path: /tmp/cache/.m2
trigger:
...
==================
其實大部分CI/CD會需要的的功能官方或社群的支持者已經有提供各式各樣的plugin,如範例裡面第3,4步,只要指定image name,按照文檔裡的格式帶入參數就可以work,非常省時省力,而且可以依照需求隨時置換不同的plugin,使用起來非常舒服。
這邊提供官方plugins給大家參考:http://plugins.drone.io/
再來如果要控制流程的step的執行時機,可以設置when屬性
- name: Maven install
image: maven
commands:
- mvn clean install
when:
event:
include:
- push
條件的設計很靈活,可以指定特定的event、branch、repository、status才執行,或特定條件不執行
可以參考官方文件自行組合:https://docs.drone.io/pipeline/docker/syntax/conditions/
如果沒有特別指定的話,預設是前面的step fail的話,後面的step就不會執行。
如果是要控制整個pipeline的執行條件,就要使用pipeline的trigger屬性,用法跟when屬性大同小異,可以用來區別不同環境的pipeline流程。
詳見官方文件:https://docs.drone.io/pipeline/triggers/
你也可以在drone server 的setting頁面加入cron job,然後在pipeline的trigger加入event:- cron,就可以在特定的時間觸發pipeline
最後如果流程中需要用到本次建置的metadata,如branch、commit hash 、repository等等,官方提供了${變數名稱}的語法,可以在pipeline中調用
例如:
- name: publish
image: plugins/docker
settings:
#這樣可以取commit sha-1的前八碼
tags: ${DRONE_COMMIT_SHA:0:8}
repo: xxxuser/xxxxrepo
官方文件有列出所有可以使用的變數名稱:https://docs.drone.io/pipeline/environment/reference/
如果運行順利,就可以看到本次bulid過程,各個階段的console,有出現錯誤也會有錯誤訊息
如果說,現有的plugin都不符合你的需求,你想自己做一個image加入你的ci/cd流程,也很簡單。
首先執行docker login ,輸入以下指令:
docker login -p <password> -u <dockerhubAccount>
登入你的dockerhub帳號
然後bulid一個客製化的images,通常使用一個Dockerfile
==================
## maven image 為基底
FROM maven:latest
## PLUGIN_開頭的環境變數,可以在step中 用setting置換
ENV PLUGIN_HELLO=hi
## 改寫image啟動後的指令
ENTRYPOINT [ "/bin/sh", "-c", "echo $PLUGIN_HELLO" ]
=================
使用指令build docker image
docker build -t <dockerhubAccount>/drone-plugin-test .
然後上傳docker image
docker push <dockerhubAccount>/drone-plugin-test
就可以在流程中使用囉!
- name: test
image: <your Account>/drone-plugin-test
pull: false
settings:
hello: testting
commands:
- echo $PLUGIN_HELLO
上面的範例只是單純的echo 一個環境變數,實際運用可以run一個腳本或程式去完成你在CI/CD流程中要做的事。
總結一下本篇重點,drone 是一套非常輕量化CI工具,兼容各大git repository,利用docker-compose 可以快速搭建,也很適合在容器化的環境運行,pipeline內容是以yml檔描述,易於閱讀也很好維護,有多樣的plugins可以套用,快速開發出適合專案的pipeline。OK !以上就drone的簡單介紹,有任何問題歡迎留言指教,謝謝!
介紹得很詳盡!但是我沒辦法三分鐘就學會(笑)
留言打完案發表要登入,登入完跑到這個網站的首頁
按上一頁才能回到這頁,然後剛打的東西就全消失了
重打留言再按一次發表,又跳到登入頁面要我再登入...