写点什么

极狐 GitLab include 语法减少 CI/CD Pipeline 代码冗余,提升构建效率

作者:极狐GitLab
  • 2022-12-29
    江西
  • 本文字数:4330 字

    阅读完需:约 14 分钟

极狐GitLab include 语法减少 CI/CD Pipeline 代码冗余,提升构建效率

项目经理:我们有个 Java 的新项目要开始了,需要你帮忙设置调试一下 CI/CD Pipeline

DevOps 工程师:好的,没问题

ONE WEEK LATER...

项目经理:新项目的 CI/CD Pipeline 咋样了啊,我看研发还是手动人肉编译部署呢,严重影响了效率。CI/CD Pipeline 遇到什么问题了吗?

DevOps 工程师:已经写了 50% 了,正在写其他的,然后调试,再一周能好。

项目经理:WHT,一个 CI/CD Pipeline 为啥这么久?而且前面有类似的 Java 项目,有可用的 CI/CD Pipeline,直接抽象成 template,然后用 include 语法在新项目中引入,再根据新项目的特性做微调即可。分分钟能搞定的啊。

DevOps 工程师:什么 template?什么 include?还能这么玩?

项目经理:我的乖乖……


封装和复用是软件编程设计中常用的特性,能够在很大程度上提高代码整体的可读性、可维护性。对于 CI/CD Pipeline 来讲也可以用封装和复用,来为新项目快速构建起一套合适的 CI/CD Pipeline,节约时间的同时,方便实现 Pipeline as Code,提升团队的端到端交付能力。

极狐 GitLab include 语法


极狐 GitLab CI/CD 是通过 YAML 语法来编写并存储到 YAML 文件中,可以将能够抽象出来的 CI/CD Pipeline(诸如单元测试、镜像构建、安全扫描等)代码存放到一个 YAML 文件,然后在其他项目的 .gitlab-ci.yml 中直接用 include 语法引入这个 YAML 文件即可。相当于用 include 一行代码实现了多行代码的功能,实现了 CI/CD Pipeline 的复用。这种做法有以下好处:


  • 减少代码冗余。通过复用减少相同代码的复制使用,能有效减少代码冗余。

  • 减小变更范围。如果有配置需要修改时,只要在 include 的文件中(upstream)进行修改,就可以将变更传递到使用此文件(downstream)的地方。一个变更,多处生效。

  • 提高可维护性。将一个配置文件拆分成多个配置文件,避免形成“巨型”配置文件,修改时候无从下手,维护起来耗时耗力。


极狐 GitLab include 的用法有以下四种,以引用不同来源的 YAML 文件:


local


引用同一项目中的流水线配置文件:


include:  - local: '/templates/.include-template.yml'
复制代码


file


引入同一极狐 GitLab 实例中的流水线配置文件:


include  - project: xiaomage/templates  - ref: main    file: docker-image-build-tamplates.yml
复制代码


上述写法引入了 xiaomage/templates 项目下的 docker-image-build-tamplates.yml 配置文件。


remote


引用位于其他远端仓库中的流水线配置文件:


include:   - remote: 'https://jihulab.com/xiaomage/teamplates/raw/main/docker-image-build-tamplates.yml'
复制代码


template


极狐 GitLab 内置了很多开箱即用的 template,可以直接引入使用。所有的模版存储在 lib/gitlab/ci/templates 下面。也可以在项目中添加 .gitlab-ci.yml 文件的时候选择:



上图所示,引入了容器镜像扫描的功能。下面的 Demo 中会演示扫描效果。可以用同样的方法引入极狐 GitLab DevSecOps 中的其他安全测试手段。

极狐 GitLab include 中的 Override


用 include 引入的流水线配置是“共性”的内容,而实际使用的过程中是“个性”的,因此这时候需要用 Override 的方式,修改引入文件中的一些配置和参数。


比如,如果将镜像构建并推送至极狐 GitLab 镜像仓库的流程定义为如下的流水线配置文件:


variables:  IMAGE_TAG: 1.0.0  build:  image: docker:latest  stage: build  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
复制代码


项目的 .gitlab-ci.yml 文件内容如下:


variables:  IMAGE_TAG: 2.0.0  include:   - remote: 'https://jihulab.com/xiaomage/teamplates/raw/main/docker-image-build-tamplates.yml'
复制代码


则最终构建出来的镜像的 tag 是 2.0.0。因为 .gitlab-ci.yml 中 variables::IMAGE_TAG 的值,覆盖了引入的流水线配置中的 variables::IMAGE_TAG。这种方式成为了“合并”(merging)。

极狐 GitLab include 的嵌套使用


include 语法可以实现配置文件的嵌套使用,比如在项目的 .gitlab-ci.yml 内容如下:


include:  - local: /.gitlab-ci/another-config.yml
复制代码


而 /.gitlab-ci/another-config.yml 内部又使用了 include 引入了另外一个配置文件:


include:  - local: /.gitlab-ci/config-defaults.yml
复制代码


最终 /.gitlab-ci/config-defaults.yml 的内容为:


default:  after_script:    - echo "Job complete."
复制代码


