• gitlab pipeline optimize 效率优化


    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来跳过私有库,比如常用的GitlabGitee,中间使用逗号分隔:

    go env -w GOPRIVATE=*.gitlab.com,*.gitee.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 依赖关系:

    image-20220328162940889

    image-20220328163013955

    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

  • 相关阅读:
    小Z的袜子
    C#操作XML
    C#中接口的实现方法
    C#邮箱批量注册
    C# 委托的使用
    C# socket
    在C#.net中如何操作XML
    C#接口的基础知识
    C#判断网页中是否含有某字符串
    C#多线程处理多个队列的数据
  • 原文地址:https://www.cnblogs.com/leffss/p/16105837.html
Copyright © 2020-2023  润新知