CI/CD初探(docker+drone)

將使用 docker + docker compose + drone + git 實現項目自動部署

使用docker可以讓drone實現任意語言程序的構建與部署

分工

docker: 整潔迅速的部署方案

docker-compose: 組網和簡單容器編排

drone: go語言寫的基于docker的CI框架

流程預覽

代碼提交到git

git 通知drone應用

觸發(fā)drone服務器運行項目下的.drone.yml

如果沒有配置clone步驟, drone會運行默認的clone步驟, 并clone到workspace設置下的path

依次運行pipeline下的步驟, 通常是 test -> build -> publish -> ssh連接到運行服務容器的服務器 并重啟容器, 下面會依次說明pipeline各步驟.

安裝Drone

可參考drone官方文檔

官方使用docker-compose安裝, 編寫docker-compose.yml如下

docker-compose.yml

version:'2'services:? drone-server:? ? image:drone/drone:latest? ? ports:? ? ? -8082:8000? ? ? -9000? ? volumes:? ? ? -/workspace/docker/volumes/drone:/var/lib/drone/? ? restart:always? ? environment:? ? ? -DRONE_OPEN=true? ? ? -DRONE_HOST=${DRONE_HOST}? ? ? -DRONE_CODING=true? ? ? -DRONE_CODING_CLIENT=${DRONE_CODING_CLIENT}? ? ? -DRONE_CODING_URL=https://coding.net? ? ? -DRONE_CODING_SECRET=${DRONE_CODING_SECRET}? ? ? -DRONE_CODING_GIT_MACHINE=e.coding.net? ? ? -DRONE_CODING_SCOPE=user,project,project:depot? ? ? -DRONE_GITHUB_SKIP_VERIFY=false? ? ? -DRONE_SECRET=${DRONE_SECRET}? ? ? -DRONE_ADMIN=bysir? ? ? -DRONE_CODING_GIT_USERNAME=${DRONE_CODING_GIT_USERNAME}? ? ? -DRONE_CODING_GIT_PASSWORD=${DRONE_CODING_GIT_PASSWORD}? drone-agent:? ? image:drone/agent:latest? ? command:agent? ? restart:always? ? depends_on:? ? ? -drone-server? ? volumes:? ? ? -/var/run/docker.sock:/var/run/docker.sock? ? environment:? ? ? -DRONE_SERVER=drone-server:9000? ? ? -DRONE_SECRET=${DRONE_SECRET}? ? ? -DRONE_MAX_PROCS=5

備注

字段注釋

DRONE_ADMIN管理員, 名字是你版本控制的賬號名, 添加了管理員的才可以管理用戶

DRONE_OPEN是否開啟新用戶注冊

DRONE_GITHUB使用github作為版本控制

在上面你會看到其中有${DRONE_HOST}的變量,這是docker-compose支持的語法,文檔

我們需要在同級目錄下編寫一個.env文件來寫入這些變量

.env

# drone的安裝服務器, 不需要端口DRONE_HOST=http://47.94.204.137 # DRONE需要GITHUB作為應用授權, 這里填寫授權賬號密碼, 詳情看[文檔](http://docs.drone.io/install-for-github/)DRONE_GITHUB_CLIENT=xxxxDRONE_GITHUB_SECRET=xxxx# 用于drone服務器和agent之間的密鑰, 隨意填寫DRONE_SECRET=123456

現在運行docker-compose up就能運行drone了, 順利的話就不會看到報錯, 如果有報錯就按報錯提示來解決.

訪問服務器 8080端口就能看到drone的web頁面了, 使用GITHUB的賬號登陸即可, 登陸后drone會自動拉去項目目錄, 點擊項目就能開啟對這個項目的監(jiān)管.

編寫項目

需要單獨為每一個項目編寫.drone.yml文件 用來表述在代碼提交后需要執(zhí)行哪些操作.

用一個簡單的go項目說明

