PAC 解析器
针对普通用户
本指南面向普通用户,介绍如何使用 PAC 解析器自动解析并嵌入来自本地仓库、Tekton Hub 以及远程 URL 的任务和流水线。
本指南讲解如何使用 Pipelines as Code(PAC)解析器,自动解析并嵌入来自三种来源的任务和流水线:仓库中定义的本地任务、Tekton Hub 的远程任务,以及远程 Git 仓库或 HTTP URL 中的任务。
前提条件
- 已部署并运行 PAC 组件
- 已配置 Repository CR(参见 配置仓库)
- 理解 Tekton PipelineRun 结构
关于 PAC 解析器
PAC 解析器会自动获取并嵌入远程任务和流水线到你的 PipelineRun 定义中,免去了手动定义任务或在流水线代码中使用解析器语法的需求。
任务嵌入工作原理
当 PAC 从 Tekton Hub 解析任务时:
- PAC 从 Hub 获取任务定义(YAML)
- PAC 将
taskRef 转换为 taskSpec,并将任务定义内联嵌入到 PipelineRun 中
- 嵌入的任务成为 PipelineRun 定义的一部分
- 该任务无需作为独立的 Task 资源存在于集群中
这意味着你可以直接使用 Tekton Hub 的任务,而无需手动复制定义或在集群中创建 Task 资源。
支持的来源
- 本地任务:定义在你的 Git 仓库中的任务(使用 taskSpec 或解析器语法)
- Tekton Hub:来自 Tekton Hub 目录的任务和流水线
- 远程 URL:来自远程 Git 仓库或 HTTP URL 的任务和流水线
官方文档
有关 Pipelines as Code 远程解析功能的详细信息,请参阅:
PAC 解析器工作原理
理解解析器的工作流程有助于你排查问题并优化流水线配置。
解析器工作流程
当 PAC 处理带有解析器注解的 PipelineRun 时,执行以下步骤:
- 事件触发:Git 事件(push、pull request 等)触发 PAC 控制器
- 流水线获取:PAC 控制器从你的 Git 仓库获取 PipelineRun 定义
- 注解检测:PAC 控制器扫描注解中的解析器指令:
pipelinesascode.tekton.dev/task: "task-name"
pipelinesascode.tekton.dev/task-1: "task-name"
pipelinesascode.tekton.dev/pipeline: "pipeline-name"
- 任务解析:针对每个任务注解:
- PAC 控制器查询 Tekton Hub API(或配置的 hub URL)
- 获取任务定义(YAML)
- 验证任务结构
- 任务嵌入:PAC 将解析到的任务定义嵌入 PipelineRun:
- PAC 将
taskRef 转换为 taskSpec,并将任务定义内联嵌入每个任务条目
- 嵌入的任务成为 PipelineRun 定义的一部分,无需在集群中存在独立的 Task 资源
- PipelineRun 创建:PAC 在 Kubernetes 中创建最终的 PipelineRun,包含嵌入的任务
- 执行:Tekton Pipeline 控制器拾取并执行该 PipelineRun
详细示例:逐步解析
下面通过一个完整示例,演示解析器的工作过程:
第 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 控制器处理注解
当发生 push 事件时,PAC 控制器:
-
从 Git 读取 PipelineRun:PAC 从仓库获取 .tekton/pipelinerun.yaml 文件
-
检测注解:PAC 扫描类似 pipelinesascode.tekton.dev/task: "git-clone" 的任务注解
-
解析任务名称和版本:
- 仅任务名(如
"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 返回的任务定义: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"),保证可重复性和稳定性
- 开发/测试:使用最新版本(无版本后缀),自动获取新功能和修复
- 版本锁定:生产环境始终锁定具体版本,避免 Hub 更新导致破坏性变更
- 版本更新:定期审查并受控更新锁定版本
第 3 步:PAC 将任务嵌入 PipelineRun
PAC 修改 PipelineRun,将 taskRef 转为 taskSpec 并嵌入解析到的任务定义:
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 将 taskRef 转为 taskSpec 并嵌入任务定义
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 步:PipelineRun 在 Kubernetes 中创建
PAC 在集群中创建最终的 PipelineRun。你可以验证:
kubectl get pipelinerun my-pipeline -n <namespace> -o yaml
示例输出(简略,显示嵌入任务):
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
spec:
pipelineSpec:
tasks:
- name: fetch-code
# 任务定义以 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"
解析器时机
重要:任务解析发生在 PipelineRun 创建到 Kubernetes 之前。这意味着:
- 任务在流水线定义阶段解析,而非执行阶段
- 若任务无法解析,PipelineRun 创建将失败
- 你可以通过查看 Kubernetes 中的 PipelineRun YAML 验证任务解析情况
- PAC 会缓存解析的任务以提升性能
验证任务解析
验证任务是否正确解析:
-
检查 Kubernetes 中的 PipelineRun:
kubectl get pipelinerun <name> -n <namespace> -o yaml
查找每个任务中是否有内联的 taskSpec:
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"
理解任务嵌入
PAC 通过将 taskRef 转换为 taskSpec,将解析到的任务定义内联嵌入到每个任务中,符合标准 Tekton 语法。
-
查看 PAC 控制器日志:
kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100 | grep -i "task.*resolve" # 将 <pac-namespace> 替换为实际命名空间(默认:tekton-pipelines)
示例输出(显示任务解析):
{"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"}
-
验证任务引用是否正确:
# 检查 taskRef.name 是否与注解中的任务名匹配
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}'
示例输出:
若任务解析失败,PipelineRun 可能未创建,或状态为 Failed 并带有错误信息。
使用本地任务
本地任务是直接定义在你的 Git 仓库中的任务。PAC 支持两种方式使用本地任务:
内联任务定义(taskSpec)
你可以在 PipelineRun 中直接使用 taskSpec 定义任务:
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 ./...
工作原理:
- 任务通过
taskSpec 直接内联定义在流水线的每个任务中
- 无需外部解析,任务成为 PipelineRun 定义的一部分
- 适用于简单且特定于仓库的任务
引用仓库中的任务文件
你也可以通过 PAC 注解,使用特殊语法引用仓库中存储的任务文件。
重要:对于仓库中的任务,使用 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]"
# 使用相对路径引用本地任务
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]
工作原理:
- 当任务注解中使用相对路径时,PAC 自动解析并嵌入仓库中的任务
taskRef.name 应与 YAML 文件中定义的任务名一致
- 该方式比使用
resolver: git 语法更简单,是 PAC 推荐的用法
何时使用本地任务
适合使用本地任务的场景:
- 任务特定于项目,不适合共享
- 需要完全控制任务定义和版本
- 任务随代码频繁变更
- 希望任务和流水线一起纳入版本控制
使用远程任务注解
你可以使用 PAC 注解引用来自 Tekton Hub 或远程 HTTP URL 的任务,PAC 会自动获取并嵌入这些任务到 PipelineRun。
来自 Tekton Hub 的远程任务
引用 Tekton Hub 中的单个任务:
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 任务
- PAC 自动将任务定义嵌入 PipelineRun
- 你可以通过
taskRef.name: git-clone 引用该任务
来自 HTTP URL 的远程任务
你也可以引用远程 HTTP URL 中的任务:
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]"
# 引用远程 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 获取任务定义
- 自动将任务嵌入 PipelineRun
taskRef.name 应与远程 YAML 文件中定义的任务名一致
多任务注解
使用编号注解引用多个任务:
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]
任务列表语法
你也可以使用括号语法在单个注解中指定多个任务:
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"
任务版本指定
默认情况下,PAC 从 Hub 获取任务的最新版本。若需指定版本,使用格式 task-name:version。
参考:更多远程任务解析细节,请参阅 Red Hat OpenShift Pipelines as Code 文档。
最新版本(推荐开发环境):
metadata:
annotations:
pipelinesascode.tekton.dev/task: "git-clone"
指定版本(推荐生产环境):
metadata:
annotations:
pipelinesascode.tekton.dev/task: "git-clone:0.9"
多任务带版本:
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" # 使用最新版本
自定义 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:
# 集群内部 Hub(不同命名空间)
hub-url: "http://tekton-hub-api.<your-namespace>:8000/v1"
# 或外部/公共 Hub
hub-url: "https://api.hub.tekton.dev/v1"
# 或自定义 Hub 实例
hub-url: "https://custom-hub.example.com/v1"
注意:只有 PAC 控制器需要访问 Hub URL。若使用集群内部 Hub,确保 PAC 控制器能访问该服务。
使用远程流水线注解
使用场景有限
远程流水线注解在实际中较少使用。大多数用户倾向于使用 pipelineSpec 内联定义流水线,而非引用远程流水线。本节内容为完整性保留。
你可以引用来自 Tekton Hub 的远程流水线,尽管这不如内联定义常见:
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]"
# 引用 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 获取流水线
- PAC 自动嵌入流水线定义
- 你通过
pipelineRef.name 引用该流水线
注意:大多数情况下,建议在仓库中使用 pipelineSpec 内联定义流水线,以便更好地进行版本控制和流水线定义的可见性。
远程任务与流水线的组合使用
与解析器语法的比较
PAC 注解提供了比 Tekton 解析器语法更简单的替代方案:
使用 PAC 注解(推荐)
metadata:
annotations:
pipelinesascode.tekton.dev/task: "git-clone"
spec:
pipelineSpec:
tasks:
- name: clone
taskRef:
name: git-clone
使用解析器语法
spec:
pipelineSpec:
tasks:
- name: clone
taskRef:
resolver: hub
params:
- name: name
value: git-clone
- name: kind
value: task
PAC 注解优势:
- 语法更简单
- 自动任务嵌入
- 无需指定解析器参数
- 与 PAC 任务解析无缝集成
故障排查
任务未找到
-
核实任务名称:确认任务名在 Tekton Hub 中正确
-
检查 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"}
任务解析失败
-
检查网络连通性:确保 PAC 控制器能访问 Tekton Hub
# 从 PAC 控制器 Pod 测试访问 Hub
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
-
检查任务版本:确认指定版本存在
# 查询 Tekton Hub 中可用版本
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"}
]
}
任务未嵌入
- 核实注解语法:检查注解键和值格式是否正确
- 检查 PipelineRun:确保
taskRef.name 与注解中的任务名匹配
- 查看 PAC 控制器日志,排查嵌入错误
后续步骤