Pod Template 配置指南

快速导航

入门:

常见场景:

故障排查:

为什么使用 Pod Templates?

当你在生产环境中运行 Tekton Pipelines 时,通常会遇到默认 Pod 配置无法满足需求的场景:

常见挑战:

  • 安全策略要求:组织的安全策略要求所有容器都以非 root 用户运行,但某些 Pipeline 执行会因权限错误而失败。
  • 私有镜像仓库访问:Pipeline 使用来自私有镜像仓库的自定义镜像,但由于缺少凭证,Pod 无法拉取镜像。
  • 资源调度:你需要让构建任务运行在带有 SSD 存储的高性能节点上,但 Pod 被调度到普通节点,导致构建速度很慢。
  • 多租户环境:不同团队对其 Pipelines 需要不同的安全设置、资源配额或节点放置策略。
  • 合规要求:你必须满足特定的合规标准(PCI DSS、HIPAA 等),这些标准要求特定的 Pod 安全配置。

没有 Pod Templates 时:

你需要修改单独的 Task 定义,或者为同一个 Task 创建多个不同配置的版本,这会导致:

  • 配置重复和维护开销
  • 难以强制执行一致的安全策略
  • 无法将社区 Tasks(例如 Tekton catalog Tasks)适配到你的环境中

Pod Templates 如何解决这些问题:

Pod templates 提供了一个灵活的多级配置系统,使你能够:

  • 为集群中的所有 Pipelines 设置安全的基线配置
  • 在需要时为特定 Pipeline 或 Task 覆盖配置
  • 使用官方 Tekton catalog Tasks,同时适配到你的环境
  • 保持 Task 逻辑与执行环境配置分离

什么是 Pod Templates?

Pod templates 是配置字段,允许你自定义 Tekton TaskRuns 和 PipelineRuns 的 Pod 规格。它们定义了 PodSpec 的一部分,Tekton 使用这些配置来配置执行 Tasks 和 Pipelines 的 Pods。

Pod templates 可以在不同层级进行配置(全局、按 pipeline、按 task),从而灵活地应用不同作用域和优先级的配置。

有关 Pod template 概念和支持字段的详细信息,请参见 Pod Templates Concepts。

何时使用 Pod Templates

Pod templates 适用于以下场景:

  • 安全要求:配置 security contexts(例如 runAsUser、fsGroup)以满足安全策略
  • 私有镜像仓库访问:为访问私有容器镜像仓库配置 image pull secrets
  • 节点调度:配置 node selectors、tolerations 或 affinity 规则来控制 Pod 放置
  • 资源管理:配置计算资源、卷和存储需求
  • 环境变量:为 Pipeline 执行设置环境变量
  • 网络配置:配置 DNS policies 和网络设置
  • 一致性:确保多个 Pipeline 执行之间的执行环境保持一致

选择哪种配置方式

使用此决策指南可快速确定哪种配置方式最适合你的需求:

场景推荐方法原因
一次性执行且有特殊要求方法 1:TaskRun仅应用于单个 TaskRun。
在全局应用前先测试某项配置方法 1:TaskRun可安全测试,不影响其他执行。
某一个特定 pipeline 需要特殊配置方法 2:PipelineRun仅覆盖这个 pipeline,不影响其他。
同一 pipeline 中的不同 tasks 需要不同配置方法 3:TaskRunSpecs可对每个 task 进行精细控制。适用于混合工作负载(官方 + 自定义 Tasks)。
为集群中的所有 pipelines 设置基线配置方法 4:全局(TektonConfig)配置一次即可影响所有执行。适用于安全默认值、image pull secrets。

如何配置 Pod Templates

Pod templates 可以在四个不同层级进行配置,每个层级用途不同,影响范围也不同。

方法 1:TaskRun 级配置

直接在 TaskRun 中配置 Pod template。这只会影响该特定 TaskRun 的执行。

使用场景:为单个 TaskRun 执行应用特定配置。

配置位置:TaskRun 中的 spec.podTemplate

示例:

apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
  name: build-task-run
