流水线架构

流水线是极狐GitLab 中 CI/CD 的基本构建模块。本页记录了一些与它们相关的重要概念。

构建流水线的主要方法有三种,每种方法都有自己的优势。如果需要,可以混合和匹配这些方法:

  • 基本:适用于所有配置都集中在一个易于找到的地方的简单项目。
  • needs 关键字的流水线:适用于需要高效执行的大型复杂项目。
  • 父子流水线:适用于具有大量独立定义组件的 monorepos 和项目。
  • 多项目流水线:适用于有内部依赖的大型产品,诸如使用微服务架构的产品。

    比如,您可能从三个不同的极狐GitLab 项目中部署您的 Web 应用程序。有了多项目流水线,您可以在每个项目中触发流水线,而且每个流水线都有自己的构建、测试和部署流程。您可以在一个地方查看连接的流水线,包括所有的跨项目依赖。

有关下面使用的任何关键字的更多详细信息,请查看我们的 CI YAML 参考以获取详细信息。

基本流水线

这是极狐GitLab 中最简单的流水线。它同时运行构建阶段的所有内容,一旦所有这些都完成,它会以相同的方式运行测试阶段的所有内容,依此类推。 这不是最有效的,如果您有很多步骤,它会变得非常复杂,但更容易维护:

graph LR subgraph deploy stage deploy --> deploy_a deploy --> deploy_b end subgraph test stage test --> test_a test --> test_b end subgraph build stage 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

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 关键字的流水线

如果效率对您很重要,并且您希望一切都尽可能快地运行,则可以使用有向无环图(DAG)。 使用 needs 关键字 定义作业之间的依赖关系。当系统知道您的作业之间的关系时,它可以尽可能快地运行所有内容,甚至在可能的情况下跳到后续阶段。

在下面的示例中,如果 build_atest_abuild_btest_b 快得多,即使 build_b 仍在运行,系统也会启动 deploy_a

graph LR subgraph Pipeline using DAG build_a --> test_a --> deploy_a build_b --> test_b --> deploy_b end

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

stages:
  - build
  - test
  - deploy

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 的导入会增加配置的复杂性,并可能导致无意中重复作业的命名空间冲突。
  • 流水线 UX 有太多的作业和阶段需要处理。

此外,有时流水线的行为需要更加动态。选择启动(或不启动)子流水线的能力是一项强大的能力,尤其是在动态生成 YAML 的情况下。

Parent pipeline graph expanded

在上面的基本流水线有向无环图流水线示例中,有两个可以独立构建的包。 这些情况非常适合使用父子流水线。 它将配置分成多个文件,使事情变得更简单。 您可以将父子流水线与以下结合:

graph LR subgraph Parent pipeline trigger_a -.-> build_a trigger_b -.-> build_b subgraph child pipeline B build_b --> test_b --> deploy_b end subgraph child pipeline 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 配置,位于 /a/.gitlab-ci.yml 中,使用 DAG needs 关键字:

stages:
  - build
  - test
  - deploy

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 配置,位于 /b/.gitlab-ci.yml 中,使用 DAG needs 关键字:

stages:
  - build
  - test
  - deploy

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

也可以将作业设置为在触发子流水线之前或之后运行,例如,如果您有通用的设置步骤或最后的统一部署。