PipelineRuns
PipelineRun 是一个 Kubernetes 自定义资源,用于实例化 Pipeline 以执行。PipelineRuns 负责执行 Pipeline 中定义的 Tasks 并管理其生命周期,提供了一种运行端到端 CI/CD 工作流的方式。
目录
为什么需要 PipelineRuns
CI/CD 工作流的挑战
在 CI/CD 系统中,工作流执行面临以下几个挑战:
- 工作流编排:需要按特定顺序协调多个任务
- 资源协调:需要管理多个任务之间的资源
- 数据共享:需要在工作流中的任务之间共享数据
- 执行跟踪:需要跟踪整个工作流的进度
- 错误处理:需要在任务和工作流级别处理失败
- 审计能力:需要维护所有工作流执行的记录
Tekton 的解决方案
Tekton PipelineRuns 通过以下方式解决这些挑战:
- 工作流实例:每个 PipelineRun 代表 Pipeline 的一次具体执行,带有特定输入
- 编排:PipelineRuns 根据依赖关系管理 Tasks 的执行顺序
- 资源绑定:PipelineRuns 将实际资源绑定到 Pipeline 的需求
- 状态跟踪:PipelineRuns 跟踪每个 Task 的执行状态
- 结果传播:PipelineRuns 支持任务间结果共享
- Kubernetes 集成:PipelineRuns 利用 Kubernetes 进行资源管理和调度
优势
- 隔离性:每个 PipelineRun 独立执行,支持同一 Pipeline 的并行执行
- 可追溯性:PipelineRuns 提供详细的执行历史和日志
- 灵活性:PipelineRuns 可以覆盖 Pipeline 参数和工作空间绑定
- 复用性:同一 Pipeline 可通过不同 PipelineRuns 使用不同输入执行
- 集成性:PipelineRuns 可通过 Kubernetes API 被多种系统触发
- 可观测性:可通过 Kubernetes 工具监控 PipelineRun 状态和日志
适用场景
PipelineRuns 适用于多种场景,包括:
- 应用 CI/CD:构建、测试和部署应用
- 基础设施即代码:基础设施的配置和管理
- 发布管理:协调复杂的发布流程
- 定时工作流:按计划运行工作流
- 事件驱动工作流:响应外部事件触发工作流
约束与限制
- PipelineRuns 在单个 Kubernetes 集群内执行
- 启动后,PipelineRun 参数不可修改
- PipelineRuns 对失败任务的重试能力有限
- PipelineRun 执行时间受 Kubernetes Pod 超时限制
- PipelineRuns 一旦开始执行,无法暂停(“finally”任务除外)
原则
PipelineRun 执行模型
创建 PipelineRun 时:
- Tekton 验证 PipelineRun 规范
- 为 Pipeline 中的每个 Task 创建 TaskRuns
- TaskRuns 根据依赖关系执行
- 收集任务结果供后续任务使用
- 每个 TaskRun 完成时更新 PipelineRun 状态
- 所有其他任务完成或失败后执行 “finally” 任务
- 所有 TaskRuns 完成后,PipelineRun 结束
PipelineRun 状态
PipelineRun 状态提供执行的详细信息:
- 总体状态(运行中、成功、失败等)
- 开始和完成时间
- 各个 TaskRun 状态
- 任务结果
- 失败原因(如适用)
- 用于访问日志的 TaskRun 名称
配置示例
基础 PipelineRun 示例
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-app-run
spec:
pipelineRef:
name: build-deploy-app
params:
- name: image-name
value: my-registry/my-app:latest
- name: deployment-name
value: my-app
workspaces:
- name: source
persistentVolumeClaim:
claimName: app-source-pvc
带嵌入式 Pipeline 定义的 PipelineRun
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: simple-pipeline-run
spec:
pipelineSpec:
params:
- name: message
type: string
tasks:
- name: print-message
taskSpec:
params:
- name: message
type: string
steps:
- name: print
image: ubuntu
script: |
echo "$(params.message)"
params:
- name: message
value: "$(params.message)"
params:
- name: message
value: "Hello, Tekton Pipeline!"
重要参数
Timeout
Timeout 用于设置 PipelineRun 执行的最大时长。
使用场景
- 防止长时间运行的 Pipeline 无限制占用资源
- 确保 CI/CD 工作流在合理时间内完成
- 处理挂起或死锁的任务
- 为 Pipeline 执行的不同阶段设置不同超时限制
原则
Timeout:
- 在 PipelineRun 规范中通过
timeouts
字段指定(旧的 timeout
字段已弃用)
- 可应用于整个 PipelineRun 或特定部分(tasks、finally)
- 从第一个任务开始到最后一个任务完成计时
- 超时则导致 PipelineRun 失败
- 必须满足约束:
timeouts.pipeline >= timeouts.tasks + timeouts.finally
- 重要:若任一子字段设置为 "0",则该部分无超时。若要将
timeouts.tasks
或 timeouts.finally
设为 "0",必须同时将 timeouts.pipeline
设为 "0"
Timeout 字段
- pipeline:整个 PipelineRun 的最大时长
- tasks:所有非 finally 任务的最大时长
- finally:所有 finally 任务的最大时长
配置示例
示例 1:标准超时配置
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-with-timeout
spec:
pipelineRef:
name: build-deploy-app
timeouts:
pipeline: "1h" # 整个 Pipeline 超时
tasks: "45m" # 所有常规任务超时
finally: "15m" # finally 任务超时
params:
- name: image-name
value: my-registry/my-app:latest
示例 2:tasks 和 finally 无超时(pipeline 超时需为 0)
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-no-timeout
spec:
pipelineRef:
name: build-deploy-app
timeouts:
pipeline: "0" # 无整体超时
tasks: "0" # 常规任务无超时
finally: "0" # finally 任务无超时
params:
- name: image-name
value: my-registry/my-app:latest
注意:
- 示例 1 满足约束
pipeline (1h) >= tasks (45m) + finally (15m)
- 示例 2 展示了如何通过将所有值设为 "0" 来禁用超时
ServiceAccount
ServiceAccount 用于指定 Kubernetes ServiceAccount 以进行身份认证。
使用场景
- 提供访问私有容器镜像仓库的凭据
- 云服务提供商认证
- 授权访问 Kubernetes 资源
- 提供 Git 操作凭据
原则
ServiceAccount:
- 可在 PipelineRun 级别指定,应用于所有任务
- 可通过 taskRunSpecs 映射到特定任务
- 通过 Kubernetes secret 提供凭据
- 支持安全访问外部资源
配置示例
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-with-service-account
spec:
pipelineRef:
name: build-deploy-app
taskRunTemplate:
serviceAccountName: pipeline-service-account
params:
- name: image-name
value: my-registry/my-app:latest
Pod Template
Pod Template 用于指定执行每个 Task 的 Pod 配置模板。
使用场景
- 为特定硬件需求设置节点选择器
- 配置专用节点的容忍度
- 指定安全上下文以增强安全性
- 在 Pod 级别设置资源限制和请求
- 配置亲和规则以优化资源利用
- 为 Pod 添加自定义注解或标签
原则
Pod Templates:
- 应用于 PipelineRun 中所有任务,除非被 taskRunSpecs 覆盖
- 遵循 Kubernetes Pod 模板规范
- 可被 Task 特定配置覆盖
- 保证 PipelineRun 中所有任务的 Pod 配置一致
- 支持所有标准 Kubernetes Pod 模板字段
配置示例
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-with-pod-template
spec:
pipelineRef:
name: build-deploy-app
taskRunTemplate:
serviceAccountName: default
# PipelineRun 中所有任务的全局 Pod 模板
podTemplate:
nodeSelector:
disktype: ssd
environment: production
tolerations:
- key: "dedicated"
operator: "Equal"
value: "pipeline"
effect: "NoSchedule"
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
params:
- name: image-name
value: my-registry/my-app:latest
TaskRunSpecs
TaskRunSpecs 允许在 PipelineRun 内自定义单个 TaskRun 配置,通过指定 PipelineTaskRunSpec
列表,可为每个任务设置 ServiceAccountName
、Pod 模板和 Metadata
。
使用场景
- 为不同任务应用不同的 ServiceAccount,实现细粒度访问控制
- 为不同任务设置特定 Pod 模板,满足不同资源或安全需求
- 配置任务特定的元数据,便于组织和跟踪
- 覆盖全局 PipelineRun 配置以适应特定任务
- 为 Pipeline 不同阶段应用不同的计算资源或节点选择器
原则
TaskRunSpecs:
- 覆盖整个 Pipeline 设置的 Pod 模板
- 支持对任务执行环境的细粒度控制
- 满足特定安全、资源或调度需求
- 支持 Pipeline 不同阶段的差异化配置
- 支持所有标准 Kubernetes Pod 模板规范
- 可与全局 PipelineRun 配置结合使用
配置字段
每个 TaskRunSpec 支持以下字段:
- pipelineTaskName:应用配置的 Pipeline 任务名称
- serviceAccountName:该任务使用的 ServiceAccount
- podTemplate:该任务特定的 Pod 模板配置
- metadata:TaskRun 的元数据配置
配置示例
示例 1:基础 TaskRunSpecs,包含 ServiceAccount 和 Pod 模板
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-with-taskrunspecs
spec:
pipelineRef:
name: build-deploy-app
taskRunSpecs:
- pipelineTaskName: build
serviceAccountName: build-service-account
podTemplate:
nodeSelector:
disktype: ssd
environment: build
tolerations:
- key: "dedicated"
operator: "Equal"
value: "build"
- pipelineTaskName: deploy
serviceAccountName: deploy-service-account
podTemplate:
nodeSelector:
disktype: ssd
environment: production
tolerations:
- key: "dedicated"
operator: "Equal"
value: "deploy"
effect: "NoSchedule"
params:
- name: image-name
value: my-registry/my-app:latest
示例 2:带高级 Pod 配置的 TaskRunSpecs
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: advanced-taskrunspecs
spec:
pipelineRef:
name: multi-stage-pipeline
taskRunSpecs:
- pipelineTaskName: build
serviceAccountName: build-sa
podTemplate:
nodeSelector:
gpu: available
disktype: nvme
securityContext:
runAsNonRoot: true
runAsUser: 1000
- pipelineTaskName: test
serviceAccountName: test-sa
podTemplate:
nodeSelector:
environment: testing
tolerations:
- key: "test-only"
operator: "Equal"
value: "true"
effect: "NoSchedule"
- pipelineTaskName: deploy
serviceAccountName: deploy-sa
podTemplate:
nodeSelector:
environment: production
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
示例 3:带元数据配置的 TaskRunSpecs
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: taskrunspecs-with-metadata
spec:
pipelineRef:
name: build-test-deploy
taskRunSpecs:
- pipelineTaskName: build
serviceAccountName: build-sa
metadata:
labels:
stage: build
environment: development
annotations:
tekton.dev/description: "Build stage with optimized resources"
podTemplate:
nodeSelector:
disktype: ssd
- pipelineTaskName: deploy
serviceAccountName: deploy-sa
metadata:
labels:
stage: deploy
environment: production
annotations:
tekton.dev/description: "Production deployment stage"
podTemplate:
nodeSelector:
environment: production
示例 4:TaskRunSpecs 覆盖全局 Pod 模板
TaskRunSpecs 可以覆盖 PipelineRun 级别设置的全局 Pod 模板:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: override-global-template
spec:
pipelineRef:
name: build-deploy-app
taskRunTemplate:
serviceAccountName: default
# 所有任务的全局 Pod 模板
podTemplate:
nodeSelector:
disktype: ssd
tolerations:
- key: "general"
operator: "Equal"
value: "pipeline"
effect: "NoSchedule"
# 任务特定覆盖
taskRunSpecs:
- pipelineTaskName: build
podTemplate:
nodeSelector:
disktype: nvme
gpu: available
tolerations:
- key: "build-only"
operator: "Equal"
value: "true"
effect: "NoSchedule"
- pipelineTaskName: deploy
podTemplate:
nodeSelector:
environment: production
tolerations:
- key: "deploy-only"
operator: "Equal"
value: "true"
effect: "NoSchedule"
params:
- name: image-name
value: my-registry/my-app:latest
Workspaces
Workspaces 允许在 Pipeline 中的任务之间共享数据。
使用场景
- 在构建和测试任务之间共享源代码
- 将构建产物传递给部署任务
- 跨多个任务共享配置文件
- 在 Pipeline 执行间持久化数据
原则
Workspaces:
- 在 Pipeline 中声明,在 PipelineRun 中绑定
- 可由多种卷类型支持(PVC、ConfigMap、Secret 等)
- 实现数据共享而无需直接依赖
- 支持不同访问模式(只读、读写)
配置示例
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-test-with-workspace
spec:
pipelineRef:
name: build-test-pipeline
workspaces:
- name: source-code
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- name: cache
persistentVolumeClaim:
claimName: build-cache-pvc
PipelineRun 状态管理
监控执行状态
PipelineRun 的 status 字段提供执行进度的详细信息:
status:
completionTime: "2023-05-04T02:19:14Z"
conditions:
- lastTransitionTime: "2023-05-04T02:19:14Z"
message: "Tasks Completed: 4, Skipped: 0"
reason: Succeeded
status: "True"
type: Succeeded
startTime: "2023-05-04T02:00:11Z"
childReferences:
- name: build-deploy-app-run-build
pipelineTaskName: build
kind: TaskRun
取消 PipelineRun
要取消正在运行的 PipelineRun,更新其 spec.status 字段:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-app-run
spec:
# [...other fields...]
status: "Cancelled"
这会立即终止所有正在运行的 TaskRuns,并且不会执行待处理的任务或 finally 任务。
优雅停止 PipelineRun
要优雅停止 PipelineRun,允许执行 finally 任务:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-app-run
spec:
# [...other fields...]
status: "StoppedRunFinally"
这会完成当前正在运行的任务,但不启动新的任务,除了 finally 任务。
参考资料