spec:
  taskRef:
    name: build-task
  podTemplate:
    securityContext:
      runAsUser: 65532  # 可按需修改(例如,0 表示 root,1000 表示自定义用户)
      fsGroup: 65532
    nodeSelector:
      disktype: ssd

方法 2:PipelineRun 级配置

在 PipelineRun 级别配置 Pod template。这会影响该 PipelineRun 中的所有 Tasks,除非被 taskRunSpecs 覆盖。

使用场景:为一次 Pipeline 执行中的所有 Tasks 应用一致配置。

配置位置:PipelineRun 中的 spec.taskRunTemplate.podTemplate

示例:

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  name: build-deploy-pipeline-run
spec:
  pipelineRef:
    name: build-deploy-pipeline
  taskRunTemplate:
    podTemplate:
      securityContext:
        runAsUser: 65532  # 可按需修改(例如,0 表示 root)
        fsGroup: 65532
      nodeSelector:
        environment: production
      imagePullSecrets:
        - name: private-registry-secret

方法 3:PipelineRun TaskRunSpecs 配置

为 PipelineRun 中的特定 Tasks 配置 Pod template。这允许对 Pipeline 中的单个 Task 进行精细控制。

使用场景:为同一次 Pipeline 执行中的不同 Tasks 应用不同配置。

配置位置:PipelineRun 中的 spec.taskRunSpecs[].podTemplate

示例:

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  name: build-deploy-pipeline-run
spec:
  pipelineRef:
    name: build-deploy-pipeline
  taskRunSpecs:
    - pipelineTaskName: build
      podTemplate:
        securityContext:
          runAsUser: 0  # 如有需要,可为该特定 task 覆盖
        nodeSelector:
          disktype: ssd
          performance: high
        tolerations:
          - key: "dedicated"
            operator: "Equal"
            value: "build"
            effect: "NoSchedule"
    - pipelineTaskName: deploy
      podTemplate:
        securityContext:
          runAsUser: 65532  # 为该 task 使用安全默认值
          runAsNonRoot: true
        nodeSelector:
          environment: production

方法 4:全局默认配置(TektonConfig)

配置一个全局默认 Pod template,适用于集群中的所有 TaskRuns 和 PipelineRuns。

使用场景:在集群中的所有 Pipeline 执行中应用一致的基线配置。

配置位置:TektonConfig 中的 spec.pipeline.default-pod-template

[Security Best Practice]

建议使用非 root 用户(例如 runAsUser: 65532)作为默认配置,以遵循最小权限原则。官方 Tekton Tasks 设计为可与 UID 65532 配合使用。仅在自定义镜像或旧版应用需要时,才将 runAsUser 覆盖为 0。

[Why UID 65532?]

UID 65532 是官方 Tekton Tasks 以及大多数 Tekton catalog Tasks 使用的标准非 root 用户 ID。该 ID 遵循最小权限原则,并且在 Tekton 生态中被广泛采用,符合安全最佳实践。

fsGroup:为 Pod 中所有容器设置组 ID。这可确保 Pod 创建的文件归指定组所有,从而允许正确的文件访问权限。

步骤:

Step 1

编辑 TektonConfig 资源:

$ kubectl edit tektonconfigs.operator.tekton.dev config

Step 2

添加或修改 spec.pipeline.default-pod-template 配置:

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pipeline:
    default-pod-template: |
      securityContext:
        runAsUser: 65532
        fsGroup: 65532
      imagePullSecrets:
        - name: private-registry-secret

Step 3

验证配置:

$ kubectl get configmap -n tekton-pipelines config-defaults -o yaml | grep 'default-pod-template: |' -A5

配置方式对比

方法作用范围优先级适用场景优点缺点
方法 1:TaskRun单个 TaskRun 执行中测试、一次性执行安全、隔离、易测试需要为每个 TaskRun 单独配置
方法 2:PipelineRun一个 PipelineRun 中的所有 tasks中特定 pipeline 的需求易于管理,适用于 pipeline 中所有 tasks必须为每个 PipelineRun 指定
方法 3:TaskRunSpecsPipelineRun 中的特定 tasks最高混合工作负载(官方 + 自定义 Tasks)可对每个 task 进行精细控制配置更复杂
方法 4:全局(TektonConfig)集群中的所有 TaskRuns/PipelineRuns最低基线安全和默认值配置一次,影响所有执行全局影响,需要集群权限

