☰
Tekton Pipeline Pod 模板(PodTemplate)完整指南:TaskRun/PipelineRun 调度配置、参数替换与全局默认模板合并策略
2026/9/27 8:46:56 网站建设 项目流程
  • 云原生
  • CI/CD
  • DevOps
  • 后端

【免费下载链接】pipeline

A cloud-native Pipeline resource.

项目地址:https://gitcode.com/gh_mirrors/pipelin/pipeline
点击查看免费下载

本文是一份关于 Tekton Pipeline 中 Pod 模板(Pod Template)的技术指南,核心围绕TaskRun与PipelineRun如何通过podTemplate字段复用PodSpec的“样板配置”,以及如何通过全局config-defaultsConfigMap 设置默认模板、如何在taskRunSpecs中做参数替换、如何使用imagePullSecrets查找镜像入口点(entrypoint)。读完本文,你将掌握 Pod 模板支持的完整字段清单、全局模板与运行级模板的合并规则,以及 Affinity Assistant Pod 模板的用法,并能直接在自己的 Tekton 工作负载中落地。

什么是 Pod 模板

Pod 模板定义了PodSpec的一部分配置(对应的 Kubernetes API 为Pod v1 core),Tekton 将它作为运行Task与Pipeline时创建 Pod 的“样板(boilerplate)”使用。也就是说,你不必在每个Task/Pipeline内部重复编写调度相关的底层字段,而是可以在更外层统一指定。

你可以在两类资源上指定 Pod 模板:

  • TaskRun:模板作用于该次 TaskRun 生成的单个 Pod。
  • PipelineRun:模板作用于该 PipelineRun 执行期间创建的所有 Task Pod。

此外,你还可以在 Tekton 的全局配置config-defaultsConfigMap 中,通过default-pod-template键定义一个全局 Pod 模板,见 additional-configs.md 中的“Customizing basic execution parameters”。全局模板会与你在TaskRun/PipelineRun中指定的模板进行合并(merge),合并规则详见下文。

指定 Pod 模板的具体示例可参考:

  • 为TaskRun指定 Pod 模板
  • 为PipelineRun指定 Pod 模板

一个最小示例

在TaskRun中通过podTemplate.securityContext强制容器以非 root 用户运行(这是常见的非 root 实践,见 taskruns.md):

apiVersion: tekton.dev/v1 # 或 tekton.dev/v1beta1 kind: TaskRun metadata: generateName: show-non-root-steps-run- spec: taskRef: name: show-non-root-steps podTemplate: securityContext: runAsNonRoot: true runAsUser: 1001

注意:如果某个 Task 的 step 自身指定了与 Pod 模板不同的用户,那么 step 自身的securityContext会优先生效,覆盖 Pod 级别设置。完整的可运行示例见 examples/v1/taskruns/run-steps-as-non-root.yaml。

在PipelineRun中,Pod 模板同时携带securityContext与volumes也是常见用法(例如将 PVC 挂载为缓存卷):

apiVersion: tekton.dev/v1 kind: PipelineRun metadata: name: mypipelinerun spec: pipelineRef: name: mypipeline podTemplate: securityContext: runAsNonRoot: true runAsUser: 1001 volumes: - name: my-cache persistentVolumeClaim: claimName: my-volume-claim

自定义任务(Custom Tasks)不一定使用 Pod 模板,需要查阅你所使用的自定义任务文档确认其是否支持。

全局默认 Pod 模板与合并策略

除了在资源上直接指定,你还可以在config-defaultsConfigMap 中通过default-pod-template键设置全局默认模板。该 ConfigMap 的定义见 config/config-defaults.yaml,其中_example块对每个键都给出了注释说明:

apiVersion: v1 kind: ConfigMap metadata: name: config-defaults data: default-service-account: "tekton" default-timeout-minutes: "20" default-pod-template: | nodeSelector: kops.k8s.io/instancegroup: build-instance-group default-managed-by-label-value: "my-tekton-installation" default-task-run-workspace-binding: | emptyDir: {} default-max-matrix-combinations-count: "1024" default-resolver-type: "git"

