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 时:

  1. Tekton 验证 PipelineRun 规范
  2. Tekton 为 Pipeline 中的每个 Task 创建 TaskRuns
  3. TaskRuns 根据其依赖关系执行
  4. 从 Tasks 收集结果,并可供后续 Tasks 使用
  5. 随着每个 TaskRun 完成,PipelineRun 状态会更新
  6. 在所有其他 Tasks 完成或失败后,执行 "finally" Tasks
  7. 当所有 TaskRuns 完成时,PipelineRun 完成

PipelineRun 状态

PipelineRun 状态提供有关执行的详细信息:

  1. 总体状态(Running、Succeeded、Failed 等)
  2. 开始和完成时间
  3. 各个 TaskRun 的状态
  4. Task 结果
  5. 失败原因(如适用)
  6. 用于访问日志的 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.taskstimeouts.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 配置基础。

TIP

有关 Pod Templates 的更多信息,请参阅 Pod Templates

使用场景

  • 为特定硬件需求设置 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 模板、computeResourcesMetadata

使用场景

  • 为不同 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 除外。

参考