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