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

  1. Tekton 验证 PipelineRun 规范
  2. 为 Pipeline 中的每个 Task 创建 TaskRuns
  3. TaskRuns 根据依赖关系执行
  4. 收集任务结果供后续任务使用
  5. 每个 TaskRun 完成时更新 PipelineRun 状态
  6. 所有其他任务完成或失败后执行 “finally” 任务
  7. 所有 TaskRuns 完成后,PipelineRun 结束

PipelineRun 状态

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

  1. 总体状态(运行中、成功、失败等)
  2. 开始和完成时间
  3. 各个 TaskRun 状态
  4. 任务结果
  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 执行的最大时长。

使用场景

  • 防止长时间运行的 Pipeline 无限制占用资源
  • 确保 CI/CD 工作流在合理时间内完成
  • 处理挂起或死锁的任务
  • 为 Pipeline 执行的不同阶段设置不同超时限制

原则

Timeout:

  • 在 PipelineRun 规范中通过 timeouts 字段指定(旧的 timeout 字段已弃用)
  • 可应用于整个 PipelineRun 或特定部分(tasks、finally)
  • 从第一个任务开始到最后一个任务完成计时
  • 超时则导致 PipelineRun 失败
  • 必须满足约束:timeouts.pipeline >= timeouts.tasks + timeouts.finally
  • 重要:若任一子字段设置为 "0",则该部分无超时。若要将 timeouts.taskstimeouts.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 配置模板。

TIP

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

使用场景

  • 为特定硬件需求设置节点选择器
  • 配置专用节点的容忍度
  • 指定安全上下文以增强安全性
  • 在 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 任务。

参考资料