合并规则

全局模板与TaskRun/PipelineRun中指定的模板会合并,规则如下:

  • 除env和volumes外的所有字段:如果全局模板与运行级模板同时设置了某个字段,以TaskRun或PipelineRun中的值为准(运行级覆盖全局)。
  • env与volumes字段:按数组元素中的name进行合并。如果某项name相同,则使用TaskRun或PipelineRun中的那一项;name不同的项则全部保留。

源码层面的合并实现

以上规则在源码中有精确对应。pod.Template类型与MergePodTemplateWithDefault函数定义于 pkg/apis/pipeline/pod/template.go:

  • MergePodTemplateWithDefault(tpl, defaultTpl *PodTemplate):逐字段判断,凡是运行级模板字段为 nil(或空字符串/空切片)时,才回退到全局默认值;env与volumes则调用mergeByName按name合并,见该文件mergeByName与getName的实现。整体逻辑与上文描述的合并规则完全一致。

从源码结构看,运行级模板是“高优先级覆盖层”,全局模板只是兜底默认值。这也是为什么全局模板主要用于统一团队基线(如默认 nodeSelector、默认安全上下文),而个别任务再通过运行级模板覆盖。

配置解析入口

default-pod-template与default-affinity-assistant-pod-template两个键在 pkg/apis/config/default.go 中定义(第 67~68 行的常量),并在NewDefaultsFromMap中通过 YAML 反序列化为pod.Template/pod.AffinityAssistantTemplate结构(第 177~191 行)。若 YAML 解析失败,控制器会直接报错拒绝加载配置。对应的解析用例可参考 pkg/apis/config/default_test.go 与测试数据 pkg/apis/config/testdata/config-defaults-with-pod-template.yaml、pkg/apis/config/testdata/config-defaults-pod-template-err.yaml(后者用于验证非法配置的报错路径)。

在 taskRunSpecs 中对 Pod 模板做参数替换

当在PipelineRun的taskRunSpecs中使用 Pod 模板时,你可以基于 Pipeline 参数动态配置 Pod 模板字段——这对使用Matrix扇出(fan out)的 PipelineTask 尤其有用,因为每个矩阵组合携带不同的参数值。

参数替换使用标准 Tekton 语法$(params.paramName),支持所有接受字符串值的 Pod 模板字段。例如:

taskRunSpecs: - pipelineTaskName: build-task podTemplate: nodeSelector: kubernetes.io/arch: $(params.arch) environment: $(params.env) tolerations: - key: "workload-type" operator: "Equal" value: "$(params.workload)" effect: "NoSchedule"

更完整的示例见 pipelineruns.md 中的“Parameter Substitution in taskRunSpecs”。

与 Matrix 结合:每个组合一个独立 TaskRun

当与 Matrix 配合使用时,每个矩阵组合都会创建一个独立的TaskRun,并将参数值替换进对应的 Pod 模板。例如:

spec: taskRunSpecs: - pipelineTaskName: build-and-push-manifest podTemplate: nodeSelector: kubernetes.io/arch: $(params.arch) pipelineSpec: tasks: - name: build-and-push-manifest matrix: params: - name: arch value: ["amd64", "arm64"] taskSpec: params: - name: arch steps: - name: build-and-push image: ubuntu script: | echo "building on $(params.arch)"

上述配置中,Matrix 会产生两个TaskRun——一个面向amd64、一个面向arm64,各自通过替换后的nodeSelector调度到对应架构的节点。完整示例见 examples/v1/pipelineruns/beta/pipelinerun-with-matrix-and-taskrunspecs-param-substitution.yaml。更多细节参见 pipelineruns.md 中的“Matrix Support with taskRunSpecs”。

taskRunSpecs 的覆盖语义

taskRunSpecs中的podTemplate会覆盖Pipeline 级别的spec.podTemplate配置,而 Pipeline 级别的securityContext等字段仍会保留。例如下面的配置中,build-task使用任务级podTemplate(nodeSelector: disktype=ssd),同时继承 PipelineRun 级securityContext(runAsUser: 1000、runAsGroup: 2000、fsGroup: 3000),并拥有 1 小时 30 分钟的超时:

