目錄
template 引用,減少代碼冗余,增強 CI/CD 構(gòu)建擴展性
問題 1:代碼冗余,低效實踐
問題 2:維護性難,工作量大
??local
? file
??remote
??template
收益 1:一處修改,多處生效
收益 2:高效構(gòu)建,簡單便捷
Component,打造 CI/CD Pipeline 單一可信源,簡化 CI/CD Pipeline 構(gòu)建
Component 倉庫的構(gòu)建
Component 的發(fā)布
Component 的引用
?Runner,CI/CD 高效構(gòu)建的利器
專有 + 共享,更多靈活選擇
動態(tài)擴縮容,提高資源使用率
合規(guī)流水線,助力流水線的安全合規(guī)使用
極狐GitLab CI 內(nèi)置于極狐GitLab 一體化平臺,提供開箱即用的 CI/CD 能力,也是受眾多用戶喜愛的 CI 工具之一。極狐GitLab CI 獨特的設(shè)計機制和企業(yè)級功能特性,能夠幫助企業(yè)在大規(guī)模落地 CI/CD 實踐時,提高 CI/CD 構(gòu)建效率、降低 Pipeline 維護成本,同時還能保持足夠的安全合規(guī)性。
本文從 CI/CD Pipeline 的構(gòu)建入手,講述極狐GitLab CI 三大方面的使用:
-
通過?
template
?、component
?來縮短 Pipeline 編寫時間、提高維護性; -
通過 Runner 的“花式”玩法來滿足不同場景下的 CI/CD Pipeline 運行需求,同時降低使用成本;
-
用合規(guī)框架來保障 CI/CD Pipeline 的合規(guī)使用。
template 引用,減少代碼冗余,增強 CI/CD 構(gòu)建擴展性
在企業(yè)內(nèi)部,一種很常見的場景就是:不同團隊或者不同產(chǎn)品線都有自己獨有的項目,每個項目都有對應(yīng)的 CI/CD 流水線,隨著項目的增多,流水線的數(shù)量也會不斷增加,一個企業(yè)內(nèi)部有可能存在數(shù)百甚至上千條流水線。
因為 CI/CD 流水線是軟件交付(從編碼到上線)的自動化展現(xiàn)形式,因此大部分流水線之間會有比較高的相似度,甚至有一些 stage 或者 job 是完全一樣的,比如在云原生交付場景下需要將應(yīng)用程序打包成鏡像,使用極狐GitLab CI 進行構(gòu)建的代碼如下:
build:
??image:?docker:latest
??stage:?build
??services:
????-?docker:20.10.7-dind
??script:
????-?docker?login?-u?"$CI_REGISTRY_USER"?-p?"$CI_REGISTRY_PASSWORD"?$CI_REGISTRY
????-?docker?build?-t?$CI_REGISTRY_IMAGE:1.0.0?.
????-?docker?push?$CI_REGISTRY_IMAGE:1.0.0
此外,如果都是 java 或者 golang 項目,其編譯或者測試的命令可能也是類似的。這種“重復(fù)”會隨著流水線的增加而增加,以下問題也會隨之而來:
問題 1:代碼冗余,低效實踐
如果每一條流水線都有一個 stage 或者 job 是相似的,大約有 10 行代碼,那么數(shù)百上千條流水線,其重復(fù)的代碼數(shù)量就是成千上萬條。這種代碼冗余在軟件研發(fā)領(lǐng)域本身就是一種低效實踐,如果不及時進行重構(gòu),隨著項目的演進,就會變成技術(shù)債。
問題 2:維護性難,工作量大
在對 CI/CD Pipeline 進行優(yōu)化的過程中,需要對流水線的部分內(nèi)容進行改造,比如需要升級?dind?的版本,抑或為了安全地構(gòu)建鏡像,將構(gòu)建方式從?dind?轉(zhuǎn)向?kaniko,那么對應(yīng)的代碼就要變成:
??services:
????-?docker:24.0.3-dind
及:
build:
??stage:?build
??image:
????name:?registry.jihulab.com/jh-xiaomage-devops/go-demo/kaniko:debug
????entrypoint:?[""]
??script:
????-?mkdir?-p?/kaniko/.docker
????-?echo?"{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf?"%s:%s"?"${CI_REGISTRY_USER}"?"${CI_REGISTRY_PASSWORD}"?|?base64?|?tr?-d?'\n')\"}}}"?>?/kaniko/.docker/config.json
????-?>-
??????/kaniko/executor
??????--context?"${CI_PROJECT_DIR}"
??????--dockerfile?"${CI_PROJECT_DIR}/Dockerfile"
??????--destination?"${CI_REGISTRY_IMAGE}:1.0.0"
這時就要對所有的流水線進行改造,數(shù)百條乃至上千條流水線的改造將是一個巨大的工作量,且大量代碼的“復(fù)制粘貼”過程,很難避免不出錯。
在軟件研發(fā)領(lǐng)域,解決冗余代碼的重要手段就是通過抽象 + 復(fù)用:也就是將相同(或者相似)的內(nèi)容抽象成模版,將模版“存儲”在某一個地方,其他地方只需要簡單引用模版即可。
對于 CI/CD Pipeline 來說也是一樣。極狐GitLab template 就是極狐GitLab CI 內(nèi)置的模版引擎功能,可以將抽象之后的模版存儲在項目倉庫中,其他項目通過?include
?語法就可完成 template 的引用。
極狐GitLab template 的用法比較靈活,首先需要將“制作”模版,也就是將“重復(fù)”的代碼提取出來,保存在一個 YAML 文件中。比如上面的鏡像構(gòu)建內(nèi)容,可以寫到一個 docker-image-build.gitlab-ci.yml 文件中。接下來使用?include
?進行引用。根據(jù)模版存儲的位置不同,include
?的引用有以下四種方式:
??local
模版位于當前項目中,使用?local
?關(guān)鍵字來引用。使用語法如下:
include:??
??-?local:?'/templates/docker-image-build.gitlab-ci.yml'
? file
模版和項目位于同一實例,但是不同倉庫,使用?file
?關(guān)鍵字來引用。使用語法如下:
include??
??-?project:?xiaomage/templates??
??-?ref:?main????
??file:?/templates/docker-image-build.gitlab-ci.yml
??remote
引用遠端倉庫中的流水線,通常是不同實例之間的引用。使用語法如下:
include:???
??-?remote:?'https://jihulab.com/xiaomage/teamplates/raw/main/docker-image-build.gitlab-ci.yml'
??template
極狐GitLab 內(nèi)置模版的引用。極狐GitLab 根據(jù)自身多年的經(jīng)驗,沉淀了眾多可以直接復(fù)用的模版,使用?template?語法即可使用。最典型的就是極狐GitLab DevSecOps 模版的引用。極狐GitLab DevSecOps 有密鑰掃描、依賴項掃描、SAST、DAST、容器鏡像掃描、模糊測試及許可證合規(guī)檢測功能,所有功能兩行代碼即可開啟。
因此,使用 template 能帶來以下收益:
收益 1:一處修改,多處生效
如果需要對流水線的內(nèi)容進行優(yōu)化,比如將?dind
?的版本進行升級,則只需要在模版中進行修改,其他引用的地方會隨之生效,真正實現(xiàn)“一處修改,多處生效”,這完全避免了“一處變更,處處修改”所帶來的重復(fù)勞動,而且流水線的冗余度也會降低。
收益 2:高效構(gòu)建,簡單便捷
template 可以實現(xiàn)多級嵌套,也就是模版里面引用模版。這樣做的好處就是,可以將模版的內(nèi)容細粒度化,可能是一個 stage,也可能是一個 job,比如容器鏡像構(gòu)建是一個模版,容器鏡像安全掃描又是一個模版。如果要對新項目構(gòu)建一條流水線,則可以直接使用多個 template 進行“搭積木”的方式就可快速完成流水線的構(gòu)建,然后根據(jù)項目的實際構(gòu)建流程來對參數(shù)或者流程做一些變更即可。
當然,為了高效的使用模版,還有一個問題需要注意,那就是模版中變量的覆蓋。
為了靈活使用模版,使用同一套模版,構(gòu)建出多個不同的實例。關(guān)鍵在于模版中變量的使用。比如,構(gòu)建容器鏡像時 tag 可能會隨著版本的不同而不同,此時可以將 tag 設(shè)置為一個變量:
variables:
??IMAGE_TAG:?1.0.0
build:
??image:?docker:latest
??stage:?build
??services:
????-?docker:20.10.7-dind
??script:
????-?docker?login?-u?"$CI_REGISTRY_USER"?-p?"$CI_REGISTRY_PASSWORD"?$CI_REGISTRY
????-?docker?build?-t?$CI_REGISTRY_IMAGE:$IMAGE_TAG?.
????-?docker?push?$CI_REGISTRY_IMAGE:$IMAGE_TAG
在引用的地方直接進行變量覆蓋即可:
variables:
??IMAGE_TAG:?"2.0.0"
include:?
??-?remote:?'https://jihulab.com/xiaomage/teamplates/raw/main/docker-image-build.gitlab-ci.yml'
覆蓋之后,鏡像 tag 的值從默認的?1.0.0
?就變成了?2.0.0
?,這樣就能滿足不同場景的訴求,兼具高效和靈活。
Component,打造 CI/CD Pipeline 單一可信源,簡化 CI/CD Pipeline 構(gòu)建
template 的使用大大降低了用戶構(gòu)建 CI/CD Pipeline 的難度,通過引用 + 參數(shù)覆蓋的模式就能夠快速構(gòu)建出對應(yīng)場景的 Pipeline,但是目前并沒有一個 template 的單一可信源,來方便用戶找到自己想用的 Pipeline,同時也無法讓愿意貢獻的用戶將可用的 template 貢獻出來,來共同打造 Pipeline 的繁榮生態(tài)。
為此,極狐GitLab 推出了 CI/CD Component 這一特色功能,其目的就是打造 CI/CD Pipeline 的單一可信源,通過將不同流水線(或者單獨的作業(yè))變成不同的 component,然后發(fā)布到 component 倉庫,其他用戶可以在此倉庫中通過搜索來找到自己想要的 component,在構(gòu)建流水線的時候直接引用即可,多個組件的引用就能夠快速搭建起整個完整的流水線,這極大的改變了用戶使用 CI/CD 的體驗。
更為重要的是用戶可以將自己認為已經(jīng)得到實踐的一些優(yōu)秀流水線(或者單獨的作業(yè))以 component 的形式發(fā)布到 component 倉庫,通過不同用戶的不斷貢獻、迭代來共同打造繁榮的 CI/CD Pipeline 生態(tài),最終構(gòu)建企業(yè)內(nèi)部 CI/CD Pipeline 單一可信源,提高 CI/CD Pipeline 構(gòu)建效率的同時,安全性也得到了很大的提升。
注意:CI/CD Component 目前處于實驗階段。
CI/CD Component 示意圖
因此,componnt 的核心是:component 倉庫的構(gòu)建、 component 的發(fā)布及 component 的引用。
Component 倉庫的構(gòu)建
通過創(chuàng)建一個極狐GitLab 倉庫,并且將其標記為 component 倉庫來構(gòu)建一個初始的 component 倉庫。該倉庫至少需要兩個文件?README.md
?和?template.yml
:
-
README.md
?可以對倉庫中包含的 component 進行描述,方便用戶學習使用; -
template.yml
?就是 component 的具體內(nèi)容。
可以通過不同的目錄結(jié)構(gòu)(分支、tag 等)來實現(xiàn)不同 component 的區(qū)分,比如:
├──?template.yml
├──?README.md
├──?.gitlab-ci.yml
├──?forntend/
│???└──?template.yml
└──?backend/
????└──?template.yml
上述目錄表示,在此 component 倉庫中有三個可用的 component:
-
根目錄下?
template.yml
?表示的 component; -
frontend 目錄下?
template.yml
?表示的 component; -
backend 目錄下?
template.yml
?表示的 component。
可以通過項目 → 設(shè)置 → 通用 → 可見性、項目功能、通用 → 開啟 CI/CD 目錄資源來將一個倉庫標記為 component 倉庫。
Component 的發(fā)布
如果需要發(fā)布一個 component,則需要將對應(yīng)的內(nèi)容寫入到某個?template.yml
?內(nèi),然后將該文件推送至 component 倉庫即可。以上述鏡像構(gòu)建為例,將下述內(nèi)容寫入到某個?template.yml
?中:
spec:??
??inputs:????
????stage:??????
??????default:?test????
????image:??????
??????default:?docker:latest????
????tags:??????
??????default:?tags????
????image_tag:??????
??????default:?1.0.0
??????
component-job-build-image:??
??image:?$[[?inputs.image?]]??
??stage:?$[[?inputs.stage?]]??
??tags:????
????-?$[[?inputs.tags?]]??
??script:?????
????-?docker?login?-u?"$REGISTRY_USER"?-p?"$REGISTRY_PWD"?REGISTRY_URL????
????-?docker?build?-t?dllhb/cicd-component:$[[?inputs.image_tag?]]?.????
????-?docker?push?dllhb/cicd-component:$[[?inputs.image_tag?]]
然后推送至?jh.instance.url/username/component-project
?目錄下。參數(shù)說明:
-
jh.instance.url
:極狐GitLab 私有化部署實例地址; -
username
:極狐GitLab 用戶名; -
component-project
:component 倉庫名稱。
上述 component 位于倉庫根目錄下,有一個?component-job-build-image
?job。
Component 的引用
如果想要在其他 Pipeline 中引用上述發(fā)布的 component,在?.gitlab-ci.yml
?中用如下語法引用:
include:??
??-?component:?jh.instance.url/username/component-project@main????
??inputs:??????
????stage:?build??????
????image:?docker:latest??????
????tags:?cicd??????
????image_tag:?2.0.0
????
stages:?[build]
需要注意的地方有:
-
在?
include
?中完整寫入 component(也就是?tempate.yml
?存在的路徑)的路徑,通過 @ 來明確引用的是 component 的哪個版本(可以用分支、commit hash、tag 等表示); -
在?
inputs
?中寫入具體的參數(shù)。
觸發(fā) CI/CD Pipeline,可以看到?component-job-build-image?job
執(zhí)行成功:
同樣地,如果想要將?dind
?的構(gòu)建方式換為?kaniko
,則無需替換上述 component 的內(nèi)容,只需要再次發(fā)布一個以 kaniko 為主題的 component 即可。
這有很多種做法來實現(xiàn),比如將?template.yml
?放在 component 倉庫的另外一個目錄(非根目錄下,因為根目錄下已經(jīng)有?dind
?的 component)、分支、tag 下來表示這是不同的 component;比如針對上述的 component,main 分支表示?dind
?component,那么可以新建一個?kaniko
?分支來存放 kaniko 對應(yīng)的 component,最后在?.gitlab-ci.yml
?中引用的時候指明分支即可:
include:??
??-?component:?jh-jhma.gitlab.cn/cicd-component/cicd-component-demo@kaniko???
??inputs:??????
????stage:?build??????
????image:?gcr.io/kaniko-project/executor:debug??????
????tags:?cicd??????
????image_tag:?2.0.0
????
stages:?[build]
當然,鏡像也要由原來的?
dind
?改為?kinako
,這只需要修改?inputs
?的參數(shù)即可。
運行 CI/CD Pipeline 可以得到相同的結(jié)果。
component 的引入拉開了極狐GitLab CI/CD 使用新范式的序幕。這種通過用戶貢獻來打造 CI/CD Pipeline 單一可信源的做法,對于用戶構(gòu)建完整的 Pipeline 有著巨大幫助,不僅加速了 CI/CD Pipeline 的構(gòu)建,還大大降低了用戶學習繁雜 YAML 語法的成本。
以上所演示的代碼均存儲在極狐GitLab 私有化部署實例上,地址為?https://jh-jhma.gitlab.cn/cicd-component。
?Runner,CI/CD 高效構(gòu)建的利器
Runner 是極狐GitLab CI 的一個重要組件,它能夠幫助運行 CI/CD 流水線中所定義的 Job。當研發(fā)人員提交代碼變更后,極狐GitLab 就會“通知” Runner 去按照?.gitlab-ci.yml
?定義的流水線步驟完成變更代碼的構(gòu)建、測試、部署等,此過程中 Runner 會根據(jù)所選擇的 executor(比如針對 PowerShell 的 shell、針對容器的 docker 等)來針對不同環(huán)境進行 Job 的運行。關(guān)于 executor 的選擇可以參考極狐GitLab 執(zhí)行器官網(wǎng)。
Runner 像是一個“agent”,接受“server”端(極狐GitLab 實例)的請求,因此為了滿足不同場景的需求,Runner 要能夠滿足在不同 OS、不同 CPU 架構(gòu)上以不同的安裝方式來運行。
專有 + 共享,更多靈活選擇
Runner 分為專有和共享兩大類:
-
專有:指 Runner 只給指定的項目用,通常是使用項目的一些信息( Runner register token)來將 Runner 注冊到對應(yīng)的項目下面;
-
共享:指 Runner 是針對整個極狐GitLab 實例的,意味著整個實例下面的所有項目都可以使用這些 Runner,至于如何用、誰先用、誰后用是由極狐GitLab 的內(nèi)部調(diào)度機制來實現(xiàn)的。
專有 Runner 的最大優(yōu)勢在于:
-
節(jié)省時間:專有 Runner 只給對應(yīng)的項目運行 CI/CD 流水線,因此不用排隊去等待共享 Runner 來執(zhí)行 CI/CD 流水線,且隨著項目、流水線的增加,排隊將耗費大量時間;
-
自主可控:專有 Runner 是用戶自己安裝在自己可控的服務(wù)器上,在使用過程中如果要對流水線過程進行 Debug 或者對 Runner 配置進行修改,甚至想獲取某些運行過程中的數(shù)據(jù),則可以直接登陸到對應(yīng)的 Runner 中進行操作。
專有 Runner 的配置信息
共享 Runner 的好處也是顯而易見的:用戶無需了解 Runner 的過多信息,也無需自己安裝運維等。是一種比較省事的方式。
因此,用戶可以根據(jù)自身的需求,來選擇不同方式的 Runner 來完成相應(yīng)的 CI/CD 流水線運行。
動態(tài)擴縮容,提高資源使用率
Runner 可以和云資源動態(tài)伸縮的特性緊密綁定,實現(xiàn) Runner 的動態(tài)伸縮:當有 CI/CD 流水線需要運行的時候,Runner 使用一些資源(CPU、內(nèi)存等)來執(zhí)行所有 Job,當 CI/CD 流水線運行結(jié)束(成功或失?。┖螅瑢?yīng)的資源被釋放,對環(huán)境進行恢復(fù)。
比如說,可以使用容器來運行 Runner,最典型的就是使用 Kubernetes 來運行極狐GitLab Runner。
當執(zhí)行 CI/CD 時,Kubernetes 會動態(tài)創(chuàng)建一個 pod,pod 會根據(jù)?.gitlab-ci.yml
?文件中描述的 stage 以及對應(yīng)的鏡像來生成相應(yīng)的容器(所有容器在一個 pod 內(nèi),共享 pod 內(nèi)部資源),流水線的運行都在容器內(nèi)部,當流水線運行結(jié)束,pod 會刪除,運行過程中的數(shù)據(jù)、所需的資源會被釋放。
此外,還可以使用云廠商提供的 serverless 產(chǎn)品實現(xiàn) Runner 的動態(tài)擴所容,提高資源的使用率。
合規(guī)流水線,助力流水線的安全合規(guī)使用
流水線使用過程中還會遇到一個場景:某一個流程是需要所有項目的流水線都必須運行的,比如在鏡像構(gòu)建結(jié)束必須進行鏡像安全掃描,如果有安全漏洞就需要終止流水線的運行。這種情況下的解決方案往往是針對所有項目在流水線中使用?include
?加入容器鏡像掃描環(huán)節(jié),但是隨著項目數(shù)量的增多(成百乃至上千),這意味著巨大的重復(fù)工作量,而且無法確保操作的精準度。
而正確的解決方案就是:合規(guī)流水線。
合規(guī)流水線是極狐GitLab CI/CD 流水線內(nèi)置的一個安全功能,主要是確保群組內(nèi)的所有項目都能夠運行指定的合規(guī)作業(yè)。通過在群組級別配置好合規(guī)框架,選擇好每個項目都必須運行的合規(guī)流水線作業(yè),則此群組下面的所有項目都會運行此合規(guī)作業(yè),甚至后續(xù)在該群組下新創(chuàng)建的項目也會默認執(zhí)行此合規(guī)作業(yè)。
合規(guī)流水線的使用,首先需要在群組級別進行合規(guī)框架的配置。在群組 → 設(shè)置 → 通用 → 合規(guī)框架中,選擇新建合規(guī)框架,然后填入合規(guī)框架名稱、描述、合規(guī)流水線配置(也就是合規(guī)流水線所存儲的位置),最后選擇一個背景顏色即可。
如將此合規(guī)框架設(shè)置為群組的默認合規(guī)框架,則此群組下面新建的項目都會默認使用此合規(guī)框架,默認運行此合規(guī)流水線,而且在項目頁面會有合規(guī)框架的標簽生成。
接著需要將合規(guī)流水線寫入到此群組下面的一個項目(比如 Compliance-Pipeline)中。以容器鏡像構(gòu)建和掃描流水線為例,在?.gitlab-ci.yml
?文件中寫入如下內(nèi)容:
include:?
??-?remote:?'https://jihulab.com/xiaomage/teamplates/raw/main/docker-image-build.gitlab-ci.yml'
??-?template:?Security/Container-Scanning.gitlab-ci.yml
后續(xù)所有的新建項目都會執(zhí)行容器鏡像構(gòu)建和容器鏡像掃描這兩個作業(yè),而不是項目自帶的流水線。
如果想要項目自帶的流水線也被執(zhí)行,只需要將合規(guī)流水線的內(nèi)容和項目自帶流水線的內(nèi)容進行合并即可。比如自帶流水線需要使用 cosgin 對打包的容器鏡像進行簽名和驗證,防止鏡像被篡改:
stages:
??-?singature
??-?verfication
image-singature:
??stage:?singature
??tags:
????-?cosign
??image:?
????name:?dllhb/cosign:1.0.0
????entrypoint:?[""]
??before_script:
????-?mkdir?~/.docker
????-?cat?"$DOCKER_CRED_FILE"?>?~/.docker/config.json
????-?cat?"$COSIGN_KEY"?>?/tmp/cosign.key
????-?export?COSIGN_PASSWORD="$COSIGN_PASSWORD"
??script:
????-?cosign?sign?--key?/tmp/cosign.key?$CI_REGISTRY_IMAGE:1.0.0
image-verfication:
??stage:?verfication
??tags:
????-?cosign
??image:?
????name:?dllhb/cosign:1.0.0
????entrypoint:?[""]
??before_script:
????-?cat?"$COSIGN_PUB"?>?/tmp/cosign.pub
????-?export?COSIGN_PASSWORD="$COSIGN_PASSWORD"
??script:
????-?cosign?verify?--key?/tmp/cosign.pub?$CI_REGISTRY_IMAGE:1.0.0
需要將上述流水線引入到合規(guī)流水線當中:
include:
??-?project:?'Compliance-Pipeline-Group/regular-pipeline'
????file:?'.gitlab-ci.yml'
最終該群組下的其他項目的流水線都會執(zhí)行容器鏡像的打包、掃描、簽名及驗證這四個步驟。文章來源:http://www.zghlxwxcb.cn/news/detail-659255.html
因此合規(guī)框架的選擇,是為了標記某些項目必須滿足某些合規(guī)要求或者需要額外的監(jiān)督,然后通過執(zhí)行合規(guī)流水線來完成合規(guī)工作的完成。文章來源地址http://www.zghlxwxcb.cn/news/detail-659255.html
到了這里,關(guān)于極狐GitLab 企業(yè)級 CI/CD 規(guī)?;涞貙嵺`指南(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!