Help us learn about your current experience with the documentation. Take the survey.

流水线架构

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

流水线是 GitLab 中 CI/CD 的基本构建块。本文档记录了与流水线相关的一些重要概念。

您可以使用不同的方法来构建流水线,每种方法都有其自身的优势。如果需要,这些方法可以组合使用:

  • 基础流水线:适用于所有配置都在一个地方的简单项目。

  • 使用 needs 关键字的流水线:适用于需要高效执行的大型复杂项目。

  • 父子流水线:适用于 monorepo 和包含大量独立定义组件的项目。

    概述请参见父子流水线功能演示

  • 多项目流水线:适用于需要跨项目依赖关系的大型产品,例如具有微服务架构的产品。

    例如,您可能从三个不同的 GitLab 项目部署您的 Web 应用程序。使用多项目流水线,您可以在每个项目中触发一个流水线,每个流水线都有自己的构建、测试和部署过程。您可以在一个地方可视化连接的流水线,包括所有跨项目依赖关系。

    概述请参见多项目流水线演示

基础流水线

基础流水线是 GitLab 中最简单的流水线。它在构建阶段并行运行所有任务,一旦所有任务完成,它就会以同样的方式运行测试和后续阶段的所有任务。这不是最有效的方法,如果您有很多步骤,可能会变得相当复杂,但它更容易维护:

%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: 基础流水线
accDescr: 展示一个通过构建、测试和部署阶段顺序运行的流水线。

  subgraph 部署阶段
    deploy --> deploy_a
    deploy --> deploy_b
  end

  subgraph 测试阶段
    test --> test_a
    test --> test_b
  end

  subgraph 构建阶段
    build --> build_a
    build --> build_b
  end

  build_a -.-> test
  build_b -.-> test
  test_a -.-> deploy
  test_b -.-> deploy

与上图匹配的基础 /.gitlab-ci.yml 流水线配置示例:

stages:
  - build
  - test
  - deploy

default:
  image: alpine

build_a:
  stage: build
  script:
    - echo "This job builds something."

build_b:
  stage: build
  script:
    - echo "This job builds something else."

test_a:
  stage: test
  script:
    - echo "This job tests something. It will only run when all jobs in the"
    - echo "build stage are complete."

test_b:
  stage: test
  script:
    - echo "This job tests something else. It will only run when all jobs in the"
    - echo "build stage are complete too. It will start at about the same time as test_a."

deploy_a:
  stage: deploy
  script:
    - echo "This job deploys something. It will only run when all jobs in the"
    - echo "test stage complete."
  environment: production

deploy_b:
  stage: deploy
  script:
    - echo "This job deploys something else. It will only run when all jobs in the"
    - echo "test stage complete. It will start at about the same time as deploy_a."
  environment: production

使用 needs 关键字的流水线

如果效率很重要,并且希望一切尽可能快地运行,您可以使用 needs 关键字 来定义作业之间的依赖关系。当 GitLab 知道作业之间的依赖关系时,作业可以尽可能快地运行,甚至在同一阶段的其他作业之前就开始。

在下面的示例中,如果 build_atest_abuild_btest_b 快得多,GitLab 会在 build_b 仍在运行时就启动 deploy_a

%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: 使用 needs 的流水线
accDescr: 展示两个作业如何在不等待早期阶段完成的情况下启动

  subgraph 使用 needs 的流水线
    build_a --> test_a --> deploy_a
    build_b --> test_b --> deploy_b
  end

与上图匹配的 /.gitlab-ci.yml 配置示例:

stages:
  - build
  - test
  - deploy

default:
  image: alpine

build_a:
  stage: build
  script:
    - echo "This job builds something quickly."

build_b:
  stage: build
  script:
    - echo "This job builds something else slowly."

test_a:
  stage: test
  needs: [build_a]
  script:
    - echo "This test job will start as soon as build_a finishes."
    - echo "It will not wait for build_b, or other jobs in the build stage, to finish."

test_b:
  stage: test
  needs: [build_b]
  script:
    - echo "This test job will start as soon as build_b finishes."
    - echo "It will not wait for other jobs in the build stage to finish."

deploy_a:
  stage: deploy
  needs: [test_a]
  script:
    - echo "Since build_a and test_a run quickly, this deploy job can run much earlier."
    - echo "It does not need to wait for build_b or test_b."
  environment: production

deploy_b:
  stage: deploy
  needs: [test_b]
  script:
    - echo "Since build_b and test_b run slowly, this deploy job will run much later."
  environment: production

父子流水线

随着流水线变得越来越复杂,一些相关的问题开始出现:

  • 阶段化的结构要求一个阶段的所有步骤必须完成,下一个阶段的第一项作业才能开始,这会导致等待,从而减慢速度。
  • 单个全局流水线的配置变得难以管理。
  • 使用 include 的导入会增加配置的复杂性,并可能导致命名空间冲突,导致作业被意外重复。
  • 流水线的用户体验需要处理过多的作业和阶段。

此外,有时流水线的行为需要更加动态。选择启动子流水线(或不启动)的能力是一种强大的功能,特别是当 YAML 是动态生成时。

在之前的基础流水线needs流水线示例中,有两个可以独立构建的包。这些情况非常适合使用父子流水线。它将配置分离到多个文件中,使事情变得更简单。您可以将父子流水线与以下功能结合使用:

%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: 父子流水线
accDescr: 展示父流水线可以触发独立的子流水线

  subgraph 父流水线
    trigger_a -.-> build_a
  trigger_b -.-> build_b
    subgraph 子流水线 B
    build_b --> test_b --> deploy_b
    end

    subgraph 子流水线 A
      build_a --> test_a --> deploy_a
    end
  end

与上图匹配的父流水线 /.gitlab-ci.yml 配置示例:

stages:
  - triggers

trigger_a:
  stage: triggers
  trigger:
    include: a/.gitlab-ci.yml
  rules:
    - changes:
        - a/*

trigger_b:
  stage: triggers
  trigger:
    include: b/.gitlab-ci.yml
  rules:
    - changes:
        - b/*

位于 /a/.gitlab-ci.yml 的子流水线 a 配置示例,使用 needs 关键字:

stages:
  - build
  - test
  - deploy

default:
  image: alpine

build_a:
  stage: build
  script:
    - echo "This job builds something."

test_a:
  stage: test
  needs: [build_a]
  script:
    - echo "This job tests something."

deploy_a:
  stage: deploy
  needs: [test_a]
  script:
    - echo "This job deploys something."
  environment: production

位于 /b/.gitlab-ci.yml 的子流水线 b 配置示例,使用 needs 关键字:

stages:
  - build
  - test
  - deploy

default:
  image: alpine

build_b:
  stage: build
  script:
    - echo "This job builds something else."

test_b:
  stage: test
  needs: [build_b]
  script:
    - echo "This job tests something else."

deploy_b:
  stage: deploy
  needs: [test_b]
  script:
    - echo "This job deploys something else."
  environment: production

在 GitLab 中,可以将作业设置为在触发子流水线之前或之后运行,从而允许通用的设置步骤或统一的部署。