一、介紹
Drone是一個(gè)用GO語言編寫的基于Docker的持續(xù)集成、持續(xù)交付平臺,所有的編譯、測試的流程都在Docker容器中執(zhí)行。Drone使用簡單的YAML配置文件來定義和執(zhí)行Docker容器中的Pipelines,開發(fā)人員只需要在項(xiàng)目中包含.drone.yml文件,將代碼推送到Git版本控制倉庫中,Drone就能夠自動(dòng)化的進(jìn)行編譯、測試和發(fā)布。
Drone可以無縫集成多個(gè)源碼管理的平臺,包括Github、GitLab、Bitbucket、Gitea、Gogs等,如果企業(yè)是基于上面幾個(gè)搭建的源碼管理平臺,可以和Drone無縫集成。Drone原生就是跨平臺的,支持多種操作系統(tǒng)和架構(gòu),包括Linux x64、ARM、ARM64和Windows x64。Drone是在Docker容器里執(zhí)行流水線,所以Drone支持任意編程語言、數(shù)據(jù)庫和服務(wù)。
二、特性
1、配置文件即代碼
Drone中定義Pipeline(流水線)都是通過命名為.drone.yml的配置文件來定義的。這個(gè)配置文件是以簡單、易讀的YAML格式編寫,如下圖所示。這個(gè).drone.yml文件需要和代碼一起提交到Git版本控制倉庫中,納入版本管理,方便變更記錄的跟蹤和回溯。每條流水線的執(zhí)行都是在一個(gè)獨(dú)立的Docker容器中執(zhí)行,在執(zhí)行時(shí)自動(dòng)下載需要的組件。
2、插件體系
Drone是通過插件體系兼容多方平臺和提供強(qiáng)大的功能。Drone在執(zhí)行時(shí),使用容器將預(yù)先配置好的步驟加入到Pipeline中,然后從現(xiàn)有的插件體系中選擇需要的插件,或者可以創(chuàng)建自己的插件。這里需要提到的是已經(jīng)和釘釘、微信等通信工具集成。
在Drone里使用插件不會(huì)像Jenkins里那樣,Jenkins是在自己的平臺里管理自己的插件,插件和流水線構(gòu)建是集成在一起的,每次進(jìn)去都會(huì)看到升級的提示。但在Drone里,插件管理和流水線是分開的,在Pipeline里聲明一下,只要有網(wǎng)絡(luò)連接能訪問到就可以,究竟插件是如何管理,如何升級的都可以不用管。
3、獨(dú)立的構(gòu)建環(huán)境
因?yàn)槊看螛?gòu)建都運(yùn)行在獨(dú)立的Docker容器里,不用擔(dān)心由于構(gòu)建環(huán)境共用導(dǎo)致的問題。同時(shí),也解決了企業(yè)內(nèi)部多種開發(fā)語言,構(gòu)建工具版本的不同的問題,準(zhǔn)備一個(gè)鏡像就可以解決。基于Docker的構(gòu)建環(huán)境的創(chuàng)建同樣也能夠加入到Git版本控制倉庫,也能對構(gòu)建環(huán)境的版本進(jìn)行管理和追溯。
4、構(gòu)建環(huán)境的自動(dòng)擴(kuò)縮容
首先,基于Docker容器的構(gòu)建環(huán)境本身就具有自動(dòng)擴(kuò)縮容的能力。每次都是通過構(gòu)建一下新的容器環(huán)境來執(zhí)行流水線任務(wù),只要資源足夠,可以支持無限制的構(gòu)建任務(wù)。
Drone提供了一個(gè)Autoscaler的組件,是一個(gè)獨(dú)立運(yùn)行的后臺進(jìn)程,需要安裝在宿主機(jī)上,而且不同的云平臺安裝方式也不一樣。這個(gè)組件能夠根據(jù)構(gòu)建任務(wù)的數(shù)量自動(dòng)創(chuàng)建和終止服務(wù)器的實(shí)例,從而實(shí)現(xiàn)構(gòu)建環(huán)境的自動(dòng)擴(kuò)縮容的目標(biāo)。
三、安裝
Drone的安裝包含Server端和一個(gè)或多個(gè)Runners。一個(gè)runner是一個(gè)安裝在遠(yuǎn)端服務(wù)器上的獨(dú)立的后臺進(jìn)程,它通過輪詢服務(wù)器上的負(fù)載決定是否執(zhí)行,將runner安裝在許多個(gè)服務(wù)器上來創(chuàng)建分布式的網(wǎng)絡(luò)。
1、Server端
上面提到,Drone可以無縫集成多種源碼管理平臺,在進(jìn)行Server端安裝時(shí),需要與源碼管理平臺進(jìn)行集成,這里以GitHub為例進(jìn)行說明:
第一步:準(zhǔn)備工作
創(chuàng)建一個(gè)OAuth應(yīng)用程序,在Github設(shè)置里創(chuàng)建一個(gè)OAuth應(yīng)用程序,Key和Secret用于授權(quán)訪問Github上的資源。
創(chuàng)建一個(gè)共享的Secret,這個(gè)Secret用于Server和Runner之間的通信,可以使用openssl生成一個(gè)共享的Secret。
$ opensslrand-hex16bea26a2221fd8090ea38720fc445eca6
第二步,下載Drone鏡像
Drone是以一個(gè)輕量級的Docker鏡像分發(fā)的,這個(gè)鏡像是自包含的,不需要任何其他的外部依賴。
$ docker pull drone/drone:1
第三步,配置Server
Drone Server采用環(huán)境變量的方式進(jìn)行配置。這里需要設(shè)置的變量有:
DRONE_GITHUB_CLIENT_ID:github oauth Client ID
DRONE_GITHUB_CLIENT_SECRET:github oauth Client Secret
DRONE_GIT_ALWAYS_AUTH:clone時(shí)是否每次都需要授權(quán),只在Github Enterprise私有模式下生效
DRONE_RPC_SECRET:通過RPC連接到server的授權(quán)Secret
DRONE_SERVER_HOST:提供外部主機(jī)名或IP地址
DRONE_SERVER_PROTO:http或https協(xié)議,當(dāng)使用ssl或acme配置時(shí)默認(rèn)是https。
第四步,啟動(dòng)服務(wù)器
通過如下的命令啟動(dòng)服務(wù)端容器,配置需要的參數(shù)通過環(huán)境變量,這是使用docker run方式啟動(dòng)。
dockerrun \? --volume=/var/lib/drone:/data \? --env=DRONE_AGENTS_ENABLED=true \? --env=DRONE_GITHUB_SERVER=https://github.com \? --env=DRONE_GITHUB_CLIENT_ID=${DRONE_GITHUB_CLIENT_ID} \? --env=DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET} \? --env=DRONE_RPC_SECRET=${DRONE_RPC_SECRET} \? --env=DRONE_SERVER_HOST=${DRONE_SERVER_HOST} \? --env=DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO} \? --publish=80:80 \? --publish=443:443 \? --restart=always \? --detach=true \? --name=drone \? drone/drone:1
基于Github的Server就啟動(dòng)了,其他的源碼控制管理平臺的安裝也是一樣。
2、Runner安裝
一旦Server端安裝完畢后,就需要安裝Runner來執(zhí)行Pipelines。Drone支持多種形式的Runner,下面單獨(dú)介紹:
Docker Runner:當(dāng)在Docker容器里執(zhí)行構(gòu)建流水線時(shí)安裝此Runner。
Kubernetes Runner:當(dāng)Drone運(yùn)行在Kubernetes上時(shí),該Runner在Pods里執(zhí)行構(gòu)建流水線。
Exec Runner:當(dāng)直接在宿主機(jī)上執(zhí)行構(gòu)建流水線時(shí)安裝此Runner,通常都是采用shell腳本。
SSH Runner:當(dāng)需要在遠(yuǎn)程服務(wù)器上執(zhí)行構(gòu)建流水線時(shí),通過SSH協(xié)議直接調(diào)用執(zhí)行。
DIgital Ocean Runner:這個(gè)Runner使用SSH協(xié)議在一臺專用的Droplet上執(zhí)行,這個(gè)Droplet在每個(gè)流水線執(zhí)行時(shí)創(chuàng)建,完成后銷毀。
四、配置
一個(gè)項(xiàng)目以配置即代碼的方式存儲(chǔ)配置文件,在項(xiàng)目的根目錄下添加一個(gè).drone.yml文件,這個(gè)文件和代碼庫一起加入版本控制,并遵循相同的分支結(jié)構(gòu)。每次推送代碼、創(chuàng)建或更新一個(gè)Pull Request、或者推送一個(gè)Tag時(shí),系統(tǒng)將獲取這個(gè)yaml配置文件并執(zhí)行這個(gè)Pipeline。主要配置以下幾個(gè)資源:
1、Pipeline
一個(gè)Pipeline為這個(gè)項(xiàng)目定義了一個(gè)持續(xù)集成和持續(xù)交付的過程,可以認(rèn)為是一個(gè)工作流,定義了如何構(gòu)建、測試和部署等步驟。pipeline配置樣例:
---kind:pipelinetype:dockername:defaultsteps:-name: buildimage:golangcommands:-go build-go test...
Drone支持不同類型的執(zhí)行環(huán)境,每種類型的環(huán)境都有自定義的yaml規(guī)范。kind和type屬性定義了pipeline的類型和目標(biāo)執(zhí)行環(huán)境。根據(jù)上面Runner類型的不同,這里的yaml文件的配置也是不一樣的,通過type這個(gè)字段進(jìn)行區(qū)分,每種類型的Runner支持的Yaml文件的規(guī)范也是不一樣的,特殊類型要特殊對待。
2、Secrets
Secret用戶存儲(chǔ)和管理敏感信息,有下面幾種級別的設(shè)置。
代碼庫級別:
代碼庫的Secrets用于存儲(chǔ)和管理敏感信息,如密碼、令牌和ssh密鑰。將此信息存儲(chǔ)在Secrets中比純文本的配置文件更加安全。
組織級別:
組織級別的Secrets可以用于這個(gè)組織下的任意代碼庫。
加密Secrets:
加密Secrets用于存儲(chǔ)敏感信息,如密碼、令牌和ssh密鑰,將此信息作為加密的字符串存儲(chǔ)在配置文件中??梢允褂妹钚泄ぞ呒用躍ecrets,每個(gè)代碼庫都單獨(dú)加密,這個(gè)Key從不離開服務(wù)器環(huán)境。
External
外部的Secrets用于從外部的Secrets存儲(chǔ)里獲取敏感信息,如密碼、令牌和ssh密鑰。
3、Signature簽名
可以選擇對配置文件進(jìn)行簽名,以驗(yàn)證其真實(shí)性并防止篡改。這個(gè)簽名在代碼庫是公共的,并且需要防止對配置進(jìn)行未經(jīng)授權(quán)的更改時(shí)會(huì)很有用。如果用戶修改配置并且簽名驗(yàn)證失敗,流水線將被阻止,需等待對代碼庫具有寫權(quán)限或管理權(quán)限的用戶手動(dòng)批準(zhǔn)。
4、Cron定時(shí)調(diào)度
可以使用Cron jobs來執(zhí)行基于時(shí)間的調(diào)度,可以在代碼庫的Settings界面上創(chuàng)建和管理cron job或使用命令行工具。
表達(dá)式
cron表達(dá)式代表了任務(wù)執(zhí)行的時(shí)間集合,包含6個(gè)字段,各字段說明如下:
Drone內(nèi)部已經(jīng)定義了一些調(diào)度的cron表達(dá)式,如@yearly、@monthly、@weekly、@daily、@hourly。
五、試用
在Drone Cloud平臺上,可以與Github集成,構(gòu)建Github上的代碼倉庫,這里我選擇了一個(gè)SpringBootTest的代碼庫,使用Github的頁面編輯新增.drone.yml文件,如下:
提交之后就會(huì)觸發(fā)Drone流水線構(gòu)建
點(diǎn)擊進(jìn)入到流水線詳情頁面。第一步是clone代碼庫階段,clone不需要在yml文件內(nèi)聲明。
第二步是test階段,這一步是.drone.yml文件中聲明的,通過日志可以看出,該步驟是先拉取了gradle:jdk8的鏡像,然后在該容器內(nèi)部執(zhí)行的流水線步驟。
六、總結(jié)
如今,越來越多的企業(yè)開始重視軟件研發(fā)的效率和質(zhì)量,也有越來越多的企業(yè)開始采用DevOps理念來提升效率和質(zhì)量。在整個(gè)軟件研發(fā)全生命周期中,CICD是非常重要并且提升效率最為明顯的階段。通過實(shí)現(xiàn)自動(dòng)化,能夠大幅縮短從開發(fā)到測試到部署的時(shí)間。
隨著Docker、Kubernetes等容器技術(shù)的成熟,特別是一線互聯(lián)網(wǎng)公司已經(jīng)將自己的業(yè)務(wù)部署在云端。在不遠(yuǎn)的未來,云計(jì)算必將成為軟件系統(tǒng)運(yùn)行的基礎(chǔ)設(shè)施環(huán)境,就像如今的水和電一樣想用就用。云計(jì)算的普遍使用,也催生了云原生技術(shù)的發(fā)展,同時(shí)也催生了云原生下的CICD平臺的崛起,Drone就是其中一員。
Jenkins在一段時(shí)期內(nèi)是CICD的代名詞,界面化的操作和配置根本無法談增效,Jenkins 2.0后,通過配置即代碼的最佳實(shí)踐,將流水線的構(gòu)建過程配置到j(luò)enkinsfile里,提交到代碼倉庫下也納入到了版本控制下,但真正用起來的并不多見。Jenkins X是下一代基于云原生的CICD框架,以Docker和Kubernetes容器生態(tài)為基礎(chǔ)組件,通過命令行的方式實(shí)現(xiàn)CICD的所有功能。
JenkinsX和Drone都屬于云原生下的CICD框架,都能充分利用容器的天然優(yōu)勢,提高CICD的靈活性和效率,JenkinsX目前仍在開發(fā)中,Drone目前來看已經(jīng)在多個(gè)案例使用。如果打算構(gòu)建容器環(huán)境的CICD平臺,Drone可以是個(gè)不錯(cuò)的選擇。