优先级规则:当同一个字段在多个层级进行了配置时,优先级更高的配置将生效。TaskRunSpecs(最高)> PipelineRun/TaskRun(中)> Global(最低)。

配置优先级

Pod template 配置遵循清晰的优先级层次。当同一字段存在多个配置时,优先级更高的配置会覆盖优先级更低的配置。

优先级顺序(从高到低):

  1. PipelineRun taskRunSpecs podTemplate - 最高优先级,适用于特定 tasks
  2. PipelineRun podTemplate 或 TaskRun podTemplate - 中等优先级,适用于 pipeline 或 task 级别
  3. Global default-pod-template - 最低优先级,适用于所有执行

合并行为:

  • 环境变量:按名称合并;高优先级值会覆盖低优先级值
  • Volumes:按名称合并;高优先级值会覆盖低优先级值
  • 其他字段:高优先级配置会完全替换低优先级配置

示例:

如果你有:

  • 全局配置:runAsUser: 65532(安全默认值)
  • PipelineRun 配置:runAsUser: 0(为自定义镜像覆盖)
  • TaskRunSpec 配置:runAsUser: 65532(为官方 Tasks 恢复安全默认值)

结果将是:

  • 特定 task(使用官方 Task):runAsUser: 65532
  • Pipeline 中其他 tasks(使用自定义镜像):runAsUser: 0

配置示例

示例 1:安全默认配置(推荐)

场景:为所有 Pipeline tasks 设置使用非 root 用户的安全默认配置。这是遵循安全最佳实践的推荐基线配置。

全局配置:

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pipeline:
    default-pod-template: |
      securityContext:
        runAsUser: 65532
        runAsNonRoot: true
        fsGroup: 65532
        fsGroupChangePolicy: "OnRootMismatch"

注意:官方 Tekton Tasks 和 catalog Tasks 设计为可与 UID 65532 配合使用。此配置可确保所有 Pipeline 执行默认都以安全方式运行。

示例 2:Image Pull Secrets

场景:为访问私有仓库配置 image pull secrets。

PipelineRun 配置:

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  name: build-pipeline-run
spec:
  pipelineRef:
    name: build-pipeline
  taskRunTemplate:
    podTemplate:
      imagePullSecrets:
        - name: private-registry-secret
        - name: enterprise-registry-secret

示例 3:节点调度

场景:在高性能节点上运行构建 tasks。

TaskRunSpecs 配置:

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  name: build-deploy-pipeline-run
spec:
  pipelineRef:
    name: build-deploy-pipeline
  taskRunSpecs:
    - pipelineTaskName: build
      podTemplate:
        nodeSelector:
          disktype: ssd
          performance: high
        tolerations:
          - key: "dedicated"
            operator: "Equal"
            value: "build"
            effect: "NoSchedule"

示例 4:为需要 root 访问权限的自定义镜像进行覆盖

场景:你的全局默认值使用安全的非 root 用户(65532),但你有一个 pipeline 使用需要 root 访问权限的自定义镜像。使用 TaskRunSpecs 为特定 tasks 进行覆盖,同时为官方 Tasks 保持安全默认值。

# 全局基线配置(安全默认值)
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pipeline:
    default-pod-template: |
      securityContext:
        runAsUser: 65532
        fsGroup: 65532
        fsGroupChangePolicy: "OnRootMismatch"
      imagePullSecrets:
        - name: default-registry-secret

---
# 带有选择性覆盖的 Pipeline 执行
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  name: mixed-workload-pipeline-run
spec:
  pipelineRef:
    name: build-deploy-pipeline
  taskRunSpecs:
    # 仅为使用需要 root 的自定义镜像的 tasks 覆盖
    - pipelineTaskName: custom-build
      podTemplate:
        securityContext:
          runAsUser: 0
        nodeSelector:
          disktype: ssd
    # 使用官方 Tekton catalog Tasks 的 tasks 会继承安全默认值(65532)
    # 对 'git-clone'、'kaniko-build' 等无需覆盖