spec: podTemplate: securityContext: runAsUser: 1000 runAsGroup: 2000 fsGroup: 3000 taskRunSpecs: - pipelineTaskName: build-task serviceAccountName: sa-for-build podTemplate: nodeSelector: disktype: ssd timeout: "1h30m"

(v1beta1 中对应字段名为taskServiceAccountName与taskPodTemplate,见 pipelineruns.md。)

支持的字段清单

Pod 模板支持下表所列字段(各字段的 Kubernetes 语义详见对应链接):

字段说明
envPod 模板中在TaskRun/PipelineRun级别定义的环境变量,优先级高于steps与stepTemplate中定义的环境变量
nodeSelector必须为 true,Pod 才能被调度到对应节点(参见 Assigning Pods to Nodes)
tolerations允许(但不强制)Pod 调度到带匹配污点(taints)的节点上
affinity根据节点上的标签约束 Pod 可被调度的节点集合
securityContext指定 Pod 级安全属性与通用容器设置,如runAsUser与selinux
volumes指定 Pod 内容器可挂载的卷列表,允许你为Task中的每个volumeMount指定卷类型
runtimeClassName指定 Pod 的 RuntimeClass
automountServiceAccountToken默认:true。决定 Tekton 是否在容器内预定义路径自动挂载 Pod 所用 ServiceAccount 的 token
dnsPolicy默认:ClusterFirst。指定 Pod 的 DNS 策略。合法值为ClusterFirst、Default、None。不支持ClusterFirstWithHostNet,因为 Tekton Pod 不能使用 host networking
dnsConfig指定 Pod 的 附加 DNS 配置,如 nameserver 与 search domains
enableServiceLinks默认:true。决定 Pod 所在命名空间中的 Service 是否像 Docker service links 一样以环境变量形式注入 Pod
priorityClassName指定 Pod 的 PriorityClass,允许你选择性让低优先级工作负载被抢占
schedulerName指定调度 Pod 时使用的 调度器。可以为不同类型的工作负载指定不同调度器,例如机器学习负载使用volcano.sh
imagePullSecrets指定拉取私有镜像时使用的 Secret(参见 从私有仓库拉取镜像)
hostNetwork默认:false。决定是否使用宿主机网络命名空间
hostUsers默认:true。决定是否使用宿主的用户命名空间。设为false时为 Pod 创建新的用户命名空间,提供更好的安全隔离,有助于缓解容器逃逸漏洞。该字段为 alpha 级别,需要在 Kubernetes 集群上启用UserNamespacesSupportfeature gate(Kubernetes 1.25+ 可用)
hostAliases向 Pod 的/etc/hosts添加条目,提供 Pod 级主机名覆盖(参见 Kubernetes 文档)
topologySpreadConstraints控制 Pod 在集群拓扑域之间的分布方式

上述字段在源码pod.Template结构体(pkg/apis/pipeline/pod/template.go)中都有对应的 Go 字段与 JSON tag(如nodeSelector、env、tolerations、affinity、securityContext、volumes、runtimeClassName、automountServiceAccountToken、dnsPolicy、dnsConfig、enableServiceLinks、priorityClassName、schedulerName、imagePullSecrets、hostAliases、hostNetwork、hostUsers、topologySpreadConstraints),可供核对字段名与类型。

使用 imagePullSecrets 查找入口点(entrypoint)

当Task中没有配置command,且podTemplate中配置了imagePullSecrets时,Tekton Controller 会使用这些imagePullSecrets去镜像仓库查找镜像的入口点。

Tekton Controller 的 ServiceAccount 默认被授予访问 Secret 的权限(参见 config/200-clusterrole.yaml)。如果你的 Controller ServiceAccount 没有被授予访问其他命名空间下 Secret 的权限,需要通过RoleBinding显式授权,例如:

apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: creds-getter namespace: my-ns rules: - apiGroups: [""] resources: ["secrets"] resourceNames: ["creds"] verbs: ["get"]
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: creds-getter-binding namespace: my-ns subjects: - kind: ServiceAccount name: tekton-pipelines-controller namespace: tekton-pipelines apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: creds-getter apiGroup: rbac.authorization.k8s.io