上面的写法实现了 include 的 2 级嵌套。


关于极狐 GitLab include 的其他用法,可以参考极狐GitLab 官网文档


极狐 GitLab include 实战


以 istio 中的 bookinfo 为例来演示 include 的强大功能。 bookinfo 中有 6 个服务:details、productpage、ratings、reviews、mysql、mongodb,每个都包含一个 Dockerfile:


├── details│   ├── Dockerfile├── mongodb│   ├── Dockerfile├── mysql│   ├── Dockerfile├── productpage│   ├── Dockerfile├── ratings│   ├── Dockerfile└── reviews    ├── reviews-wlpcfg    │   ├── Dockerfile
复制代码


如果完整构建这几个镜像,就需要执行 6 次镜像构建命令,在极狐 GitLab CI/CD 中,构建镜像的 Job 如下:



build: image: docker:latest stage: build 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
复制代码


因此,可以重复写 6 次来完成整个镜像的构建,比如:


stages:  - build  ratings_image_build:  image: docker:latest  stage: build  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
productpage_image_build: image: docker:latest stage: build 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 details_image_build: image: docker:latest stage: build 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
其他三个重复,不再赘述。
复制代码


上述写法除了冗余、重复并没有太多价值。可以将镜像构建的代码写入一个 YAML 文件,并且存储到极狐 GitLab(比如 SaaS 上),存储路径为:https://jihulab.com/xiaomage/teamplates/raw/main/docker-image-build-tamplates.yml。然后在项目的 .gitlab-ci.yml 文件中使用 include 引入此文件即可:


variables:  IMAGE_TAG: "1.0.0"
stages: - build
include: - remote: 'https://jihulab.com/xiaomage/teamplates/raw/main/docker-image-build-tamplates.yml'
.image_build: image: docker:latest stage: build
ratings_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/ratings" IMAGE_NAME: "ratings"
productpage_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/productpage" IMAGE_NAME: "productpage"
details_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/details" IMAGE_NAME: "details"其他三个重复,不再赘述。.
复制代码


而且使用了 variables 来完成,对于 include 引入的 template 文件中的 variables 进行了覆盖,这样只需要修改一次即可完成 6 个镜像的 tag 修改。触发 CI/CD Pipeline 构建,可以查看构建结果:



再进一步,加一个镜像扫描。极狐 GitLab 本身支持对于容器镜像的扫描,详情可以查看过往文章云原生时代,保证容器镜像安全分几步?


只需以下两行代码即可开启容器镜像扫描:


include:  - template: Security/Container-Scanning.gitlab-ci.yml
复制代码

Security/Container-Scanning.gitlab-ci.yml 是极狐 GitLab 提供的众多开箱即用的 template 中的一个。


因此将镜像构建与扫描都用 include 引入:


variables:  CS_ANALYZER_IMAGE: registry.gitlab.cn/security-products/container-scanning/trivy:4  SECURE_ANALYZERS_PREFIX: "registry.gitlab.cn/security-products"  IMAGE_TAG: "1.0.0"
stages: - build - test
include: - remote: 'https://jihulab.com/xiaomage/teamplates/raw/main/docker-image-build-tamplates.yml' - template: Container-Scanning.gitlab-ci.yml

.image_build: image: docker:latest stage: build
ratings_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/ratings" IMAGE_NAME: "ratings"
productpage_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/productpage" IMAGE_NAME: "productpage"
details_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/details" IMAGE_NAME: "details"其他三个重复,不再赘述。

container_scanning: image: "$CS_ANALYZER_IMAGE" stage: test variables: DOCKER_IMAGE: "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" GIT_STRATEGY: fetch DOCKER_USER: "$CI_REGISTRY_USER" DOCKER_PASSWORD: "$CI_REGISTRY_PASSWORD"

container_scanning_ratings: extends: container_scanning variables: IMAGE_NAME: "ratings"

container_scanning_productpage: extends: container_scanning variables: IMAGE_NAME: "productpage"
container_scanning_details: extends: container_scanning variables: IMAGE_NAME: "details"其他三个重复,不再赘述。
复制代码


可以查看构建结果:



在极狐 GitLab 镜像仓库查看推送的镜像:



在极狐 GitLab 安全仪表盘查看镜像扫描结果:



极狐 GitLab CI/CD include 语法能够很好的解决 CI/CD Pipeline 代码的封装和复用,可以将共性的流程抽象出来封装成 template,存储在极狐 GitLab 上。


当有新项目需要设置 CI/CD Pipeline,只需要用 include 语法引入,再根据新项目的实际情况做一些变动,即可完成新项目的 CI/CD Pipeline 设置,能够节省大量时间,而且便于维护。

发布于: 刚刚阅读数: 3
用户头像

极狐GitLab

关注

开源开放,人人贡献 2021-05-19 加入

开放式一体化DevOps平台,助力行业高速协同增长!

评论

发布
暂无评论
极狐GitLab include 语法减少 CI/CD Pipeline 代码冗余,提升构建效率_DevOps_极狐GitLab_InfoQ写作社区