最佳实践:仅对真正需要 root 访问权限的特定 tasks 将 runAsUser 覆盖为 0。让官方 Tekton Tasks 使用安全默认值(65532)。

示例 5:使用官方 Tasks 与旧版全局配置

场景:你已从 Alauda DevOps Tekton v3 迁移到 Alauda DevOps Pipelines,并将全局 default-pod-template 设置为 runAsUser: 0,以兼容现有自定义镜像。现在你希望使用官方 Tekton catalog Tasks,而这些 Tasks 需要 runAsUser: 65532 和 fsGroup: 65532。

解决方案:对于使用官方 Tasks 的 Pipelines,在 PipelineRun 级别覆盖全局配置。

当前全局配置(迁移期间设置):

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pipeline:
    default-pod-template: |
      securityContext:
        runAsUser: 0  # 自定义镜像的旧版全局设置

用于官方 Tasks 的 PipelineRun 配置:

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  name: catalog-tasks-pipeline-run
spec:
  pipelineRef:
    name: pipeline-using-catalog-tasks  # 使用 git-clone、buildah 等的 Pipeline
  taskRunTemplate:
    podTemplate:
      # 覆盖全局 runAsUser: 0,以使用官方 Tasks 所需的安全设置
      securityContext:
        runAsUser: 65532
        fsGroup: 65532

替代方案:对于混合场景,使用 TaskRunSpecs:

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  name: mixed-pipeline-run
spec:
  pipelineRef:
    name: mixed-pipeline
  # 大多数 tasks 将使用全局 runAsUser: 0(用于自定义镜像)
  taskRunSpecs:
    # 仅为使用官方 catalog Tasks 的 tasks 覆盖
    - pipelineTaskName: git-clone
      podTemplate:
        securityContext:
          runAsUser: 65532
          fsGroup: 65532
    - pipelineTaskName: buildah
      podTemplate:
        securityContext:
          runAsUser: 65532
          fsGroup: 65532
    # 其他 tasks(使用自定义镜像)继承全局 runAsUser: 0

长期建议:逐步更新你的自定义镜像以支持非 root 用户,然后将全局默认值更改为 runAsUser: 65532,以获得更好的安全性。

示例 6:主动迁移期间的临时覆盖

场景:你当前正在从 Alauda DevOps Tekton v3 迁移到 Alauda DevOps Pipelines,但你的自定义镜像尚未更新为支持非 root 用户。你需要一个临时方案,在更新镜像期间继续运行旧版 pipelines。

上下文:与示例 5(迁移已完成且全局 runAsUser: 0)不同,此场景适用于以下用户:

  • 拥有安全的全局默认值(runAsUser: 65532)
  • 正在主动迁移旧版 pipelines
  • 在更新容器镜像期间需要临时覆盖

临时 PipelineRun 配置:

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  name: legacy-pipeline-run
spec:
  pipelineRef:
    name: legacy-pipeline-requiring-root
  taskRunTemplate:
    podTemplate:
      # 迁移期间的临时覆盖 - 计划后续移除
      securityContext:
        runAsUser: 0

迁移路径:

  1. 短期:对需要 root 的旧版 pipelines 使用此覆盖
  2. 中期:更新自定义容器镜像以支持非 root 用户(UID 65532)
  3. 长期:移除这些覆盖,改为依赖安全的全局默认值

重要:这是主动迁移期间的临时变通方案。

重要注意事项

常见问题

以下是用户最常遇到的问题。在配置 Pod templates 之前,请先查看这些内容:

  1. ❌ 将全局 runAsUser 设置为 0:不要在全局 default-pod-template 中设置 runAsUser: 0。这违反了安全最佳实践,并使所有 Pipeline 执行暴露于不必要的风险中。全局默认值应始终使用 runAsUser: 65532。如果确实需要 root 访问权限,只能在 TaskRun/PipelineRun 级别覆盖。

  2. ❌ security context 冲突:确保 Task 级别的 security context 设置(例如 runAsNonRoot: true)与 Pod template 的 security context 兼容。常见错误:container's runAsUser breaks non-root policy。有关解决方案,请参见 故障排查:Custom Image Pod Creation Failed。

  3. ❌ 对配置优先级理解错误:请记住,优先级更高的配置会覆盖优先级更低的配置:

    • TaskRunSpecs(最高)> PipelineRun/TaskRun(中)> Global(最低)
    • 如果某个配置未生效,请检查是否有更高优先级层级的覆盖。
  4. ❌ 全局配置影响范围:修改全局 default-pod-template 时要谨慎,因为它会影响集群中的所有 Pipeline 执行。请先使用 TaskRun/PipelineRun 进行测试。

  5. ❌ YAML 格式:在 TektonConfig 中配置 default-pod-template 时,请使用竖线(|)字符来正确格式化 YAML 多行字符串:

    default-pod-template: |
      securityContext:
        runAsUser: 65532