源码中的调用链

这一行为在源码中有完整的调用链:

  1. 在 pkg/pod/pod.go 的第 273~283 行,构建 Pod 时取出taskRun.Spec.PodTemplate,并将其中的ImagePullSecrets传给resolveEntrypoints。
  2. resolveEntrypoints定义在 pkg/pod/entrypoint_lookup.go:遍历所有 step,凡是没有显式command的容器,都会通过EntrypointCache.get()查询镜像元数据(入口点命令与 digest),并传入namespace、serviceAccountName与imagePullSecrets。
  3. 查询完成后,镜像引用会被改写为按 digest 引用的形式(steps[i].Image = ref.Context().Digest(...)),保证可复现性。
  4. EntrypointCache的实际实现见 pkg/pod/entrypoint_lookup_impl.go,其单元测试在 pkg/pod/entrypoint_lookup_test.go 与 pkg/pod/entrypoint_lookup_impl_test.go。

也就是说,imagePullSecrets在这一场景下不仅决定 kubelet 拉镜像时的凭据,还直接决定了 Controller 能否成功解析镜像入口点——若 Controller 无权读取对应 Secret,任务会因 entrypoint 解析失败而无法启动。

Affinity Assistant Pod 模板

使用 Workspaces 时,Tekton 会创建 Affinity Assistant Pod 来协助调度。你在TaskRun和PipelineRun中指定的 Pod 模板同样适用于这些 Affinity Assistant Pod,但只作用于部分字段。

Affinity Assistant Pod 支持的字段仅限于:tolerations、nodeSelector、securityContext、priorityClassName与imagePullSecrets(含义见上表)。

与全局 Pod 模板类似,你也可以在 Tekton 配置中通过default-affinity-assistant-pod-template键定义全局 Affinity Assistant Pod 模板(见 additional-configs.md),其合并策略与上文描述的default-pod-template一致(仅针对上述受支持字段)。

源码层面的对应实现

在 pkg/apis/pipeline/pod/template.go 中:

  • Template.ToAffinityAssistantTemplate()方法(第 168~180 行)将完整模板裁剪为仅含NodeSelector、Tolerations、ImagePullSecrets、SecurityContext、PriorityClassName的AffinityAssistantTemplate——这正是“只作用于部分字段”的代码级体现。
  • MergeAAPodTemplateWithDefault实现 Affinity Assistant 模板与全局默认模板的合并,规则与MergePodTemplateWithDefault相同(运行级覆盖全局级)。

小结与实践建议

  • 职责分层:把“集群级基线”(默认节点选择、默认安全上下文、默认镜像拉取凭据)放进config-defaults的default-pod-template;把“任务级特例”写在TaskRun/PipelineRun的podTemplate中,运行级字段优先。
  • 动态调度:利用taskRunSpecs+$(params.xxx)参数替换,配合 Matrix 实现按架构、按环境动态选择节点与容忍度,无需为每个组合手写 Pod 模板。
  • 安全默认:runAsNonRoot、hostUsers: false(需集群启用UserNamespacesSupport)、显式imagePullSecrets等都是值得优先纳入模板的字段。
  • 权限联动:若 Task 镜像不带command且依赖私有镜像,请确保 Tekton Controller 的 ServiceAccount 具备读取目标命名空间 Secret 的权限,否则 entrypoint 解析会失败。

如需进一步深入,可继续阅读 docs/taskruns.md、docs/pipelineruns.md、docs/additional-configs.md 与 docs/workspaces.md。

  • 云原生
  • CI/CD
  • DevOps
  • 后端

【免费下载链接】pipeline

A cloud-native Pipeline resource.

项目地址:https://gitcode.com/gh_mirrors/pipelin/pipeline
点击查看免费下载
上一篇:微信聊天记录永久保存指南:如何让珍贵对话永不丢失?
下一篇:react-native-router-flux 路由文档未来:沉浸式体验

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询