PAC Resolver
适用于普通用户
本指南面向普通用户,介绍如何使用 PAC resolver 从本地仓库、Tekton Hub 和远程 URL 自动解析并嵌入 task 和 pipeline。
本指南说明如何使用 Pipelines as Code (PAC) resolver,从三个来源自动解析并嵌入 task 和 pipeline:仓库中定义的本地 task、来自 Tekton Hub 的远程 task,以及来自远程 Git 仓库或 HTTP URL 的 task。
前提条件
- PAC 组件已部署并正在运行
- 已配置 Repository CR(参见 指南)
- 了解 Tekton PipelineRun 结构
关于 PAC Resolver
PAC resolver 会自动获取远程 task 和 pipeline,并将其嵌入到你的 PipelineRun 定义中。这样就无需在 pipeline 代码中手动定义 task 或使用 resolver 语法。
Task 嵌入的工作方式
当 PAC 从 Tekton Hub 解析 task 时:
- PAC 从 Hub 获取 task 定义(YAML)
- PAC 将
taskRef 转换为 taskSpec,并将 task 定义以内联方式嵌入到你的 PipelineRun 中
- 嵌入的 task 成为 PipelineRun 定义的一部分
- 该 task 无需作为单独的 Task 资源存在于你的集群中
这意味着你可以直接使用 Tekton Hub 中的 task,而无需手动复制其定义或在集群中创建 Task 资源。
支持的来源
- 本地 Task:定义在 Git 仓库中的 Task(使用 taskSpec 或 resolver 语法)
- Tekton Hub:来自 Tekton Hub 目录的 Task 和 pipeline
- 远程 URL:来自远程 Git 仓库或 HTTP URL 的 Task 和 pipeline
PAC Resolver 的工作原理
了解 resolver 的工作流程有助于你排查问题并优化 pipeline 配置。
Resolver 工作流程
当 PAC 处理带有 resolver 注解的 PipelineRun 时,会按以下步骤执行:
- 事件触发:Git 事件(push、pull request 等)触发 PAC controller
- 获取 Pipeline:PAC controller 从你的 Git 仓库中获取 PipelineRun 定义
- 检测注解:PAC controller 扫描注解中的 resolver 指令:
pipelinesascode.tekton.dev/task: "task-name"
pipelinesascode.tekton.dev/task-1: "task-name"
pipelinesascode.tekton.dev/pipeline: "pipeline-name"
- Task 解析:针对每个 task 注解:
- PAC controller 查询 Tekton Hub API(或已配置的 hub URL)
- 获取 task 定义(YAML)
- 验证 task 结构
- Task 嵌入:PAC 将解析后的 task 定义嵌入到 PipelineRun 中:
- PAC 将
taskRef 转换为 taskSpec,并将 task 定义以内联方式嵌入到每个 task 条目中
- 嵌入的 task 成为 PipelineRun 定义的一部分,因此无需作为单独的 Task 资源存在于集群中
- 创建 PipelineRun:PAC 在 Kubernetes 中创建最终的、包含嵌入 task 的 PipelineRun
- 执行:Tekton Pipeline controller 获取该 PipelineRun 并执行
详细示例:逐步解析
让我们通过一个完整示例来了解 resolver 的工作方式:
步骤 1:原始 PipelineRun 定义
你在仓库中定义一个 PipelineRun(.tekton/pipelinerun.yaml):
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
pipelinesascode.tekton.dev/task: "git-clone"
spec:
pipelineSpec:
tasks:
- name: fetch-code
taskRef:
name: git-clone
params:
- name: url
value: "https://github.com/tektoncd/catalog.git"
- name: revision
value: "main"
步骤 2:PAC Controller 处理注解
当发生 push 事件时,PAC controller 会:
-
从 Git 读取 PipelineRun:PAC 从仓库中获取 .tekton/pipelinerun.yaml 文件
-
检测注解:PAC 扫描诸如 pipelinesascode.tekton.dev/task: "git-clone" 的 task 注解
-
解析 task 名称和版本:
- 仅 task 名称(例如
"git-clone"):从 Hub 获取最新版本
- 带版本(例如
"git-clone:0.1"):获取指定版本
- 版本选择:
- 未指定版本 → PAC 向 Hub 查询最新稳定版本
- 已指定版本(格式:
task-name:version)→ PAC 获取该确切版本
- 版本格式遵循语义化版本控制(例如
0.1、0.9、1.2.3)
-
查询 Tekton Hub API:
- Hub URL:默认指向集群内部 Hub(
http://tekton-hub-api.tekton-pipelines:8000/v1)或公共 Hub(https://api.hub.tekton.dev/v1)
- 查询最新版本:PAC 向 Hub 查询当前可用的最新版本
- 查询特定版本:PAC 请求注解中指定的确切版本
- 示例查询:
- 最新:
"git-clone" → Hub 返回最新版本
- 指定版本:
"git-clone:0.1" → Hub 返回 0.1 版本
-
从 Hub 接收 task 定义:Hub 返回完整的 Task YAML:
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: git-clone
spec:
params:
- name: url
description: git url to clone
- name: revision
description: revision to checkout
steps:
- name: clone
image: gcr.io/tekton-releases/git-init
script: |
#!/bin/sh
git clone $(params.url) $(workspaces.output.path)
cd $(workspaces.output.path)
git checkout $(params.revision)
版本选择最佳实践:
- 生产环境:指定确切版本(例如
"git-clone:0.1"),以保证可复现性和稳定性
- 开发/测试:使用最新版本(不带版本后缀),以便自动获得新功能和 bug 修复
- 版本固定:在生产环境中始终固定到具体版本,避免 Hub 更新带来的破坏性变更
- 版本更新:定期以受控方式审查并更新已固定的版本
步骤 3:PAC 将 Task 嵌入到 PipelineRun 中
PAC 通过将 taskRef 转换为 taskSpec,并嵌入解析后的 task 定义来修改 PipelineRun:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
spec:
pipelineSpec:
tasks:
- name: fetch-code
# PAC converts taskRef to taskSpec and embeds the task definition
taskSpec:
params:
- name: url
description: git url to clone
- name: revision
description: revision to checkout
steps:
- name: clone
image: gcr.io/tekton-releases/git-init
script: |
#!/bin/sh
git clone $(params.url) $(workspaces.output.path)
cd $(workspaces.output.path)
git checkout $(params.revision)
params:
- name: url
value: "https://github.com/tektoncd/catalog.git"
- name: revision
value: "main"
步骤 4:在 Kubernetes 中创建 PipelineRun
PAC 在你的集群中创建最终的 PipelineRun。你可以使用以下方式进行验证:
kubectl get pipelinerun my-pipeline -n <namespace> -o yaml
示例输出(已简化,仅显示嵌入的 task):
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
spec:
pipelineSpec:
tasks:
- name: fetch-code
# Task definition is embedded as taskSpec
taskSpec:
params:
- name: url
- name: revision
steps:
- name: clone
image: gcr.io/tekton-releases/git-init
script: |
#!/bin/sh
git clone $(params.url) $(workspaces.output.path)
params:
- name: url
value: "https://gitlab.com/user/repo"
- name: revision
value: "abc1234"
Resolver 时机
重要:Task 解析发生在 PipelineRun 创建到 Kubernetes 之前。这意味着:
- Task 在 pipeline 定义阶段解析,而不是在执行阶段解析
- 如果某个 task 无法解析,PipelineRun 创建将失败
- 你可以通过检查 Kubernetes 中的 PipelineRun YAML 来验证 task 解析结果
- PAC 会缓存已解析的 task 以提升性能
验证 Task 解析
要验证 task 是否正确解析:
-
检查 Kubernetes 中的 PipelineRun:
kubectl get pipelinerun <name> -n <namespace> -o yaml
查看各个 task 中是否存在包含 taskSpec 的嵌入 task:
spec:
pipelineSpec:
tasks:
- name: fetch-code
taskSpec:
params:
- name: url
- name: revision
steps:
- name: clone
image: gcr.io/tekton-releases/git-init
script: |
#!/bin/sh
git clone $(params.url) $(workspaces.output.path)
params:
- name: url
value: "https://gitlab.com/user/repo"
- name: revision
value: "abc1234"
了解 Task 嵌入
PAC 通过在各个 task 中将 taskRef 转换为 taskSpec 来嵌入已解析的 task。task 定义以内联方式嵌入为 PipelineRun 的一部分,遵循标准 Tekton 语法。
-
检查 PAC Controller 日志:
kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100 | grep -i "task.*resolve" # Replace <pac-namespace> with your actual namespace (default: tekton-pipelines)
示例输出(显示 task 解析):
{"level":"info","ts":"2024-01-01T12:00:00Z","logger":"controller","msg":"Resolving task","task":"git-clone","source":"hub"}
{"level":"info","ts":"2024-01-01T12:00:01Z","logger":"controller","msg":"Task resolved successfully","task":"git-clone","version":"0.9"}
{"level":"info","ts":"2024-01-01T12:00:02Z","logger":"controller","msg":"Task embedded in PipelineRun","task":"git-clone","pipelineRun":"my-pipeline"}
-
验证 task 是否被正确引用:
# Check that taskRef.name matches the task name in annotations
kubectl get pipelinerun <name> -n <namespace> -o jsonpath='{.spec.pipelineSpec.tasks[*].taskRef.name}'
示例输出:
-
检查 PipelineRun 是否已成功创建:
kubectl get pipelinerun <name> -n <namespace> -o jsonpath='{.status.conditions[*].type}'
示例输出:
如果 task 解析失败,PipelineRun 可能不会创建,或者会带有包含错误信息的 Failed 条件。
使用本地 Task
本地 task 是直接定义在 Git 仓库中的 task。PAC 支持两种使用本地 task 的方式:
内联 Task 定义(taskSpec)
你可以在 PipelineRun 中使用 taskSpec 直接定义 task:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
spec:
pipelineSpec:
tasks:
- name: build
taskSpec:
steps:
- name: build
image: golang:1.21
script: |
#!/bin/sh
go build -o app ./cmd
- name: test
taskSpec:
steps:
- name: test
image: golang:1.21
script: |
#!/bin/sh
go test ./...
工作方式:
- task 通过
taskSpec 以内联方式定义在 pipeline 中每个 task 内
- 无需外部解析——task 本身就是 PipelineRun 定义的一部分
- 适用于简单、特定于仓库的 task
引用仓库中的 Task 文件
你可以使用 PAC 注解引用存储在仓库中的 task 文件,并使用仓库内 task 的特殊语法。
重要:对于仓库中的 task,请使用 pipelinesascode.tekton.dev/task 或 pipelinesascode.tekton.dev/task-<N> 形式的注解。
仓库结构:
.tekton/
├── pipelinerun.yaml
└── tasks/
├── build-task.yaml
└── test-task.yaml
使用 PAC 注解的 PipelineRun 定义:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
# Reference local tasks using relative paths
pipelinesascode.tekton.dev/task: ".tekton/tasks/build-task.yaml"
pipelinesascode.tekton.dev/task-1: ".tekton/tasks/test-task.yaml"
spec:
pipelineSpec:
tasks:
- name: build
taskRef:
name: build-task
- name: test
taskRef:
name: test-task
runAfter: [build]
工作方式:
- 当你在 task 注解中使用相对路径时,PAC 会自动解析并嵌入仓库中的 task
taskRef.name 中的 task 名称应与 YAML 文件中定义的 task 名称一致
- 这种方式比使用
resolver: git 语法更简单,是 PAC 推荐的方法
何时使用本地 Task
以下情况适合使用本地 task:
- Task 仅适用于你的项目,不适合共享
- 你需要完全控制 task 定义和版本
- Task 会随着代码库频繁变更
- 你希望将 task 和 pipeline 一起纳入版本控制
使用远程 Task 注解
你可以使用 PAC 注解引用来自 Tekton Hub 或远程 HTTP URL 的 task。PAC 会自动获取并将这些 task 嵌入到你的 PipelineRun 中。
来自 Tekton Hub 的远程 Task
引用 Tekton Hub 中的单个 task:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
pipelinesascode.tekton.dev/task: "git-clone"
spec:
pipelineSpec:
tasks:
- name: fetch-code
taskRef:
name: git-clone
params:
- name: url
value: "https://github.com/tektoncd/catalog.git"
- name: revision
value: "main"
工作方式:
- 注解
pipelinesascode.tekton.dev/task: "git-clone" 告诉 PAC 从 Tekton Hub 获取 git-clone task
- PAC 会自动将 task 定义嵌入到你的 PipelineRun 中
- 然后你可以使用
taskRef.name: git-clone 来引用它
来自 HTTP URL 的远程 Task
你也可以引用来自远程 HTTP URL 的 task:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
# Reference task from remote URL
pipelinesascode.tekton.dev/task: "https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.9/git-clone.yaml"
spec:
pipelineSpec:
tasks:
- name: fetch-code
taskRef:
name: git-clone
params:
- name: url
value: "https://github.com/tektoncd/catalog.git"
- name: revision
value: "main"
工作方式:
- PAC 从指定的 HTTP URL 获取 task 定义
- PAC 会自动将 task 嵌入到你的 PipelineRun 中
taskRef.name 中的 task 名称应与远程 YAML 文件中定义的 task 名称一致
多个 Task 注解
使用编号注解引用多个 task:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
pipelinesascode.tekton.dev/task: "git-clone"
pipelinesascode.tekton.dev/task-1: "golangci-lint"
pipelinesascode.tekton.dev/task-2: "buildah"
spec:
pipelineSpec:
tasks:
- name: fetch
taskRef:
name: git-clone
params:
- name: url
value: "https://github.com/tektoncd/catalog.git"
- name: revision
value: "main"
- name: lint
taskRef:
name: golangci-lint
runAfter: [fetch]
- name: build
taskRef:
name: buildah
runAfter: [lint]
Task 列表语法
你也可以使用方括号语法在单个注解中指定多个 task:
metadata:
annotations:
pipelinesascode.tekton.dev/task-1: "[golangci-lint, buildah]"
这等同于:
metadata:
annotations:
pipelinesascode.tekton.dev/task-1: "golangci-lint"
pipelinesascode.tekton.dev/task-2: "buildah"
Task 版本指定
默认情况下,PAC 会从 Hub 获取 task 的最新版本。如果要指定某个特定版本,请使用 task-name:version 格式。
PAC 会按名称解析 Hub task,并可选地通过 task-name:version 固定到某个 task 版本。
最新版本(开发场景推荐):
metadata:
annotations:
pipelinesascode.tekton.dev/task: "git-clone"
特定版本(生产环境推荐):
metadata:
annotations:
pipelinesascode.tekton.dev/task: "git-clone:0.9"
带版本的多个 task:
metadata:
annotations:
pipelinesascode.tekton.dev/task: "git-clone:0.9"
pipelinesascode.tekton.dev/task-1: "golangci-lint:0.4"
pipelinesascode.tekton.dev/task-2: "buildah" # Uses latest
自定义 Hub URL
默认的 hub-url 指向默认命名空间中的集群内部 Tekton Hub 服务(http://tekton-hub-api.tekton-pipelines:8000/v1)。如果 Tekton Hub 部署在其他命名空间中,请相应调整 URL 中的命名空间。如果你需要使用不同的 Hub 实例,请在 OpenShiftPipelinesAsCode CR 中进行配置:
apiVersion: operator.tekton.dev/v1alpha1
kind: OpenShiftPipelinesAsCode
metadata:
name: pipelines-as-code
spec:
settings:
# For cluster-internal Hub in different namespace
hub-url: "http://tekton-hub-api.<your-namespace>:8000/v1"
# Or for external/public Hub
hub-url: "https://api.hub.tekton.dev/v1"
# Or for custom Hub instance
hub-url: "https://custom-hub.example.com/v1"
注意:只有 PAC controller 需要访问 Hub URL。如果使用集群内部 Hub,请确保 PAC controller 可以访问 Hub 服务。
使用远程 Pipeline 注解
使用场景有限
远程 pipeline 注解在实践中很少使用。大多数用户会使用 pipelineSpec 以内联方式定义 pipeline,而不是引用远程 pipeline。本节仅为完整性而包含。
你可以引用来自 Tekton Hub 的远程 pipeline,不过这比使用内联 pipeline 定义更少见:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
# Reference remote pipeline from Tekton Hub
pipelinesascode.tekton.dev/pipeline: "pipeline-name"
spec:
pipelineRef:
name: pipeline-name
params:
- name: image-url
value: "registry.example.com/myapp"
工作方式:
- 注解
pipelinesascode.tekton.dev/pipeline: "pipeline-name" 告诉 PAC 从 Tekton Hub 获取该 pipeline
- PAC 会自动嵌入 pipeline 定义
- 你可以使用
pipelineRef.name 引用它
注意:在大多数情况下,你应在仓库中使用 pipelineSpec 以内联方式定义 pipeline,而不是使用远程 pipeline。这样可以更好地对 pipeline 定义进行版本控制并提高可见性。
组合远程 Task 和 Pipeline
与 Resolver 语法的对比
PAC 注解提供了一种比 Tekton resolver 语法更简单的替代方案:
使用 PAC 注解(推荐)
metadata:
annotations:
pipelinesascode.tekton.dev/task: "git-clone"
spec:
pipelineSpec:
tasks:
- name: clone
taskRef:
name: git-clone
使用 Resolver 语法
spec:
pipelineSpec:
tasks:
- name: clone
taskRef:
resolver: hub
params:
- name: name
value: git-clone
- name: kind
value: task
PAC 注解的优势:
- 语法更简单
- 自动嵌入 task
- 无需指定 resolver 参数
- 与 PAC 的 task 解析机制无缝配合
故障排查
找不到 Task
-
验证 task 名称:检查 Tekton Hub 中的 task 名称是否正确
-
检查 Hub URL:确认 hub URL 配置正确
-
查看 PAC 日志:
kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100 | grep -i task
示例输出:
{"level":"info","ts":"2024-01-01T12:00:00Z","logger":"controller","msg":"Resolving task","task":"git-clone","source":"hub"}
{"level":"info","ts":"2024-01-01T12:00:01Z","logger":"controller","msg":"Task resolved successfully","task":"git-clone","version":"0.9"}
{"level":"info","ts":"2024-01-01T12:00:02Z","logger":"controller","msg":"Task embedded in PipelineRun","task":"git-clone","pipelineRun":"my-pipeline"}
Task 解析失败
-
检查网络连通性:确保 PAC controller 可以访问 Tekton Hub
# Test Hub connectivity from PAC controller pod
kubectl exec -n <pac-namespace> \
$(kubectl get pod -n <pac-namespace> -l app=pipelines-as-code-controller -o jsonpath='{.items[0].metadata.name}') \
-- curl -I https://api.hub.tekton.dev/v1/resource/task/git-clone
示例输出(如果可访问):
HTTP/1.1 200 OK
Content-Type: application/json
-
验证 Hub 配置:检查 OpenShiftPipelinesAsCode CR 中的 hub-url 设置
kubectl get openshiftpipelinesascodes.operator.tekton.dev pipelines-as-code -o jsonpath='{.spec.settings.hub-url}'
示例输出:
http://tekton-hub-api.tekton-pipelines:8000/v1
-
检查 task 版本:确认指定版本是否存在
# Query Tekton Hub for available versions
curl https://api.hub.tekton.dev/v1/resource/task/git-clone
示例输出(已简化):
{
"id": 1,
"name": "git-clone",
"kind": "Task",
"latestVersion": {
"id": 1,
"version": "0.9"
},
"versions": [
{"version": "0.9"},
{"version": "0.8"},
{"version": "0.7"}
]
}
Task 未嵌入
- 验证注解语法:检查注解键和值的格式
- 检查 PipelineRun:确保
taskRef.name 与注解中的 task 名称一致
- 查看 PAC controller 日志,确认是否存在嵌入错误
下一步