配置范围和生效时机

  • 全局配置:影响配置应用后新创建的所有 TaskRuns 和 PipelineRuns。不会影响已在运行中的执行。
  • TaskRun/PipelineRun 配置:仅影响特定执行。
  • 配置变更:对新的执行会立即生效。无需重启 Tekton 组件。

所需权限

  • 全局配置:需要集群级权限来修改 TektonConfig 资源(通常为 cluster-admin 或同等权限)。
  • TaskRun/PipelineRun 配置:需要 namespace 级权限来创建/修改 TaskRun 或 PipelineRun 资源。

最佳实践

  1. 遵循安全最佳实践:始终使用非 root 用户(runAsUser: 65532)作为全局默认值。官方 Tekton Tasks 设计为可与 UID 65532 配合使用。仅在特定任务确实需要 root 权限时,才覆盖为 runAsUser: 0。

  2. 从安全的全局默认值开始:在全局 default-pod-template 中配置安全基线设置:

    securityContext:
      runAsUser: 65532
      runAsNonRoot: true
      fsGroup: 65532
  3. 选择性覆盖:当自定义镜像需要 root 访问权限时,只在该特定 tasks 的 TaskRun 或 taskRunSpecs 层级进行覆盖。不要将全局默认值改为 runAsUser: 0。

  4. 使用 TaskRunSpecs 实现精细控制:当 pipeline 中不同 tasks 需要不同的 security context(例如自定义镜像与官方 Tasks)时,使用 taskRunSpecs 分别应用不同配置。

  5. 记录安全例外:清楚记录为什么特定 tasks 需要 root 访问权限(runAsUser: 0)。定期审查这些例外,看看是否可以消除。

  6. 测试配置变更:在将 Pod template 配置变更应用到生产环境之前,先在非生产环境中进行测试,尤其是 security context 的变更。

验证

应用 Pod template 配置后,请验证其是否生效:

对于全局配置

检查配置是否已应用到 ConfigMap:

# 检查 ConfigMap
$ kubectl get configmap -n tekton-pipelines config-defaults -o yaml | grep 'default-pod-template' -A 10

  default-pod-template: |
    securityContext:
      runAsUser: 65532

期望输出应显示你所配置的 pod template。

对于 TaskRun/PipelineRun 配置

Step 1:查找由你的 TaskRun 或 PipelineRun 创建的 Pod

# 对于 TaskRun
$ kubectl get pods -n <namespace> -l tekton.dev/taskRun=<taskrun-name>

# 对于 PipelineRun(显示由该 PipelineRun 创建的所有 Pods)
$ kubectl get pods -n <namespace> -l tekton.dev/pipelineRun=<pipelinerun-name>

# 示例输出:
# NAME                                      READY   STATUS      RESTARTS   AGE
# build-task-run-pod                        0/1     Completed   0          2m

Step 2:验证 Pod 规格

# 检查 Pod 的 security context
$ kubectl get pod -n <namespace> <pod-name> -o yaml | grep -A 10 "securityContext:"

  securityContext:
    runAsUser: 65532
    fsGroup: 65532

# 检查具体字段
$ kubectl get pod -n <namespace> <pod-name> -o jsonpath='{.spec.securityContext.runAsUser}'
# 应输出:65532(或你配置的值)

# 检查 fsGroup
$ kubectl get pod -n <namespace> <pod-name> -o jsonpath='{.spec.securityContext.fsGroup}'
# 应输出:65532(或你配置的值)

相关文档