.drone.yml

workspace:? base: /go? path: src/github.com/bysir-zl/gokit_startpipeline:? build:? ? image: golang:1.9? ? commands:? ? ? -pwd- go env? ? ? - go version? ? ? - go build? publish:? ? ? image: plugins/docker? ? ? registry: https://index.docker.io/v1/# 倉庫repo: bysir/golang_base# docker倉庫地址# mirror: https://docker.mirrors.ustc.edu.cn# 需要使用drone cli添加secrets: http://docs.drone.io/manage-secrets/secrets: [ docker_username, docker_password ]? ? ? tags:? ? ? ? - latest? deploy:? ? ? image: appleboy/drone-ssh? ? ? host: 47.94.204.137? ? ? username: root? ? ? port: 22? ? ? secrets: [ ssh_key ]? ? ? script:? ? ? ? -cd/root/app? ? ? ? - docker-compose pull bysir/golang_base? ? ? ? - docker-compose up

workspace

其中workspace指定pipeline的工作目錄, 上例中我們會在build中pwd看到當前目錄是/go/src/github.com/bysir-zl/gokit_start, 為什么我們需要指定到/go目錄下, 因為在golang:1.9的鏡像中,go_path就是/go, 我們要go build當然要在go_path下執(zhí)行.

build

build步驟很簡單只是go build, 你好奇為什么沒有go get, 因為我將vendor目錄也一起提交了, 推薦使用go官方依賴管理工具dep

docker在構建的時候都是以一個空白鏡像golang:1.9作為基礎的, 如果不提交vendor就需要每次構建都go get, 十分耗時. 當然還有辦法就是提交一個已經按照好go包的基礎鏡像到registry里, 在build中的image就換成你提交的鏡像. 相比之下更簡單的方法就是提交vendor目錄.

publish

publish步驟就有點復雜了, 使用到了plugins/docker插件, 這個插件是drone寫的, 用于發(fā)布docker鏡像. 它的作用就是構建一個鏡像, 并push到registry.

我們需要配置的值有

registry: 倉庫registry, 如hub.docker.com的registry地址是https://index.docker.io/v1/

repo: 在docker倉庫下的項目名稱

secrets: drone用于傳遞密鑰的實現方式, 下面會詳細介紹

在plugins/docker插件中, 構建項目鏡像是通過Dockerfile來的, 所以我們還需要在項目根編寫一個Dockerfile

Dockerfile

FROM alpine:latestCOPY gokit_start /WORKDIR /ENTRYPOINT ["./gokit_start"]

其中ENTRYPOINT是容器啟動后的運行入口, "./gokit_start"是示例項目build后的二進制文件

deply

發(fā)布流程就是通過SSH登陸上要部署程序的服務器pull下剛剛publish的鏡像并啟動.

登陸SSH就需要配置ssh_key或者ssh_password, 更多詳情看appleboy/ssh這個插件的文檔, 這里推薦使用ssh_key, 我們需要在drone的secrets添加一項ssh_key值為私鑰, 然后我們將與之匹配的公鑰放在服務器上.ssh/authorized_keys里, 這樣就能使用ssh_key登陸上服務器并執(zhí)行script.

擴展閱讀: 私鑰登錄原理

為什么要生成一對秘鑰將秘鑰放在drone的ssh_key:

DroneService(A)想要登錄Service(B)并執(zhí)行命令, 在SSH登錄認證的時候需要A用私鑰簽名一段信息發(fā)送到B, B收到請求后會使用.ssh/authorized_keys中的公鑰依次驗簽, 如果驗簽成功則登錄成功.

ps: 私鑰的格式是-----BEGIN RSA PRIVATE KEY-----xxxxxxxxx-----END RSA PRIVATE KEY-----全部放在web頁面就行了, 如下

添加secrets

在publish步驟有secrets選項, 其中docker_username和docker_password是由drone注入的, 所以我們需要在drone右上角添加secrets:

