流水线
流水线是按照定义顺序执行的一组任务,用以实现 CI/CD 工作流。流水线定义了任务的执行流程,包括它们的依赖关系、参数和工作空间,从而使您能够创建复杂的自动化工作流。
为什么需要流水线
传统 CI/CD 挑战
传统的 CI/CD 系统在创建复杂工作流时常常面临挑战:
- 复杂性管理:在不同阶段之间管理依赖关系的困难
- 可重用性:在项目之间有限的工作流组件重用能力
- 灵活性:在不同需求中调整工作流的限制
- 可见性:对工作流执行和进度的有限洞察
Tekton 的解决方案
Tekton 流水线通过以下方式解决这些挑战:
- 声明性定义:流水线作为 Kubernetes 自定义资源进行定义
- 任务协调:流水线管理任务之间的执行顺序和依赖关系
- 数据共享:流水线通过工作空间和结果促进任务之间的数据共享
- 可重用性:流水线组件可以在项目之间共享和重用
- 灵活性:流水线支持条件执行和动态参数
优势
- 模块化:将复杂工作流分解为可重用的任务
- 依赖管理:定义任务之间明确的依赖关系
- 并行性:独立任务可以并发执行
- 条件执行:根据条件运行任务
- 结果共享:通过结果在任务之间传递数据
- 工作空间共享:通过工作空间在任务之间共享文件和数据
- 可重用性:创建可重用的工作流模板
场景
流水线在多种场景中都很有用,包括:
- CI/CD 工作流:构建、测试和部署应用
- 多环境部署:部署到开发、暂存和生产环境
- 复杂构建过程:管理构建步骤之间的依赖关系
- 发布管理:协调多个组件之间的发布活动
- 基础设施自动化:协调基础设施的供给和配置
流水线执行模型
当通过 PipelineRun 执行流水线时:
- Tekton 分析流水线以确定任务的执行顺序
- 没有依赖关系的任务立即开始执行
- 有依赖关系的任务则需等待其依赖关系完成
- 可以并行运行的任务同时执行
- 当所有任务完成或当一个关键任务失败时,流水线完成
关键概念
任务依赖关系
流水线中的任务可以以两种方式相互依赖:
- 顺序依赖:使用
runAfter
字段指定一个任务应在另一个任务之后运行
- 数据依赖:当一个任务使用另一个任务的结果时
示例:
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"]
约束和限制
- 流水线不能存在任务之间的循环依赖
- 流水线在执行期间不能修改自身定义
- 任务结果必须在被其他任务消费之前生成
- 任务结果的大小有限制(通常为几千字节)
- 流水线在处理动态任务创建方面能力有限
参考文献