極狐gitlab ci/cd pipeline 效率優化


極狐gitlab ci/cd pipeline 效率優化

與任何持續集成和持續部署平台一樣,速度對於開發人員效率至關重要。

官方文檔參考:Pipeline efficiency | GitLab

1. 優化 runner

極狐gitlab 提供共享 runner 給所有項目 ci/cd 任務使用。當項目較多時,ci/cd 任務也會增多,這時候運行 pipeline 效率會降低,這是有可以兩種優化方式:

1.1 使用 tag 標記 runner

在 runner 編輯頁面設置 Tags,並且不勾選 Run untagged jobs,這時候此 runner 只運行使用 tag 選擇器的 job,這樣優化 runner 占用率

示例:

stages:
  - test

job1:
  stage: test
  script: 
    - echo 'job1'
  tag:
    - "docker"

1.2 為項目注冊專用 runner

點擊具體項目,然后在settings -> CI/CD - Expand 中查看項目 runner 注冊用的地址和 token,然后再按照官方文檔注冊 runner:Registering runners | GitLab 即可。

注冊完成后,這個 runner 只會運行當前項目的 job。

1.3 使用 k8s 運行 runner

將 runner 安裝到 Kubernetes 集群中來,並且使用 Kubernetes executor,這樣子運行 job 時可以動態的申請集群資源,可以有效避免資源不足的情況。

安裝方式參考:使用 K3s 來安裝和運行極狐GitLab Runner_嗶哩嗶哩_bilibili 或者 GitLab Runner Helm Chart | GitLab

2. 使用 cache

在運行項目編譯時,可能會安裝項目依賴,如果每次都從網絡安裝,會浪費很多時間。這時候可以使用 cache 功能提供緩存,減少依賴安裝時間。

前提 runner 開啟 cache 功能:Advanced configuration | GitLab

2.1 pip cache

示例:

image: python:3.9.7

stages:
  - test

variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
  
cache:
  paths:
    - .cache/pip/
  # 已項目 id 區分 cache,如果不區分,就是全局 cache
  key: $CI_PROJECT_ID

job1:
  stage: test
  script:
    - pip install ansible==2.9.2

or

image: python:3.9.7

stages:
  - test

cache:
  paths:
    - pip-cache
  # 已項目 id 區分 cache,如果不區分,就是全局 cache
  key: $CI_PROJECT_ID

before_script:
  - export PIP_CACHE_DIR="pip-cache"
  - mkdir -p pip-cache

job1:
  stage: test
  script:
    - pip install ansible==2.9.2

2.2 nodejs cache

示例:

variables:
  NPM_CONFIG_CACHE: npm_cache
  NPM_CONFIG_REGISTRY: https://registry.npm.taobao.org

default:
  cache:
    paths:
      - ${NPM_CONFIG_CACHE}

build:
  stage: build
  image: node:14-alpine
  script:
    - node -v
    - npm -v
    - npm ci
    - npm run build
  artifacts:
    name: "build-package"
    paths:
      - dist
    expire_in: 1 day

其他語言類似,參考:Caching in GitLab CI/CD | GitLab

3. 安裝依賴使用國內源

由於國內網絡的原因,如果使用默認源的話,安裝依賴可能會很慢甚至失敗,這時候可以設置國內或者代理解決。

nodejs

npm install --registry=https://registry.npm.taobao.org

or

yarn config set registry 'https://registry.npm.taobao.org'

python

pip install --trusted-host mirrors.aliyun.com -i https://mirrors.aliyun.com/pypi/simple -r requirements.txt

ruby

gem sources --remove https://rubygems.org/
gem sources -a https://gems.ruby-china.com
gem sources –l

golang

go env -w GOPROXY=https://goproxy.cn,direct

設置GOPRIVATE來跳過私有庫,比如常用的GitlabGithub,中間使用逗號分隔:

go env -w GOPRIVATE=*.gitlab.com,*.github.com

4. docker 優化

4.1 docker 鏡像體積優化

盡量優化減小 docker 鏡像大小

4.1.1 使用Alpine Linux

Alpine Linux是一個基於BusyBox和Musl Libc的Linux發行版,其最大的優勢就是小。一個純的基礎Alpine Docker鏡像在壓縮后僅有2.67MB。並且不少 Docker 官方鏡像都有 Alpine 版本,比如:python:3.9.12-alpine3.15ruby:2.7.5-alpine3.15

4.1.2 安裝最少依賴

如果不是必須,不要安裝 vi,wget,curl,ping 等工具。

4.1.3 合並 RUN 指令到一行

Dockerfile 中盡量合並多條指令

