PipelineRuns
PipelineRun 是一种 Kubernetes Custom Resource,用于实例化一个 Pipeline 以供执行。PipelineRun 负责执行 Pipeline 中定义的 Tasks 并管理其生命周期,从而提供一种运行端到端 CI/CD 工作流的方式。
为什么需要 PipelineRuns
CI/CD 工作流挑战
在 CI/CD 系统中,工作流执行面临多个挑战:
- 工作流编排:需要按特定顺序协调多个任务
- 资源协调:需要管理跨多个任务的资源
- 数据共享:需要在工作流中的任务之间共享数据
- 执行跟踪:需要跟踪整个工作流的进度
- 错误处理:需要同时处理任务级和工作流级的失败
- 可审计性:需要保留所有工作流执行的记录
Tekton 的解决方案
Tekton PipelineRuns 通过以下方式应对这些挑战:
- 工作流实例:每个 PipelineRun 代表一次具有特定输入的 Pipeline 执行
- 编排:PipelineRuns 根据依赖关系管理 Tasks 的执行顺序
- 资源绑定:PipelineRuns 将实际资源绑定到 Pipeline 的需求
- 状态跟踪:PipelineRuns 跟踪每个 Task 的执行状态
- 结果传递:PipelineRuns 支持在 Tasks 之间共享结果
- Kubernetes 集成:PipelineRuns 利用 Kubernetes 进行资源管理和调度
优势
- 隔离性:每个 PipelineRun 独立执行,允许同一 Pipeline 并行运行
- 可追踪性:PipelineRuns 提供详细的执行历史和日志
- 灵活性:PipelineRuns 可以覆盖 Pipeline 参数和 workspace 绑定
- 可复用性:同一个 Pipeline 可以通过不同的 PipelineRuns 使用不同输入执行
- 集成性:PipelineRuns 可通过 Kubernetes API 被各种系统触发
- 可观测性:可以通过 Kubernetes 工具监控 PipelineRun 状态和日志
使用场景
PipelineRuns 适用于多种场景,包括:
- Application CI/CD:构建、测试和部署应用
- Infrastructure as Code:配置和管理基础设施
- Release Management:协调复杂的发布流程
- Scheduled Workflows:按计划运行工作流
- Event-Driven Workflows:响应外部事件触发工作流
约束和限制
- PipelineRuns 在单个 Kubernetes 集群内执行
- 一旦启动,PipelineRun 参数不能修改
- PipelineRuns 对失败的 Tasks 具有有限的重试能力
- PipelineRun 的执行时间受 Kubernetes pod 超时限制
- PipelineRuns 在开始执行后不能暂停("finally" tasks 除外)
原则
PipelineRun 执行模型
创建 PipelineRun 时:
- Tekton 验证 PipelineRun 规范
- Tekton 为 Pipeline 中的每个 Task 创建 TaskRuns
- TaskRuns 根据其依赖关系执行
- 从 Tasks 收集结果,并可供后续 Tasks 使用
- 随着每个 TaskRun 完成,PipelineRun 状态会更新
- 在所有其他 Tasks 完成或失败后,执行 "finally" Tasks
- 当所有 TaskRuns 完成时,PipelineRun 完成
PipelineRun 状态
PipelineRun 状态提供有关执行的详细信息:
- 总体状态(Running、Succeeded、Failed 等)
- 开始和完成时间
- 各个 TaskRun 的状态
- Task 结果
- 失败原因(如适用)
- 用于访问日志的 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 执行的最大持续时间。
使用场景
- 防止长时间运行的 Pipelines 无限消耗资源
- 确保 CI/CD 工作流在合理时间内完成
- 处理挂起或死锁的 Tasks
- 为 Pipeline 执行的不同阶段设置不同的超时限制
原则
Timeout 的特点如下:
- 在 PipelineRun 规范中使用
timeouts 字段指定(旧的 timeout 字段已弃用)
- 适用于整个 PipelineRun 执行或特定部分(tasks、finally)
- 从第一个 Task 开始到最后一个 Task 完成为止进行计时
- 超出后会导致 PipelineRun 失败
- 必须遵循约束:
timeouts.pipeline >= timeouts.tasks + timeouts.finally
- 重要:如果任一子字段设置为 "0",则该部分没有超时限制。要将
timeouts.tasks 或 timeouts.finally 设为 "0",还必须将 timeouts.pipeline 设为 "0"
Timeout 字段
- pipeline:整个 PipelineRun 的最大持续时间
- tasks:所有非 finally tasks 的最大持续时间
- finally:所有 finally tasks 的最大持续时间
配置示例
示例 1:标准 timeout 配置
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-with-timeout
spec:
pipelineRef:
name: build-deploy-app
timeouts:
pipeline: "1h" # Total pipeline timeout
tasks: "45m" # Timeout for all regular tasks
finally: "15m" # Timeout for finally tasks
params:
- name: image-name
value: my-registry/my-app:latest
示例 2:tasks 和 finally 没有 timeout(要求 pipeline timeout 为 0)
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-no-timeout
spec:
pipelineRef:
name: build-deploy-app
timeouts:
pipeline: "0" # No overall timeout
tasks: "0" # No timeout for regular tasks
finally: "0" # No timeout for finally tasks
params:
- name: image-name
value: my-registry/my-app:latest
注意:
- 示例 1 符合约束
pipeline (1h) >= tasks (45m) + finally (15m)
- 示例 2 通过将所有值设为 "0" 来禁用 timeout
ServiceAccount
ServiceAccount 允许指定用于认证的 Kubernetes ServiceAccount。
使用场景
- 为访问私有容器镜像仓库提供凭据
- 与云提供商进行认证
- 授权访问 Kubernetes 资源
- 为 Git 操作提供凭据
原则
ServiceAccounts:
- 可在 PipelineRun 级别为所有 Tasks 指定
- 可通过 taskRunSpecs 映射到特定 Task
- 通过 Kubernetes secrets 提供凭据
- 支持对外部资源的安全访问
配置示例
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 允许指定一个 Pod 模板,作为执行每个 Task 的 Pod 配置基础。
使用场景
- 为特定硬件需求设置 node selector
- 为专用节点配置 tolerations
- 指定 security context 以增强安全性
- 在 Pod 级别设置资源 limits 和 requests
- 配置 affinity 规则以提升资源利用率
- 为 Pods 添加自定义 annotations 或 labels
原则
Pod Templates:
- 除非被 taskRunSpecs 覆盖,否则会应用于 PipelineRun 中的所有 Tasks
- 遵循 Kubernetes Pod template 规范
- 可被 taskRunSpecs 中的 Task 特定配置覆盖
- 在 PipelineRun 的所有 Tasks 中保持一致的 Pod 配置
- 支持所有标准 Kubernetes Pod template 字段
配置示例
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-with-pod-template
spec:
pipelineRef:
name: build-deploy-app
taskRunTemplate:
serviceAccountName: default
# Global Pod template for all Tasks in the PipelineRun
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 允许通过指定 PipelineTaskRunSpec 列表来自定义 PipelineRun 中的单个 TaskRun 配置,从而为每个 task 设置 ServiceAccountName、Pod 模板、computeResources 和 Metadata。
使用场景
- 为不同 Tasks 应用不同的 ServiceAccounts,以实现细粒度访问控制
- 设置 Task 特定的 Pod 模板,以满足不同的资源或安全要求
- 配置 Task 特定的元数据,以便更好地组织和跟踪
- 覆盖特定 Tasks 的全局 PipelineRun 配置
- 为 Pipeline 的不同阶段应用不同的 compute resources 或 node selector
原则
TaskRunSpecs:
- 覆盖为整个 Pipeline 设置的 Pod 模板
- 允许对 Task 执行环境进行细粒度控制
- 可用于满足特定的安全、资源或调度需求
- 支持为 Pipeline 的不同阶段配置不同内容
- 支持所有标准 Kubernetes Pod template 规范
- 可与全局 PipelineRun 配置结合使用
配置字段
每个 TaskRunSpec 支持以下字段:
- pipelineTaskName:要应用配置的 Pipeline task 名称
- serviceAccountName:此特定 Task 使用的 ServiceAccount
- podTemplate:此 Task 特定的 Pod 模板配置
- computeResources:此 Task 的计算资源需求(requests 和 limits),覆盖 Task spec 中定义的默认值
- metadata:TaskRun 的元数据配置
配置示例
示例 1:包含 ServiceAccount 和 Pod Template 的基本 TaskRunSpecs
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:覆盖全局 Pod Template 的 TaskRunSpecs
TaskRunSpecs 可以覆盖 PipelineRun 级别设置的全局 Pod template:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: override-global-template
spec:
pipelineRef:
name: build-deploy-app
taskRunTemplate:
serviceAccountName: default
# Global Pod template for all Tasks
podTemplate:
nodeSelector:
disktype: ssd
tolerations:
- key: "general"
operator: "Equal"
value: "pipeline"
effect: "NoSchedule"
# Task-specific overrides
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
示例 5:为特定 Tasks 覆盖 computeResources
使用 taskRunSpecs[].computeResources 为单个 Tasks 分配不同的 CPU/memory 配额,
覆盖 Task spec 中定义的任何默认值:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: pipeline-run-with-compute-resources
spec:
pipelineRef:
name: build-test-deploy
taskRunSpecs:
- pipelineTaskName: build
# Allocate more resources for the resource-intensive build step
computeResources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
- pipelineTaskName: test
# Use lighter resources for the test step
computeResources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
NOTE
taskRunSpecs 中的 computeResources 是一个 Beta 功能,需要在 Tekton feature flags ConfigMap 中将 enable-api-fields 设置为 beta(或 alpha)。在平台的默认安装中,enable-api-fields 已经设置为 beta,因此该功能开箱即用——只有在它被手动设置为 stable 时,才需要调整该标志。
Workspaces
Workspaces 允许在 Pipeline 中的 Tasks 之间共享数据。
使用场景
- 在 build 和 test Tasks 之间共享源代码
- 将构建产物传递给部署 Tasks
- 在多个 Tasks 之间共享配置文件
- 在 Pipeline 执行之间持久化数据
原则
Workspaces:
- 在 Pipeline 中声明,并在 PipelineRun 中绑定
- 可由多种 volume 类型提供支持(PVC、ConfigMap、Secret 等)
- 支持在没有直接依赖的情况下共享数据
- 支持不同访问模式(ReadOnly、ReadWrite)
配置示例
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,并且不会执行待处理的 Tasks 或 finally Tasks。
优雅停止 PipelineRun
要优雅地停止 PipelineRun,并允许 finally Tasks 执行:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-deploy-app-run
spec:
# [...other fields...]
status: "StoppedRunFinally"
这会完成当前正在运行的 Tasks,但不会启动新的 Tasks,finally Tasks 除外。
参考