添加之后如下:

secrets實現原理:

drone有一個專門存儲secrets的地方, 當pipeline中step需要secrets的時候, 會得到其值并設置為容器的環(huán)境變量

上例中drone會從數據庫拿到docker_username和docker_password并賦值給環(huán)境變量DOCKER_USERNAME和DOCKER_PASSWORD, 在plugins/docker中會使用這兩個環(huán)境變量去登陸你設置的registry:docker login -p $DOCKER_PASWORD -u $DOCKER_USERNAME $DOCKER_REGISTRY

擴展閱讀:安裝drone cli

可以使用drone的cli來添加secrets:manage-secrets

安裝方法:CLI Installation

curl -Lhttps://github.com/drone/drone-cli/releases/download/v0.8.3/drone_linux_amd64.tar.gz| tar zx

sudo install -t /usr/local/bin drone

CLI需要通過server的授權:CLI Authentication

exportDRONE_SERVER=http://47.94.204.137:8080exportDRONE_TOKEN=eyJh33OiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXh0IjoiYnlzaXItemwiLCJ0eXBlIjoidXNlciJ9.jLsJvi4PafTi-ffefe5-bYTD2N_xmIi9fg

之后就可以使用cli執(zhí)行命令

添加secrets

drone secret add? -repository bysir-zl/gokit_start? -image plugins/docker? -name docker_username? -value bysir

drone secret add? -repository bysir-zl/gokit_start? -image plugins/docker? -name docker_password? -value 123456

刪除secret

drone secret rm --repository bysir-zl/gokit_start --name docker_username

測試

現在你的項目機構應該類似于

項目

現在你可以將你寫的代碼和配置文件一起提交到git, 然后你就能看到這個項目正在構建

你可以點擊查看構建步驟

ps

終于跑起來了

我相信你沒有我這么菜

2018/04/27 更新

最近需要使用coding作為版本控制軟件

文檔說drone-server在0.8版本之后是支持coding的, 但實際不然. 實際運行起來會報錯:version control system not configured

找了很久的原因, 翻了很久源代碼發(fā)現并沒有問題, 知道發(fā)現這個詳情可看這個issue

I encounter this issue too.

When use drone from latest docker image, setting DRONE_CODING=true has no effect, result: "version control system not configured".

When build drone from git source code, It's works.

I found

gitclonegit@github.com:drone/drone-enterprise.git extras

go build -ldflags '-extldflags "-static" -X github.com/drone/drone/version.VersionDev=build.'${DRONE_BUILD_NUMBER} -o release/drone-server github.com/drone/drone/extras/cmd/drone-server

at .drone.sh,

You use drone-enterprise.git for extras to build the docker image, not the open source code.

Is that the problem?

所以我嘗試使用git上源碼重新編譯一個drone-server使用, 修改倉庫下.drone.sh如下:

#!/bin/sh# clone the extras project.set-eset-x# 由于要運行在alpine, 所以需要加GOOS=linux GOARCH=arm64 CGO_ENABLED=0# 由于drone-server使用到了sqlite3, sqlite3使用到了gcc, 所以需要-extldflags "-static"# -ldflags "-extldflags -static" at the end makes sure C code is statically linked so resulting binary truly has no dependencies even for C code.go build -ldflags'-extldflags "-static" -X github.com/drone/drone/version.VersionDev=build.'0.01 -o release/drone-server github.com/drone/drone/cmd/drone-serverGOOS=linux GOARCH=amd64 CGO_ENABLED=0? ? ? ? go build -ldflags'-X github.com/drone/drone/version.VersionDev=build.'0.01 -o release/drone-agent? ? ? ? ? ? github.com/drone/drone/cmd/drone-agentGOOS=linux GOARCH=arm64 CGO_ENABLED=0? ? ? ? go build -ldflags'-X github.com/drone/drone/version.VersionDev=build.'0.01 -o release/linux/arm64/drone-agent github.com/drone/drone/cmd/drone-agentGOOS=linux GOARCH=arm? CGO_ENABLED=0 GOARM=7 go build -ldflags'-X github.com/drone/drone/version.VersionDev=build.'0.01 -o release/linux/arm/drone-agent? github.com/drone/drone/cmd/drone-agent

