Gitlab CI進階之共享CI庫
Gitlab CI進階之共享CI庫
一 背景
目前對于gitlab CI是在單獨的項目下創建.gitlab-ci.yaml文件來定義部署過程,對于共同的一些步驟比如構建部署等,在每一個gitlab CI文件中編寫,為了能夠使代碼在不同項目復用,將其存放在一個專門用于構建的gitlab CI倉庫,其他項目想要使用該stage可以引用公共的CI文件,后續僅需要維護公共的gitlab CI庫即可,但是需要公共CI庫將一些特征數據提取出來,由 CI 確保代碼風格一致,并執行單元測試和靜態檢查等。由于倉庫數量眾多,如何有效地組織和管理 CI 配置成了問題。經過長時間的探索和優化,我整理了一些經驗,希望對你有所幫助。公共庫需要較好的擴展性與兼容性。
二 基礎語法解析
在共享倉庫中將單個操作抽象為一個原子jobs,單獨寫在一個文件中,這樣可以在模版中引用這些原子jobs,根據不同的變量,tags的runner,及branch可以任意組合成需要的模版。對此主要用到兩個Gitlab CI中的關鍵字,include和extends。
include和extends是配合使用的,include為引用項目中的yaml文件,extends,為繼承文件中的具體jobs
2.1 Include
2.1.1 功能
利用include關鍵字能夠引用其他外部的yaml文件,這有助于將CI/CD配置分解為多個文件,并提高長配置文件的可讀性。
可以將通用的一些操作,抽象為單個原子jobs,編寫共享gitlab ci庫,在模版中incloud這些原子操作jobs,來組合成模版。
在單個的項目中,可以include共享庫中預定于好的模版,僅重寫項目中的一些變量即可。
2.1.2 方式
include加載其他外部yaml文件,文件名稱擴展必須為.yaml或.yml。
include支持加載方法包含以下四種:
2.1.3 示例
include:local:
include:本地包含與.gitlab來自同一存儲庫的文件-詞yml. 它是使用相對于根目錄(/)的完整路徑引用的。
您只能在配置文件所在的同一分支上使用Git當前跟蹤的文件。換句話說,當使用包括:本地,確保兩者都是。gitlab-詞yml本地文件在同一個分支上。
include: - local: '/templates/.gitlab-ci-template.yml'
或者簡短的方法:
include: '.gitlab-ci-production.yml'
include:file
要在同一個GitLab實例下包含來自另一個私有項目的文件,請使用包括:文件。使用相對于根目錄(/)的完整路徑引用此文件。例如:
include: - project: 'my-group/my-project' file: '/templates/.gitlab-ci-template.yml'
也可以指定ref.
include: - project: 'my-group/my-project' ref: master file: '/templates/.gitlab-ci-template.yml' - project: 'my-group/my-project' ref: v1.0.0 file: '/templates/.gitlab-ci-template.yml' - project: 'my-group/my-project' ref: 787123b47f14b552955ca2786bc9542ae66fee5b # Git SHA file: '/templates/.gitlab-ci-template.yml'
include:remote
Remote用于包含來自不同位置的文件,使用HTTP/HTTPS,通過使用完整的URL引用。遠程文件必須通過簡單的GET請求公開訪問,因為遠程URL中的身份驗證架構不受支持。例如:
include: - remote: 'https://gitlab.com/awesome-project/raw/master/.gitlab-ci-template.yml'
include:template
利用template可以加載gitlab上已經預置的一些模版,
https://gitlab.com/gitlab-org/gitlab/tree/master/lib/gitlab/ci/templates
# File sourced from GitLab's template collection include: - template: Auto-DevOps.gitlab-ci.yml
也可以引用多個模版
include: - template: Android-Fastlane.gitlab-ci.yml - template: Auto-DevOps.gitlab-ci.yml
2.2 Extends
2.2.1 功能
可以把一些公共屬性或者方法(主要是Script)也進行統一管理。將其抽離在單獨的jobs中,在具體的stages中進行繼承。
extends定義使用extends的作業將從中繼承的條目名。
它的使用相較于yaml anchors,更靈活和更易讀。
2.2.2 示例
.tests: script: rake test stage: test only: refs: - branches rspec: extends: .tests script: rake rspec only: variables: - $RSPEC
在上述的示例中,rspec 的job內嵌了.tests模版的job,gitlab將要執行深度合并,結果為:
rspec: script: rake rspec stage: test only: refs: - branches variables: - $RSPEC
三 實戰
3.1 項目結構
├── README.md ├── jobs # 基礎jobs │ ├── build.yaml # 構建jobs │ ├── check.yaml # k8s 部署檢測jobs │ ├── deploy.yaml # k8s 部署jobs │ ├── scan.yaml # k8s 代碼掃描jobs │ └── test.yaml # k8s dan單元測試jobs └── templates # pipelines 模版 ├── backend-k8s-private.yaml # 私有化后端部署模版 ├── backend-k8s-saas.yaml # saas后端部署模版 ├── frontend-k8s-private.yaml # 私有化前端部署模版 └── frontend-k8s-saas.yaml # saas前端部署模版
將原子操作抽象成單個jobs
在templates中定義后端私有化幾saas 的CI模版,在其中引用
3.2 CI jobs及模版
3.2.1 jobs
在jobs中定義原子操作,在此實例build
.build: script: - echo -e "\033[5;35;40m Building Dockerfile-based application ${REGISTRY}/${NAMESPACE}/${APP_NAME}:${APP_TAG}... \033[0m" - docker build -t "${REGISTRY}/${NAMESPACE}/${APP_NAME}:${APP_TAG}" . - echo "${REGISTRY_PWD}" | docker login ${REGISTRY} -u "${REGISTRY_USER}" --password-stdin - docker push "${REGISTRY}/${NAMESPACE}/${APP_NAME}:${APP_TAG}" - docker rmi ${REGISTRY}/${NAMESPACE}/${APP_NAME}:${APP_TAG} retry: max: 2 when: - always .upload: script: - cd /builds/${PROJECT_GROUP} - tar -zcf /tmp/${PROJECT_NAME}.tgz ${PROJECT_NAME} - coscmd config -a${ACCESS_ID} -s${ACCESS_KEY} -b${BUCKET} -r${REGION} - coscmd upload /tmp/${PROJECT_NAME}.tgz ${OBJECT_PATH}/ retry: max: 2 when: - always
我們可以其中定義build和upload多個操作,在其中不定義stage/branch/tags等。
3.2.2 templates
在templates中定義不同場景的CI模版,在其中可以自己根據項目是私有化部署或是saas 來include不同的jobs文件,并繼承其中具體jobs。
在自定義模版中,主要包含四個部分:
導入jobs的yaml文件
定義全局就stage中變量
定義模版運行CI的stage
實現具體stage,管理具體stages,繼承jobs。
在此義deploy來示例:
# 1.導入作業模版 include: - project: 'devops/gitlabci-templates' ref: master file: 'jobs/test.yaml' - project: 'devops/gitlabci-templates' ref: master file: 'jobs/scan.yaml' - project: 'devops/gitlabci-templates' ref: master file: 'jobs/build.yaml' - project: 'devops/gitlabci-templates' ref: master file: 'jobs/deploy.yaml' - project: 'devops/gitlabci-templates' ref: master file: 'jobs/check.yaml' # 2.定義全局及stage變量 variables: # 2.1 全局變量 # 2.1.1 全局基本不用修改變量 # 全局默認構建容器 IMAGE: docker:latest # 鏡像倉庫 REGISTRY: ccr.ccs.tencentyun.com # gitlab項目組 PROJECT_GROUP: devops # 部署配置 DEPLOY_DIR: deploy DEPLOY_NAME: deployment.yaml # 配置文件 CONFIG_DIR: cfg CONFIG_KEY: config.yaml # 部署不同環境的目錄 DEV_ENV_DIR: dev TEST_ENV_DIR: test PROD_ENV_DIR: prod # 配置namespace,該名稱空間在鏡像倉庫和k8s中名稱空間保持一致 DEV_NAMESPACE: anchnet-devops-dev TEST_NAMESPACE: anchnet-devops-test PROD_NAMESPACE: anchnet-devops-prod # 定義各階段使用鏡像 SCAN_IMAGE: sonarsource/sonar-scanner-cli:latest TEST_IMAGE: python:3.6 UPLOAD_IMAGE: ccr.ccs.tencentyun.com/anchnet-devops-common-test/python-coscmd:latest DEPLOY_IMAGE: kubesphere/kubectl:v1.0.0 # 定義上傳到cos配置 OBJECT_PATH: /smartant/saas BUCKET: go2tencent-1253329830 REGION: ap-shanghai # 2.1.2 全局需要根據項目自定義變量 # 主要用于對k8s資源操作 APP_NAME: smartant-backend # 項目名稱與代碼倉庫名稱保持一致,用于對目錄操作 PROJECT_NAME: smartant_backend # 2.2 各個stage變量 # 2.2.1 代碼掃描測試,test-scan變量 REQUIREMENTS: requirements/requirements.txt TEST_DIR: test TEST_PARAM: --include=../application.py,../logs.py,../libs/*.py,../views/*.py --omit="test_*.py" runtests.py # 2.2.2 構建和上傳源碼到cos,build-upload變量 # 2.2.3 部署到k8s,deploy變量 DEV_CONFIG_FILE: config_dev.yaml TEST_CONFIG_FILE: config_test.yaml PROD_CONFIG_FILE: config_prod.yaml # 部署在k8s中k8s的configmap名稱,一般為APP_NAME-cm CM_NAME: smartant-backend-cm # 2.2.4 檢查k8s deploy服務,check變量 before_script: - export APP_TAG="${CI_COMMIT_TAG:-${CI_COMMIT_SHA::8}}" # 3.配置運行stage stages: - test-scan - build-upload - deploy - check # 4.作業配置 image: ${IMAGE} # --------------test and scan stage---------------- # dev環境代碼掃描 scan-dev: image: ${SCAN_IMAGE} tags: - devops-dev-runner stage: test-scan extends: .scan only: - dev # dev環境單元測試 test-dev: image: ${TEST_IMAGE} tags: - devops-dev-runner stage: test-scan extends: .test only: - dev # --------------build upload stage--------------- # dev環境構建鏡像 build-dev: variables: NAMESPACE: ${DEV_NAMESPACE} tags: - devops-dev-runner stage: build-upload extends: .build only: - dev # test環境構建鏡像 build-test: variables: NAMESPACE: ${DEV_NAMESPACE} tags: - devops-test-runner stage: build-upload extends: .build only: - test # 正式環境構建鏡像 build-prod: variables: NAMESPACE: ${PROD_NAMESPACE} tags: - devops-prod-runner stage: build-upload extends: .build only: - master # 正式環境打包代碼上傳至cos upload-prod: image: ${UPLOAD_IMAGE} variables: NAMESPACE: ${PROD_NAMESPACE} tags: - devops-prod-runner stage: build-upload extends: .upload only: - master # --------------deploy stage--------------- # dev環境發布pages pages: tags: - devops-dev-runner stage: deploy dependencies: - test-dev extends: .pages only: - dev # dev 環境部署 deploy-dev: image: ${DEPLOY_IMAGE} variables: NAMESPACE: ${DEV_NAMESPACE} DEPLOY_ENV: ${DEV_ENV_DIR} CONFIG_FILE: ${DEV_CONFIG_FILE} tags: - devops-dev-runner stage: deploy extends: .deploy only: - dev # test環境部署 deploy-test: image: ${DEPLOY_IMAGE} variables: NAMESPACE: ${TEST_NAMESPACE} DEPLOY_ENV: ${DEV_ENV_DIR} CONFIG_FILE: ${DEV_CONFIG_FILE} tags: - devops-test-runner stage: deploy extends: .deploy only: - test # --------------check stage--------------- # dev環境k8s測試 check-dev: image: ${DEPLOY_IMAGE} variables: NAMESPACE: ${DEV_NAMESPACE} tags: - devops-dev-runner stage: check extends: .check only: - dev # test環境k8s測試 check-test: image: ${DEPLOY_IMAGE} variables: NAMESPACE: ${TEST_NAMESPACE} tags: - devops-test-runner stage: check extends: .check only: - test
在該模版中利用stage中的image/tags/runner/branch進行靈活組合,從而實現適應不同場景的CI。
至此共享CI模版庫就已經創建完成,需要在具體的項目中進行應用。
3.3 項目中引用
在具體的項目中引用非常簡單,只需要在代碼倉庫中編寫.gitlab-ci.yaml即可實現CI繼承,在此我們示例一個python的后端saas項目,繼承backend的saas模版。
include: - project: 'devops/gitlabci-templates' ref: master file: 'templates/backend-k8s-saas.yaml' variables: APP_NAME: smartant-api-linux # 項目名稱與代碼倉庫名稱保持一致,用于對目錄操作 PROJECT_NAME: smartant_api_linux # 2.2 各個stage變量 # 2.2.1 代碼掃描測試,test-scan變量 REQUIREMENTS: requirements/requirements.txt TEST_DIR: test TEST_PARAM: --include=../application.py,../logs.py,../libs/*.py,../views/*.py --omit="test_*.py" runtests.py # 2.2.2 構建和上傳源碼到cos,build-upload變量 # 2.2.3 部署到k8s,deploy變量 DEV_CONFIG_FILE: config_dev.yaml TEST_CONFIG_FILE: config_test.yaml PROD_CONFIG_FILE: config_prod.yaml # 部署在k8s中k8s的configmap名稱,一般為APP_NAME-cm CM_NAME: smartant-api-linux-cm
可以看到在具體的項目中集成gitlab CI引用模版庫非常的簡單,只用引用文件,并根據項目來定義變量即可完成集成。
四 注意事項
4.1 引用注意
引用的時候如果為同一個倉庫可以使用include:local進行同一個倉庫文件本地引用
對于在同一個gitlab服務器上的項目,可以使用project來引用,注意引用末尾沒有.git
4.2 共享庫注意事項
jobs中的原子操作不用定義stages,和branch,及運行的gitlab runner的tags
將公共變量提出來,將根據項目定義的變量也提出來,提高共享庫的可擴展性及靈活性
在具體項目中引用模版,重新定義變量,將覆蓋全局變量
五 反思
為了提升CI復用性和擴展性及規范CI流程,gitlab CI共享庫非常好的解決了此問題,但是要求編寫的具體jobs需要能無狀態化,需要具備很高的擴展性和維護行,對于前期的規劃和編寫jobs都提出了很高的要求。
六 參考鏈接
https://docs.gitlab.com/ee/ci/yaml/#include
https://docs.gitlab.com/ee/ci/yaml/includes.html
https://www.jianshu.com/p/cc07db6de12d
Git GitHub
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。