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 支持在 Tasks 之间共享结果
  • Kubernetes 集成:PipelineRuns 利用 Kubernetes 进行资源管理和调度

优势

  • 隔离性:每个 PipelineRun 独立执行,从而允许同一 Pipeline 并行运行
  • 可追溯性:PipelineRuns 提供详细的执行历史和日志
  • 灵活性:PipelineRuns 可以覆盖 Pipeline 参数和 workspace 绑定
  • 可复用性:同一个 Pipeline 可以通过不同的 PipelineRuns 使用不同输入来执行
  • 集成性:PipelineRuns 可以通过 Kubernetes API 被各种系统触发
  • 可观测性:可以通过 Kubernetes 工具监控 PipelineRun 状态和日志

使用场景

PipelineRuns 适用于多种场景,包括:

  • Application CI/CD:构建、测试和部署 Application
  • 基础设施即代码:配置和管理基础设施
  • 发布管理:协调复杂的发布流程
  • 定时工作流:按计划运行工作流
  • 事件驱动工作流:响应外部事件触发工作流

约束和限制

  • 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.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" 来禁用超时

ServiceAccount

ServiceAccount 允许指定用于身份验证的 Kubernetes ServiceAccount。

使用场景

  • 为访问私有容器镜像仓库提供凭据
  • 与云提供商进行身份验证
  • 授权访问 Kubernetes 资源
  • 为 Git 操作提供凭据

原则

ServiceAccounts:

  • 可在 PipelineRun 级别为所有 Tasks 指定
  • 可通过 taskRunSpecs 映射到特定 Tasks
  • 通过 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 selectors
  • 为专用节点配置 tolerations
  • 指定 security contexts 以增强安全性
  • 在 Pod 级别设置资源 limits 和 requests
  • 配置 affinity 规则以更好地利用资源
  • 为 Pods 添加自定义 annotations 或 labels

原则

Pod Templates:

  • 默认应用于 PipelineRun 中的所有 Tasks,除非被 taskRunSpecs 覆盖
  • 遵循 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 专用的 metadata,以便更好地组织和跟踪
  • 覆盖特定 Tasks 的全局 PipelineRun 配置
  • 为 Pipeline 的不同阶段应用不同的计算资源或 node selectors

原则

TaskRunSpecs:

  • 覆盖为整个 Pipeline 设置的 Pod 模板
  • 允许对 Task 执行环境进行细粒度控制
  • 可用于满足特定的安全、资源或调度需求
  • 支持为 Pipeline 的不同阶段设置不同配置
  • 支持所有标准 Kubernetes Pod template 规范
  • 可与全局 PipelineRun 配置结合使用

配置字段

每个 TaskRunSpec 支持以下字段:

  • pipelineTaskName:要应用该配置的 Pipeline task 名称
  • serviceAccountName:用于该特定 Task 的 ServiceAccount
  • podTemplate:该 Task 专用的 Pod 模板配置
  • computeResources:该 Task 的计算资源需求(requests 和 limits),会覆盖 Task 规范中定义的默认值
  • metadata:TaskRun 的 metadata 配置

配置示例

示例 1:包含 ServiceAccount 和 Pod 模板的基础 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:包含 Metadata 配置的 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 模板的 TaskRunSpecs

TaskRunSpecs 可以覆盖在 PipelineRun 级别设置的全局 Pod 模板:

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 规范中定义的任何默认值:

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 中绑定
  • 可由多种卷类型支持(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,except for finally Tasks。

参考