PipelineRuns

PipelineRun 是一个 Kubernetes 自定义资源,用于实例化一个 Pipeline 进行执行。PipelineRuns 负责执行 Pipeline 中定义的任务并管理其生命周期,提供了一种执行端到端 CI/CD 工作流的方式。

为什么需要 PipelineRuns

CI/CD 工作流挑战

在 CI/CD 系统中,工作流执行存在以下几个挑战:

  • 工作流编排:需要按照特定顺序协调多个任务
  • 资源协调:需要在多个任务之间管理资源
  • 数据共享:需要在工作流中的任务之间共享数据
  • 执行跟踪:需要跟踪整个工作流的进度
  • 错误处理:需要处理任务和工作流层级的失败
  • 可审计性:需要维护所有工作流执行的记录

Tekton 的解决方案

Tekton PipelineRuns 针对这些挑战提供了解决方案:

  • 工作流实例:每个 PipelineRun 代表一个具有特定输入的 Pipeline 的单次执行
  • 编排:PipelineRuns 根据依赖关系管理任务的执行顺序
  • 资源绑定:PipelineRuns 将实际资源绑定到 Pipeline 需求上
  • 状态跟踪:PipelineRuns 跟踪每个任务的执行状态
  • 结果传播: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. Tekton 为 Pipeline 中的每个任务创建 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!"

重要参数

超时

超时允许设置 PipelineRun 执行的最大持续时间。

用例

  • 防止长时间运行的 Pipeline 无限制消耗资源
  • 确保 CI/CD 工作流在合理的时间内完成
  • 处理悬挂或死锁的任务

原则

超时:

  • 在 PipelineRun 规范中指定
  • 应用于整个 PipelineRun 执行或特定部分(任务、finally)
  • 从第一个任务开始到最后一个任务完成进行测量
  • 如果超过限制,将导致 PipelineRun 失败

配置示例

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  name: build-deploy-with-timeout
spec:
  pipelineRef:
    name: build-deploy-app
  timeouts:
    pipeline: "1h"
    tasks: "45m"
    finally: "15m"
  params:
    - name: image-name
      value: my-registry/my-app:latest

ServiceAccount

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

用例

  • 提供访问私有容器注册表的凭据
  • 与云服务提供商进行身份验证
  • 授权访问 Kubernetes 资源
  • 提供进行 Git 操作的凭据

原则

ServiceAccounts:

  • 可以在 PipelineRun 级别为所有任务指定
  • 可以使用 taskRunSpecs 映射到特定任务
  • 通过 Kubernetes 秘密提供凭据
  • 使对外部资源的安全访问成为可能

配置示例

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

TaskRunSpecs

TaskRunSpecs 允许自定义 PipelineRun 中单个 TaskRun 的配置。

用例

  • 为不同任务应用不同的 ServiceAccounts
  • 设置特定于任务的 Pod 模板
  • 配置特定于任务的超时
  • 应用特定于任务的计算资源

原则

TaskRunSpecs:

  • 为特定任务重写默认的 PipelineRun 配置
  • 允许对任务执行环境进行精细控制
  • 可用于满足特定的安全或资源需求
  • 使 Pipeline 的不同阶段可以使用不同的配置

配置示例

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
    - pipelineTaskName: deploy
      serviceAccountName: deploy-service-account
      podTemplate:
        tolerations:
        - key: "dedicated"
          operator: "Equal"
          value: "deploy"
          effect: "NoSchedule"

工作区

工作区允许在 Pipeline 中的任务之间共享数据。

用例

  • 在构建和测试任务之间共享源代码
  • 将构建工件传递给部署任务
  • 在多个任务之间共享配置文件
  • 在 Pipeline 执行之间持久化数据

原则

工作区:

  • 在 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:
  completionTime: "2023-05-04T02:19:14Z"
  conditions:
    - lastTransitionTime: "2023-05-04T02:19:14Z"
      message: "任务已完成: 4, 被跳过: 0"
      reason: 成功
      status: "True"
      type: 成功
  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:
  # [...其他字段...]
  status: "已取消"

这将立即终止所有正在运行的 TaskRuns,并不执行挂起的任务或 finally 任务。

优雅地停止 PipelineRun

要优雅地停止 PipelineRun,允许 finally 任务执行:

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  name: build-deploy-app-run
spec:
  # [...其他字段...]
  status: "停止执行 finally"

这将完成当前正在运行的任务,但不会启动新的任务,除了 finally 任务。

参考资料