重新編譯, 打包鏡像.

為了方便, 我將做好的鏡像放在了共有倉庫下:

bysir/drone-server(對于官方0.8.5的版本)

可以這樣使用:

version:'2'services:? drone-server:? ? image: bysir/drone-server? ? ports:? ? ? - 8082:8000? ? ? - 9000? ? volumes:? ? ? - /workspace/docker/volumes/drone:/var/lib/drone/? ? restart: always? ? environment:? ? ? - DRONE_OPEN=true- DRONE_HOST=${DRONE_HOST}- DRONE_CODING=true- DRONE_CODING_CLIENT=${DRONE_CODING_CLIENT}- DRONE_CODING_URL=https://zhuzi.coding.net? ? ? - DRONE_CODING_SECRET=${DRONE_CODING_SECRET}- DRONE_CODING_GIT_MACHINE=e.coding.net? ? ? - DRONE_CODING_SCOPE=user,project,project:depot? ? ? - DRONE_GITHUB_SKIP_VERIFY=false- DRONE_SECRET=${DRONE_SECRET}- DRONE_ADMIN=bysir? drone-agent:? ? image: drone/agentcommand: agent? ? restart: always? ? depends_on:? ? ? - drone-server? ? volumes:? ? ? - /var/run/docker.sock:/var/run/docker.sock? ? environment:? ? ? - DRONE_SERVER=drone-server:9000? ? ? - DRONE_SECRET=${DRONE_SECRET}

ps: 真是折騰... 不過終于好了

作者:bysir

鏈接:http://www.reibang.com/p/1e5f819f8881

來源:簡書

簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處钥顽。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末别威,一起剝皮案震驚了整個濱河市丘逸,隨后出現的幾起案子,更是在濱河造成了極大的恐慌赫段,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異毛仪,居然都是意外死亡,警方通過查閱死者的電腦和手機芯勘,發(fā)現死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門箱靴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人荷愕,你說我怎么就攤上這事衡怀。” “怎么了安疗?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵抛杨,是天一觀的道長。 經常有香客問我荐类,道長怖现,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮屈嗤,結果婚禮上潘拨,老公的妹妹穿的比我還像新娘。我一直安慰自己饶号,他們只是感情好铁追,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著茫船,像睡著了一般脂信。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上透硝,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天狰闪,我揣著相機與錄音,去河邊找鬼濒生。 笑死埋泵,一個胖子當著我的面吹牛,可吹牛的內容都是我干的罪治。 我是一名探鬼主播丽声,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼觉义!你這毒婦竟也來了雁社?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤晒骇,失蹤者是張志新(化名)和其女友劉穎霉撵,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體洪囤,經...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡徒坡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了瘤缩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喇完。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖剥啤,靈堂內的尸體忽然破棺而出锦溪,到底是詐尸還是另有隱情,我是刑警寧澤府怯,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布刻诊,位于F島的核電站,受9級特大地震影響富腊,放射性物質發(fā)生泄漏坏逢。R本人自食惡果不足惜域帐,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一赘被、第九天 我趴在偏房一處隱蔽的房頂上張望是整。 院中可真熱鬧,春花似錦民假、人聲如沸浮入。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽事秀。三九已至,卻和暖如春野舶,著一層夾襖步出監(jiān)牢的瞬間易迹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工平道, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留睹欲,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓一屋,卻偏偏與公主長得像窘疮,于是被迫代替她去往敵國和親嘱巾。 傳聞我的和親對象是個殘疾皇子胖烛,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內容