您好,登錄后才能下訂單哦!
UCloud內(nèi)部長期使用 Gitlab 來管理代碼。雖然Gitlab作為一套開源平臺已很優(yōu)秀,但我們對于其能為CI/CD提供的敏捷性并不十分滿意,內(nèi)部實踐中的代碼發(fā)布周期仍需按天計算。為此,我們打造了一個基于Kubernetes的內(nèi)部容器服務(wù)平臺(名為KUN),用于托管內(nèi)部服務(wù),并將Gitlab對接到KUN平臺,從而借助Kubernetes的云原生優(yōu)勢,獲得更好的CI/CD效果。這套系統(tǒng)運行一年內(nèi),Gitlab的Pipeline一共觸發(fā)了994次,執(zhí)行了約20000+次Job,在測試環(huán)境和正式環(huán)境一共進行了7000+次部署,即每天部署約20次。以下是該項目的一些實踐經(jīng)驗。
我們對CI/CD的目標(biāo)
CI即Continuous Integration(持續(xù)集成),指代碼集成到主干之前必須通過自動化測試,只要有一個測試用例失敗,就不能集成。目的是讓產(chǎn)品快速迭代的同時還能保持高質(zhì)量。
CD有兩種意思:
Continuous Delivery,持續(xù)交付,指的是任何的修改都經(jīng)過驗證,可以隨時實施部署到生產(chǎn)環(huán)境。
Continuous Deployment,持續(xù)部署,是持續(xù)交付的更高階段,指的是任何修改后的內(nèi)容都經(jīng)過驗證,自動化的部署到生產(chǎn)環(huán)境。
兩者的區(qū)別,在于是否自動部署到生產(chǎn)環(huán)境。對UCloud而言,肯定要以后者,也就是持續(xù)部署為目標(biāo)。
Gitlab分支管理
我們采用的Gitlab分支管理模型在接入KUN平臺前后并未發(fā)生變化,故簡述如下:
master:主分支,代碼經(jīng)過驗證。從 master 創(chuàng)建 tag 進行 Release。
dev:研發(fā)主分支,用于合入特性分支和補丁分支,在此分支。
臨時分支:
特性分支:用于開發(fā)某個特性;
補丁分支:用于修復(fù)線上 bug。
下面以一個實例來介紹CI/CD開發(fā)流程。StepFlow是UCloud新近推出的一款可視化工作流產(chǎn)品,通過StepFlow用戶可以靈活便捷地定義自己的工作流,快速實現(xiàn)業(yè)務(wù)功能。整套StepFlow系統(tǒng)由多個模塊組成,并全部部署在Kubernetes集群上。
在實例中,我們需要開發(fā)其中名為optimize-allocate 的一個feature:
則開發(fā)流程為:
首先,在 Gitlab 上創(chuàng)建了編號為80的Issue,跟進這個optimize-allocate的feature;
從dev分支創(chuàng)建一個新分支,名為feature/80-optimize-allocate,在該分支上進行開發(fā);
在feature/80-optimize-allocate上開發(fā)完成,進行commit,此時會觸發(fā)靜態(tài)測試、單元測試、Review等Pipeline Job;
測試通過后,創(chuàng)建一個從feature/80-optimize-allocate到dev的merge request,由負(fù)責(zé)人進行審核。審核通過并且merge成功后,觸發(fā)靜態(tài)測試、單元測試、鏡像構(gòu)建、鏡像部署、集成測試等Pipeline Job;
注:版本號tag是有命令規(guī)范的,v{x}.{y}.{z}代表著v{主版本}.{次版本}.{小修訂版本}
Gitlab CI/CD Pipeline
Gitlab 8.0版本以后,默認(rèn)集成并開啟了Gitlab-CI,是可以提供一定CI能力的,我們以此搭建持續(xù)集成的流水線,其中有Pipeline、Stage和Job三個層級需要設(shè)計。
Pipeline
Gitlab 會檢測一個項目的根目錄下的 .Gitlab-CI.yml 文件,用戶可在該文件中定義 CI/CD Pipeline,一個 Pipeline 代表了 CI/CD 的整個過程。代碼發(fā)生變化時(比如 push、tag、merge等),將觸發(fā)一個 Pipeline 的運行。
Stage
一個 Pipeline 包含多個 Stage,比如“靜態(tài)檢查”、“單元測試”、“構(gòu)建鏡像”等等,這些 Stage 一個接一個順序執(zhí)行。
Job
每一個 Stage 可以包含多個 Job,同一個 Stage 的所有 Job 同時執(zhí)行。每個Job需指定若干個重要屬性如image, stage, tags, service等。
在StepFlow例子中,針對要開發(fā)的feature,其Pipeline設(shè)計如下,包括靜態(tài)檢查、單元測試和最后的兩個手動 Code Review:
當(dāng)其需要發(fā)布到公共測試環(huán)境(類似預(yù)發(fā)布環(huán)境),則設(shè)計另一個Pipeline,包括:執(zhí)行完整的靜態(tài)檢查, 單元測試, 預(yù)發(fā)布鏡像 build, 預(yù)發(fā)布部署, 預(yù)發(fā)布集成測試。
而合并 master 之后觸發(fā) prod 環(huán)境的另一個 Pipeline,包括靜態(tài)檢查、生產(chǎn)環(huán)境鏡像的 build、生產(chǎn)環(huán)節(jié)的部署、最后集成測試:
Gitlab Runner
我們將Gitlab Runner和Gitlab-CI配合使用,負(fù)責(zé)具體 Job 的運行。Gitlab Runner Kubernetes Executor 提供了在 Kubernetes 中運行 Job 的能力。運行原理如下:
Gitlab Runner 需要事先部署并注冊到 Gitlab 上;
當(dāng)代碼發(fā)生更新時,Gitlab 根據(jù)用戶的配置,通知 runner 來運行 Job;
Gitlab Runner 使用某個鏡像來創(chuàng)建一個 Pod,然后在其中運行某些命令;
Gitlab Runner 將整個運行過程以及運行結(jié)果告訴 Gitlab。
Kaniko集成和改造:在容器中構(gòu)建Docker鏡像
為了使用 CI/CD 將代碼變成最終運行在 Kubernetes 中的服務(wù),必不可少的一步就是容器鏡像的構(gòu)建。由于CI Job本身就是以容器的形式運行的,所以需要在容器中構(gòu)建出 Docker 鏡像。
已有的方法,包括把 Host 上的 Docker Socket 掛載到 Pod 里面去(Docker Socket Mounting),或者是在 Pod 再啟動一個 Docker Daemon(Docker-in-Docker),然而,前者有安全風(fēng)險,后者需要 Pod 具備特權(quán),兩種方法都不適合。
Kaniko(https://github.com/GoogleContainerTools/kaniko)是 Google開源的一個工具,可以實現(xiàn)在 docker 容器里面制作 docker 鏡像,并且不需要任何特權(quán)。
但是原生的 Kaniko 鏡像由于缺少一些必要的工具,無法和Gitlab CI集成。為此我們修改了Kaniko鏡像,添加了整個busybox工具包進去,以支持其作為一個CI Job來運行。然后就可以把Gitlab往內(nèi)部容器服務(wù)平臺KUN對接了。代碼示例如下:
KUN+Gitlab:基于Kubernetes的CI/CD流程
KUN中CI/CD的整個流程如上圖所示。從圖中我們可以看到,CI部分是一個單元測試,預(yù)發(fā)布部署,集成測試,Debug,提交代碼的循環(huán)過程。在CI過程中預(yù)發(fā)布的部署是通過CD系統(tǒng)來實現(xiàn)的,CI其中一個步驟是生成部署文件,然后按照項目、資源集、版本等參數(shù)提交到CD后端系統(tǒng)。CD系統(tǒng)提供了頁面入口,當(dāng)部署文件推送到CD系統(tǒng)后,用戶可以在頁面查找對應(yīng)的部署文件。如果需要部署,在頁面點擊“部署”按鈕即可實現(xiàn)部署。
YAML編輯器
為方便用戶使用,我們?yōu)镵UN開發(fā)了專門的YAML編輯器,相比用普通的文本編輯器寫YAML,可以提供智能模板補全、搜索替換等能力。
上圖展示了一個使用案例,目前頁面編輯器支持的功能有:
Snippet:模版補全,用戶編輯文檔時,會提示相關(guān)模版,可選擇直接模版輸入
Hover:用戶鼠標(biāo)放置關(guān)鍵字,提示關(guān)鍵字含義和官方文檔鏈接
搜索替換:使用?+F/Ctrl+F打開頁面搜索支持頁面直接查詢
部署系統(tǒng)
為了在Gitlab CI Job中把服務(wù)部署到Kubernetes上,我們研發(fā)了部署系統(tǒng)。在CI Pipeline的最后一步,用戶生成一個YAML文件,定義需要部署到Kubernetes上的資源,然后使用部署系統(tǒng)提供的一個工具鏡像,該鏡像會調(diào)用部署系統(tǒng)的API,將YAML提交給部署系統(tǒng)。接下來部署系統(tǒng)將使用用戶的權(quán)限,調(diào)用Kubernetes API實現(xiàn)真正的部署。
目前部署系統(tǒng)主要包含兩部分功能:
1. 資源集管理:
資源集是用戶項目下一個或多個資源的集合,資源指 Kubernetes 的 object 的描述文件,一般為 YAML 文件;
資源集分為多個版本,不同的版本對應(yīng)資源的不同的描述文件;
用戶可以選擇某個版本,然后指定集群執(zhí)行部署。
2. 部署任務(wù)
用戶每次部署都會生成一個 job,就是部署任務(wù)
執(zhí)行部署后,用戶可在任務(wù)詳情頁直接查看部署任務(wù)日志。
當(dāng)完成上述所有工作,Gitlab能很好嵌入KUN平臺,運行在Kubernetes上的各模塊就可像齒輪一樣有序運轉(zhuǎn),從而獲得CI/CD上的良好效果。
前面提到的StepFlow項目,從一開始就實施了這樣一套 CI/CD,效率獲得了很大提升,每個編譯Job耗時約3分鐘,其他Job耗時在1分鐘以內(nèi)。
總結(jié)
CI/CD是提供高質(zhì)量互聯(lián)網(wǎng)服務(wù)必不可少的一環(huán)。Gitlab和Kubernetes都是非常優(yōu)秀的開源軟件,在此基礎(chǔ)上,我們根據(jù)自己的實際情況,結(jié)合兩者打造了一套高效的CI/CD平臺,努力提升研發(fā)效率,為用戶提供更優(yōu)質(zhì)的服務(wù)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。