...
RUN echo 1 \
  && echo 2
...

4.1.4 多階段構建

在Docker 17.05版本以后,新引入了multi-stage builds這一概念,這將會極大地減小鏡像大小。

簡單來說,multi-stage builds支持我們將Docker鏡像的編譯分成多個“階段”。比如常見的軟件編譯的情況,我們可以將編譯階段單獨提出來,軟件編譯完成后直接將二進制文件拷貝到一個新的基礎鏡像中,這樣做最大的好處就是,第二個鏡像不再包含任何編譯階段使用的中間依賴,干干凈凈明明白白。

具體使用方法:Dockerfile 多階段構建 - leffss - 博客園 (cnblogs.com)

更多dockerfile最佳實踐參考:Best practices for writing Dockerfiles | Docker Documentation

4.2 使用自建 docker hub 鏡像倉庫

默認情況下,docker 使用 Docker Hub 的鏡像,網絡傳輸較慢。可以搭建本地 hub 倉庫:安裝 harbor v2.3.4 - leffss - 博客園 (cnblogs.com) ,加速鏡像的 pull 與 push。

pipeline 中使用本地倉庫:

stages:
  - build

variables:
  PROJECTNAME: "test"
  DOCKERHUB: "hub.leffss.com"
  DOCKERHUBPROJECT: "library"

before_script:
  - docker login ${DOCKERHUB} -u "${DOCKERHUBUSER}" -p "${DOCKERHUBPASS}"

after_script:
  - docker logout ${DOCKERHUB}

job1:
  stage: build
  script:
    - docker build --cache-from ${DOCKERHUB}/${DOCKERHUBPROJECT}/${PROJECTNAME}:latest -t ${DOCKERHUB}/${DOCKERHUBPROJECT}/${PROJECTNAME}:${CI_COMMIT_TAG} -t ${DOCKERHUB}/${DOCKERHUBPROJECT}/${PROJECTNAME}:latest .
    - docker images
    - docker push ${DOCKERHUB}/${DOCKERHUBPROJECT}/${PROJECTNAME}:${CI_COMMIT_TAG}
    - docker push ${DOCKERHUB}/${DOCKERHUBPROJECT}/${PROJECTNAME}:latest

在有了本地 hub 倉庫的情況下,還可以根據 4.1 章節的原則自行打包一些項目編譯需要用到的基礎鏡像,把項目需要用到的基礎依賴包或者工具提前打包進去,這樣又可以減少 pipeline 安裝依賴的時間。

5. 使用 rules 減少不必要作業運行

使用 rules 規則跳過某些不必要 job。比如如果只是前端代碼改變了,則跳過測試 job。

示例:

stages:
  - build
  - test

build job:
  stage: build
  script:
    - echo 'build job'

test job:
  stage: test
  script: 
    - echo 'test job'
  rules:
    - changes:
        - backend/*
  • 當 backend 中有變化時運行 test job
  • 也可以使用類似的 only: changes 實現

更多 rules 規則參考:Keyword reference for the .gitlab-ci.yml file | GitLab

6. 使用 needs 改變多階段執行順序

pipeline 中可以定義階段 stages,如果全局未定義stages, 則按順序運行 build,test,deploy,job 如果未設置 stage,默認是 test 階段。

默認情況下:同一階段的作業並行運行,不同階段按順序執行。可以使用 needs 參數改變多階段執行順序。

示例:

stages:
  - build
  - test
  - deploy

build fontend:
  stage: build
  script:
    - echo 'build fontend job'

build backend:
  stage: build
  script:
    - echo 'build backend job'

test fontend:
  stage: test
  script:
    - echo 'test fontend job'
  needs: ["build fontend"]

test backend:
  stage: test
  script:
    - echo 'test backend job'
  needs: ["build backend"]
    
deploy fontend:
  stage: deploy
  script:
    - echo 'deploy fontend job'
  needs: ["test fontend"]

deploy backend:
  stage: deploy
  script:
    - echo 'deploy backend job'
  needs: ["test backend"]

使用 needs 參數后:對於前端任務,build fontend 完成后會立即執行下一個階段的 test fontend,不管 build backend 是否完成。后端的 build backend 任務一樣類似。

web 界面中還可以查看 needs 依賴關系。

7. 設置 Job artifacts 合理過期時間

pipeline 使用 artifacts 生成制品時,按需設置過期時間,盡量不要過長。

...
pdf:
  stage: build
  script: xelatex mycv.tex
  artifacts:
    paths:
      - mycv.pdf
    expire_in: 1 day
...

如果未設置 expire_in 參數,則為全局設置:admin -> settings -> ci/cd


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM