流水线

流水线是按照定义顺序执行的一组任务,用以实现 CI/CD 工作流。流水线定义了任务的执行流程,包括它们的依赖关系、参数和工作空间,从而使您能够创建复杂的自动化工作流。

为什么需要流水线

传统 CI/CD 挑战

传统的 CI/CD 系统在创建复杂工作流时常常面临挑战:

  • 复杂性管理:在不同阶段之间管理依赖关系的困难
  • 可重用性:在项目之间有限的工作流组件重用能力
  • 灵活性:在不同需求中调整工作流的限制
  • 可见性:对工作流执行和进度的有限洞察

Tekton 的解决方案

Tekton 流水线通过以下方式解决这些挑战:

  • 声明性定义:流水线作为 Kubernetes 自定义资源进行定义
  • 任务协调:流水线管理任务之间的执行顺序和依赖关系
  • 数据共享:流水线通过工作空间和结果促进任务之间的数据共享
  • 可重用性:流水线组件可以在项目之间共享和重用
  • 灵活性:流水线支持条件执行和动态参数

优势

  • 模块化:将复杂工作流分解为可重用的任务
  • 依赖管理:定义任务之间明确的依赖关系
  • 并行性:独立任务可以并发执行
  • 条件执行:根据条件运行任务
  • 结果共享:通过结果在任务之间传递数据
  • 工作空间共享:通过工作空间在任务之间共享文件和数据
  • 可重用性:创建可重用的工作流模板

场景

流水线在多种场景中都很有用,包括:

  • CI/CD 工作流:构建、测试和部署应用
  • 多环境部署:部署到开发、暂存和生产环境
  • 复杂构建过程:管理构建步骤之间的依赖关系
  • 发布管理:协调多个组件之间的发布活动
  • 基础设施自动化:协调基础设施的供给和配置

流水线执行模型

当通过 PipelineRun 执行流水线时:

  1. Tekton 分析流水线以确定任务的执行顺序
  2. 没有依赖关系的任务立即开始执行
  3. 有依赖关系的任务则需等待其依赖关系完成
  4. 可以并行运行的任务同时执行
  5. 当所有任务完成或当一个关键任务失败时,流水线完成

关键概念

任务依赖关系

流水线中的任务可以以两种方式相互依赖:

  1. 顺序依赖:使用 runAfter 字段指定一个任务应在另一个任务之后运行
  2. 数据依赖:当一个任务使用另一个任务的结果时

示例:

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: order-tasks
spec:
  tasks:
    - name: task1
      taskRef:
        name: task1
    - name: task2
      taskRef:
        name: task2
      runAfter:
        - task1
      params:
        - name: param1
          value: "$(tasks.task1.results.result)"
    - name: task3
      taskRef:
        name: task3
      params:
        - name: param1
          value: "$(tasks.task2.results.result)"

参数

参数允许您在执行过程中向流水线传递值。它们可用于定制流水线内任务的行为。

用例

  • 配置构建选项
  • 指定部署目标
  • 设置版本号
  • 控制功能标志

原则

参数是:

  • 在流水线规格中声明
  • 在创建 PipelineRun 时传递
  • 可用于流水线内的任务
  • 可以具有默认值

配置示例

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: build-and-deploy
spec:
  params:
    - name: image-name
      type: string
      description: 要构建的镜像名称
    - name: environment
      type: string
      description: 部署的环境
      default: "development"
  tasks:
    - name: build
      taskRef:
        name: build-image
      params:
        - name: image
          value: "$(params.image-name)"

工作空间

工作空间允许流水线中的任务共享数据。它们在流水线层面声明,然后映射到各个任务。

用例

  • 在任务之间共享源代码
  • 在任务之间传递构建工件
  • 共享配置文件
  • 在流水线执行之间维护状态

原则

流水线中的工作空间是:

  • 在流水线规格中声明
  • 映射到任务工作空间
  • 在创建 PipelineRun 时绑定到实际存储
  • 可以在多个任务之间共享

配置示例

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: build-test-deploy
spec:
  workspaces:
    - name: source-code
      description: 包含源代码的工作空间
  tasks:
    - name: fetch-source
      taskRef:
        name: git-clone
      workspaces:
        - name: output
          workspace: source-code
    - name: build
      taskRef:
        name: build-app
      workspaces:
        - name: source
          workspace: source-code
      runAfter:
        - fetch-source

结果

结果允许任务生成可被流水线中其他任务消费的输出值。

用例

  • 传递构建版本信息
  • 共享生成的工件路径
  • 传达测试结果
  • 传递部署 URL

原则

流水线中的结果是:

  • 由任务生成
  • 使用 $(tasks.taskName.results.resultName) 语法引用
  • 用作后续任务的输入
  • 可以包含在流水线结果中

配置示例

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: build-and-deploy
spec:
  tasks:
    - name: generate-version
      taskRef:
        name: semver
      results:
        - name: version
    - name: build
      taskRef:
        name: build-image
      params:
        - name: version
          value: "$(tasks.generate-version.results.version)"
      runAfter:
        - generate-version
  results:
    - name: build-version
      value: "$(tasks.generate-version.results.version)"

最终任务

最终任务在流水线中所有其他任务完成后执行,无论成功或失败。它们适用于清理操作或通知。

用例

  • 清理资源
  • 发送通知
  • 归档日志
  • 生成报告

原则

最终任务:

  • 在所有其他任务完成后运行
  • 无论流水线成功或失败都会运行
  • 不能依赖其他任务
  • 不能被其他任务所依赖

配置示例

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: build-test-deploy
spec:
  tasks:
    - name: build
      taskRef:
        name: build-app
    - name: test
      taskRef:
        name: run-tests
      runAfter:
        - build
  finally:
    - name: cleanup
      taskRef:
        name: cleanup-resources
    - name: notify
      taskRef:
        name: send-notification

条件执行

任务可以使用 when 字段进行条件执行,这允许您根据参数或结果指定条件。

用例

  • 仅在特定分支上进行部署
  • 根据代码变更运行测试
  • 根据用户输入执行任务
  • 根据先前的结果跳过任务

原则

条件执行:

  • 使用 when 字段定义
  • 可以引用参数和结果
  • 支持各种运算符(in, notin)
  • 可以组合多个条件

配置示例

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: build-test-deploy
spec:
  params:
    - name: environment
      type: string
  tasks:
    - name: build
      taskRef:
        name: build-app
    - name: deploy-to-production
      taskRef:
        name: deploy
      runAfter:
        - build
      when:
        - input: "$(params.environment)"
          operator: in
          values: ["production"]

约束和限制

  • 流水线不能存在任务之间的循环依赖
  • 流水线在执行期间不能修改自身定义
  • 任务结果必须在被其他任务消费之前生成
  • 任务结果的大小有限制(通常为几千字节)
  • 流水线在处理动态任务创建方面能力有限

参考文献