常见问题

适用于所有用户

本故障排除指南涵盖了 管理员(组件部署、配置)和 普通用户(仓库设置、pipeline 执行)可能遇到的问题。

重要:在本文档中,我们使用两个不同的 namespace:

  • <pac-namespace>:部署 PAC 组件(controller、watcher、webhook)的 namespace。默认值为 tekton-pipelines,但可以通过 TektonConfig CR 中的 targetNamespace 进行自定义。
  • <namespace>:创建 PipelineRuns 的 namespace。在创建 Repository CR 时指定,可以是集群中的任意 namespace。

请将这些占位符替换为你实际的 namespace 名称。

本文档提供了使用 Pipelines-as-Code(PAC)时遇到的常见问题的故障排除步骤。

开始之前

在排查具体问题之前,请先确认以下基本项:

1. 检查 PAC 组件是否正在运行

验证所有 PAC Pod 都在运行(将 <pac-namespace> 替换为你的 PAC namespace,默认为 tekton-pipelines):

kubectl get pods -n <pac-namespace> | grep pipelines-as-code

示例输出(所有 Pod 都应为 Running):

NAME                                          READY   STATUS    RESTARTS   AGE
pipelines-as-code-controller-769bf5c88c-xxxxx  1/1     Running   0          113d
pipelines-as-code-watcher-546d6cd86d-xxxxx     1/1     Running   15         113d
pipelines-as-code-webhook-5fcd94db5b-xxxxx     1/1     Running   0          113d

2. 确认你的 namespace

获取 PAC namespace(PAC 组件部署所在的 namespace):

kubectl get tektonconfig config -o jsonpath='{.spec.targetNamespace}'

如果命令失败或返回为空,请使用默认值:tekton-pipelines

获取 Pipeline namespace(创建 PipelineRuns 的 namespace):

kubectl get repository -A

这会显示所有 Repository CR 及其 namespace。namespace 列显示 PipelineRuns 将在何处创建。

3. 获取资源名称

获取 Pod 名称:

kubectl get pods -n <pac-namespace> | grep pipelines-as-code

获取 Repository CR 名称:

kubectl get repository -n <namespace>

获取 PipelineRun 名称:

kubectl get pipelinerun -n <namespace>

4. 本文档中使用的常见占位符

  • <pac-namespace>:PAC 部署 namespace(默认值:tekton-pipelines)
  • <namespace>:PipelineRun namespace(因仓库而异)
  • <repo-name>:Repository CR 名称(使用 kubectl get repository -n <namespace> 列出)
  • <pod-name>:Pod 名称(使用 kubectl get pods -n <pac-namespace> 列出)
  • <name>:PipelineRun 名称(使用 kubectl get pipelinerun -n <namespace> 列出)
  • <gitlab-secret>:GitLab token Secret 名称(检查 Repository CR spec)

PAC 组件未部署

症状

OpenShiftPipelinesAsCode CR 显示 Ready: False,Pod 无法启动,或者该 CR 根本不存在。

故障排除步骤

  1. 检查 TektonConfig 是否请求 PAC。operator 会根据 TektonConfig 派生 OpenShiftPipelinesAsCode CR,且仅在 profile 为 all 并且启用 PAC 时才会这样做。如果 CR 完全缺失,请从这里开始:

    kubectl get tektonconfig config \
      -o jsonpath='profile={.spec.profile} enable={.spec.platforms.kubernetes.pipelinesAsCode.enable}{"\n"}'

    预期输出:

    profile=all enable=true

    profile 为 basic 或 lite 表示 operator 根本不会进入 PAC 逻辑——它既不会创建该 CR,也不会删除已存在的 CR。

    enable 为空表示 spec.platforms.kubernetes.pipelinesAsCode 完全缺失。默认值 webhook 会将该块填充为 enable: true,但前提是有东西写入了 TektonConfig;因此,对于自 operator 升级后从未被写回的 TektonConfig,该块仍然缺失。在 profile: all 下——这是唯一会进入 PAC 逻辑的 profile——reconciler 会将这个缺失块视为 PAC 已禁用,并删除派生的 CR。按照 Deploy PAC Component 中所示显式写入该块,既能立刻修复问题,也能让意图在 CR 中保持可见。

  2. 检查 CR 状态:

    kubectl get openshiftpipelinesascodes.operator.tekton.dev pipelines-as-code -o yaml

示例输出(节选):

apiVersion: operator.tekton.dev/v1alpha1
kind: OpenShiftPipelinesAsCode
metadata:
  name: pipelines-as-code
status:
  conditions:
  - status: "False"
    type: Ready
    reason: DeploymentFailed
  1. 检查 CR 事件:

    kubectl describe openshiftpipelinesascodes.operator.tekton.dev pipelines-as-code

示例输出(节选):

Name:         pipelines-as-code
Status:       False
Events:
Type     Reason           Age   From              Message
----     ------           ----  ----              -------
Warning  DeploymentFailed 5m    tekton-operator   Failed to deploy PAC component
  1. 检查 TektonInstallerSet:

    kubectl get tektoninstallersets | grep openshiftpipelinesascode
    kubectl describe tektoninstallerset <name>

    注意:TektonInstallerSet 是 cluster-scoped 资源。此处的检查仅用于故障排除且为只读操作。不要直接修改或删除它。如果问题仍然存在,请通过 TektonConfig 和派生的 OpenShiftPipelinesAsCode CR 进行排查。

示例输出:

NAME                                             AGE
openshiftpipelinesascode-main-deployment-4bzwx   153d
openshiftpipelinesascode-main-static-s7qn2       153d
openshiftpipelinesascode-post-cdwjw              153d
  1. 检查 operator 日志:

    kubectl logs -n <pac-namespace> -l app=tekton-operator --tail=100

示例输出(日志示例):

{"level":"error","ts":"2024-01-01T12:00:00Z","logger":"operator","msg":"Failed to deploy PAC","error":"..."}

常见原因

  • TektonConfig 中未请求 PAC:profile 不是 all,或者 profile 是 all 但 spec.platforms.kubernetes.pipelinesAsCode 缺失或 enable: false。这通常是 CR 缺失而不是未就绪的原因。这两种情况不同:在 basic 或 lite 下,operator 从不创建该 CR,也不会触碰已存在的 CR;而在 all 下,缺失的块或 enable: false 会导致它删除该 CR。缺失块的情况在原地升级后很容易出现,因为该块只有在有东西写入 TektonConfig 时才会被填充
  • operator 未运行:检查 Tekton Operator 状态
  • namespace 问题:确认 targetNamespace 存在
  • 资源冲突:检查是否存在已有资源

解决方案

  1. 在 TektonConfig 中设置 spec.profile: all 和 spec.platforms.kubernetes.pipelinesAsCode.enable: true
  2. 确保 Tekton Operator 正在运行
  3. 检查 namespace 是否存在(将 <pac-namespace> 替换为实际 PAC namespace):kubectl get namespace <pac-namespace>
  4. 如果派生的 CR 处于卡住状态而不是缺失,在 profile: all 且 TektonConfig 中仍启用 PAC 的情况下,删除它——operator 会在下一次 reconcile 时重新创建它。不要在 basic 或 lite 上执行此操作:在那里不会有任何东西重新创建该 CR,因此删除它会永久移除 PAC

PAC Pod 未启动

症状

PAC Pod 处于 Pending 或 CrashLoopBackOff 状态。

故障排除步骤

  1. 检查 Pod 状态(将 <pac-namespace> 替换为你的 PAC namespace):

    kubectl get pods -n <pac-namespace> | grep pipelines-as-code

示例输出:

NAME                                          READY   STATUS             RESTARTS   AGE
pipelines-as-code-controller-769bf5c88c-xxxxx  0/1     CrashLoopBackOff   5          113d
pipelines-as-code-watcher-546d6cd86d-xxxxx    0/1     Pending            0          113d
  1. 检查 Pod 日志:

    先获取 Pod 名称(将 <pac-namespace> 替换为你的 PAC namespace):

    kubectl get pods -n <pac-namespace> | grep pipelines-as-code

    然后检查日志(将 <pod-name> 替换为实际 Pod 名称):

    kubectl logs -n <pac-namespace> <pod-name>

示例输出(错误示例):

Error: failed to start controller: cannot connect to database
  1. 检查 Pod 事件:

    先获取 Pod 名称,然后描述它(将 <pod-name> 替换为实际 Pod 名称):

    kubectl describe pod <pod-name> -n <pac-namespace>

示例输出(节选):

Name:         pipelines-as-code-controller-xxxxx
Status:       CrashLoopBackOff
Events:
Type     Reason     Age   From               Message
----     ------     ----  ----               -------
Warning  Failed     5m    kubelet            Error: ImagePullBackOff
  1. 检查资源限制:

    kubectl get pod <pod-name> -n <pac-namespace> -o yaml | grep -A 5 resources

示例输出:

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 128Mi

自动 webhook 注册失败

症状

在应用 Repository 后,没有创建 GitLab/GitHub webhook,或者 Repository 包含:

metadata:
  annotations:
    pac.tekton.alauda.io/webhook-registration-status: Failed

故障排除步骤

  1. 检查 Repository 注解和事件:

    kubectl describe repository <repo-name> -n <namespace>
    kubectl get repository <repo-name> -n <namespace> \
      -o jsonpath='{.metadata.annotations.pac\.tekton\.alauda\.io/webhook-registration-reason}{"\n"}'
    kubectl get repository <repo-name> -n <namespace> \
      -o jsonpath='{.metadata.annotations.pac\.tekton\.alauda\.io/webhook-registration-message}{"\n"}'
  2. 检查 webhook 注册 controller 日志:

    kubectl logs -n <pac-namespace> \
      -l app=tektoncd-enhancement-controller \
      --tail=100
  3. 验证 PAC webhook URL 来源:

    kubectl get configmap pipelines-as-code-info -n <pac-namespace> \
      -o jsonpath='{.data.controller-url}{"\n"}'

    如果为空,请配置 PAC 公共 URL,并将其记录到 pipelines-as-code-info.data.controller-url 中。请参阅 Get the PAC Webhook URL。

  4. 验证 token 和 webhook Secret 引用:

    kubectl get repository <repo-name> -n <namespace> -o yaml
    kubectl get secret <secret-name> -n <namespace> -o json | jq '.data | keys'
  5. 在使用共享 webhook 管理 token 时检查集中式凭证 Secret 标签:

    kubectl get secret -n <controller-namespace> \
      -l pac.tekton.alauda.io/provider-credential=true \
      --show-labels

自动 webhook 注册失败的常见原因

原因注解含义修复方案
WebhookURLUnavailablecontroller 无法找到公共 PAC webhook URL。通过 TektonConfig 填充 pipelines-as-code-info.data.controller-url。
MissingWebhookSecret实际生效的 spec.git_provider.webhook_secret 缺失,或指向一个缺失/为空的 key。在 Repository namespace 中添加 webhook_secret.name 和 key webhook.secret,或者从 PAC 全局 Repository 继承它。继承的 Secret 会从全局 Repository namespace 读取。
MissingCredential未找到可用的 provider token。在 Repository namespace 中添加 spec.git_provider.secret,从 PAC 全局 Repository 继承它,或者在 webhook 注册 controller namespace 中添加一个与之匹配的集中式 Secret。继承的 Secret 会从全局 Repository namespace 读取。
AmbiguousCredential有多个集中式 Secret 与相同的 provider 类型和 URL 匹配。只保留一个匹配的 Secret,或调整 pac.tekton.alauda.io/provider-url。
ProviderAPIErrorGitLab/GitHub API 返回了错误。检查 token 权限、git_provider.url、provider 可达性以及 CA 信任。对于集中式 webhook 注册,GitHub 需要 admin:repo_hook 或 Webhooks 写权限,GitLab 需要 api scope,并且用户必须具有 administrator 或 Maintainer/Owner 项目访问权限。
NoGitProviderRepository 没有本地 spec.git_provider,或者实际 provider 类型为空且无法推断。为 Webhook 模式添加本地 spec.git_provider 块。将 type 设置为 github 或 gitlab,从 PAC 全局 Repository 继承它,或者提供一个明确的公共 GitHub/GitLab URL,或 /api/v3 / /api/v4 API URL。GitHub App 模式不使用自动 webhook 注册。
UnsupportedProvidercontroller 仅支持 GitLab 和 GitHub Webhook 模式。使用手动注册或其他受支持的集成模式。

说明

  • 会优先尝试 Repository 本地 token。如果返回 401 或 403,controller 会使用匹配的集中式 Secret 重试。
  • 集中式凭证 Secret 从 webhook 注册 controller namespace 中读取;controller 不会在每个 Repository namespace 中搜索集中式凭证。
  • 直接使用 Repository Secret 不需要标签。controller 只会监视实际生效的 Repository spec 所引用的 Secret namespace/name 对,并在这些 Secret 变化时重新协调相关 Repository。
  • 保持 Repository 本地 token 的作用域仅限于正常 PAC 访问。启用自动 webhook 注册时,请将 webhook 管理权限存储在集中式凭证中。
  • PAC 全局 Repository 的 git_provider 设置仅适用于带有本地 spec.git_provider 块的 Repository。仅有 spec.url 的 Repository 会被自动 webhook 注册跳过。
  • 注解 pac.tekton.alauda.io/webhook-managed-ref 存储 provider hook ID。当 PAC webhook URL 发生变化但 provider 和 repository 身份保持不变时,controller 会根据 ID 更新已记录的 hook,而不是创建重复项。
  • 更新 spec.url 会为新 repository 注册 webhook,但不会删除旧 repository 上的 webhook。如果不再需要,请手动删除旧的 provider webhook。
  • 删除 Repository 会尽最大努力清理已记录的受管 webhook。清理失败会被记录并作为事件发出,但不会阻止 Repository finalizer 的移除。如果凭证已被移除或 provider API 不可达,请手动检查 provider 侧的 webhook。
  • 全局禁用自动注册,或者为 Repository 添加 pac.tekton.alauda.io/webhook-registration-disabled: "true",会在 controller 将 Repository 标记为 inactive 之前删除已记录的受管 webhook。如果由于缺少凭证或 provider 访问不可用而导致清理失败,controller 会保留受管注解和 finalizer,并在凭证或 provider 访问恢复后重试。
  • 为 Repository 添加标签 pac.tekton.alauda.io/webhook-registration-disabled: "true",可跳过该 Repository 的自动 webhook 注册。

webhook 不接收事件

症状

GitLab webhook 事件未到达 PAC,pipeline 未触发。

故障排除步骤

  1. 检查 GitLab 中的 webhook 配置:

    • 进入 GitLab 项目 → Settings → Webhooks
    • 验证 webhook URL 是否正确
    • 检查 webhook secret 是否与 Repository CR 匹配
  2. 检查 PAC controller 日志(将 <pac-namespace> 替换为你的 PAC namespace):

    kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100

示例输出(日志示例):

{"level":"info","ts":"2024-01-01T12:00:00Z","logger":"controller","msg":"Received webhook event"}
{"level":"error","ts":"2024-01-01T12:00:01Z","logger":"controller","msg":"Webhook validation failed","error":"invalid signature"}
  1. 从 GitLab 测试 webhook:

    • 进入 GitLab 项目 → Settings → Webhooks
    • 单击 "Test" → "Push events"
    • 检查 webhook 响应
  2. 验证 controller URL 可访问:

    # If using Gateway API
    curl -i http://pac.example.com/
    # If DNS is not ready yet, resolve the host to the Envoy Gateway external IP:
    # curl -i --resolve "pac.example.com:80:<gateway-external-ip>" http://pac.example.com/

示例输出:

HTTP/1.1 200 OK
Content-Type: text/plain
# 如果使用 Ingress
curl -i http://pac.example.com/

示例输出:

HTTP/1.1 200 OK
Content-Type: text/plain
# If using NodePort
curl -i http://<node-ip>:<node-port>/

示例输出:

HTTP/1.1 200 OK
Content-Type: text/plain
  1. 检查 Repository CR:

    先列出所有 Repository CR 以找到名称(将 <namespace> 替换为你的 Pipeline namespace):

    kubectl get repository -n <namespace>

    然后检查特定的 Repository CR(将 <repo-name> 替换为实际的 repository 名称):

    kubectl get repository <repo-name> -n <namespace> -o yaml

示例输出(节选):

apiVersion: pipelinesascode.tekton.dev/v1alpha1
kind: Repository
metadata:
  name: my-repo
spec:
  git_provider:
    type: gitlab
    webhook_secret:
      name: webhook-secret
      key: secret

常见原因

  • controller URL 不可访问:防火墙或网络问题
  • webhook secret 不匹配:GitLab 中的 Secret 与 Repository CR 不一致
  • webhook URL 错误:配置了错误的 controller URL
  • 未配置 Gateway/Ingress/Service:controller 未暴露

解决方案

  1. 验证 GitLab 服务器可以访问 controller URL
  2. 确保 GitLab 和 Repository CR 中的 webhook secret 一致
  3. 检查 Gateway/Ingress/Service 配置
  4. 使用 curl 手动测试 webhook

验证

应用解决方案后,验证修复是否生效:

  1. 从 GitLab 测试 webhook:

    • 进入 GitLab 项目 → Settings → Webhooks
    • 单击 "Test" → "Push events"
    • 检查 webhook 是否返回 200 OK 响应
  2. 检查 PAC controller 日志,确认 webhook 事件:

    kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=50 | grep -i webhook

    你应该能看到表示正在接收 webhook 事件的日志条目。

pipeline 未触发

症状

发生 Git 事件时,没有创建 pipeline。

故障排除步骤

  1. 检查 Pipeline 注解:

    cat .tekton/pipelinerun.yaml | grep pipelinesascode.tekton.dev

示例输出:

pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
  1. 验证分支名称是否匹配:

    git branch --show-current
    git log --oneline -1

示例输出:

main
abc1234 Test commit
  1. 检查 PAC controller 日志:

    kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100 | grep -i trigger

示例输出(日志示例):

{"level":"info","ts":"2024-01-01T12:00:00Z","logger":"controller","msg":"Processing trigger","branch":"main","event":"push"}
{"level":"warn","ts":"2024-01-01T12:00:01Z","logger":"controller","msg":"Branch mismatch","expected":"main","actual":"develop"}
  1. 检查 Repository CR 状态:

    先列出 Repository CR 以找到名称:

    kubectl get repository -n <namespace>

    然后检查 Repository CR(将 <repo-name> 替换为实际的 repository 名称):

    kubectl get repository <repo-name> -n <namespace> -o yaml
    kubectl describe repository <repo-name> -n <namespace>

示例输出(节选):

Name:         my-repo
Namespace:    project-pipelines
Status:       Ready
Events:
Type    Reason   Age   From     Message
----    ------   ----  ----     -------
Normal  Ready    5m    pac      Repository validated
  1. 验证 pipeline 文件是否存在:

    git ls-files .tekton/

示例输出:

.tekton/pipelinerun.yaml

常见原因

  • 注解语法错误:注解格式不正确
  • 分支名称不匹配:分支模式与实际分支不一致
  • 未找到 pipeline 文件:文件不在预期位置
  • 路径过滤:变更的文件不符合路径过滤条件
  • 未找到 Repository CR:没有与该 repository 匹配的 Repository CR

解决方案

  1. 验证注解语法:使用 pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]" 和 pipelinesascode.tekton.dev/on-event: "[push]",不要使用已弃用的 on-push 注解
  2. 确保分支名称完全匹配(区分大小写)
  3. 确保 repository 中存在 .tekton/pipelinerun.yaml
  4. 如果配置了路径过滤,请检查其设置
  5. 验证 Repository CR 存在且与 repository URL 匹配

验证

应用解决方案后,验证修复是否生效:

  1. 触发测试事件:

    • 向 pipeline 注解中指定的分支推送一个 commit
    • 或者在测试 MR 触发时创建一个 Merge Request
  2. 检查是否创建了 PipelineRun:

    kubectl get pipelinerun -n <namespace> --sort-by=.metadata.creationTimestamp | tail -5

    Git 事件之后你应该能看到一个新的 PipelineRun 被创建。

  3. 检查 PAC controller 日志:

    kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=50 | grep -i trigger

    查找表示事件已被处理的日志条目。

未创建 PipelineRuns

症状

收到了 webhook 事件,但没有创建 PipelineRun。

故障排除步骤

  1. 检查 PAC controller 日志:

    kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=200

示例输出(错误示例):

{"level":"error","ts":"2024-01-01T12:00:00Z","logger":"controller","msg":"Failed to create PipelineRun","error":"namespaces \"project-pipelines\" not found"}
  1. 检查 Repository CR:

    先列出 Repository CR 以找到名称:

    kubectl get repository -n <namespace>

    然后检查 Repository CR(将 <repo-name> 替换为实际的 repository 名称):

    kubectl get repository <repo-name> -n <namespace> -o yaml
    kubectl describe repository <repo-name> -n <namespace>

示例输出(节选):

apiVersion: pipelinesascode.tekton.dev/v1alpha1
kind: Repository
metadata:
  name: my-repo
spec:
  git_provider:
    type: gitlab
  # ......
  1. 验证 namespace 是否存在:

    kubectl get namespace <namespace>

示例输出:

NAME                STATUS   AGE
project-pipelines   Active   10m

如果 namespace 不存在,你会看到:

Error from server (NotFound): namespaces "project-pipelines" not found
  1. 检查 RBAC 权限:

    kubectl auth can-i create pipelineruns --namespace <namespace>

示例输出:

yes
  1. 检查 GitLab token:

    先从 Repository CR 中找到 Secret 名称:

    kubectl get repository <repo-name> -n <namespace> -o jsonpath='{.spec.git_provider.secret.name}'

    然后检查该 Secret(将 <gitlab-secret> 替换为实际 Secret 名称):

    kubectl get secret <gitlab-secret> -n <namespace> -o yaml

示例输出(节选,token 经过 base64 编码):

apiVersion: v1
kind: Secret
metadata:
  name: gitlab-secret
data:
  token: Z2xwYXQt...

常见原因

  • namespace 不存在:目标 namespace 未创建
  • RBAC 权限:PAC ServiceAccount 缺少权限
  • GitLab token 无效:token 已过期或不正确
  • pipeline 定义错误:YAML 或 Tekton 语法无效
  • repository 访问问题:无法访问 Git repository

解决方案

  1. 如果缺少 namespace,请创建:

    kubectl create namespace <namespace>

示例输出:

namespace/project-pipelines created
  1. 验证 RBAC:检查 ServiceAccount 和 RoleBindings

    检查 PAC 使用哪个 ServiceAccount:

    kubectl get pod -n <pac-namespace> -l app=pipelines-as-code-controller -o jsonpath='{.items[0].spec.serviceAccountName}'

    检查该 ServiceAccount 是否具有所需权限:

    kubectl auth can-i create pipelineruns --namespace <namespace> --as=system:serviceaccount:<pac-namespace>:<service-account-name>
  2. 如果 GitLab token 已过期,请更新它

  3. 校验 pipeline YAML 语法

  4. 测试 GitLab token:

    curl --header "PRIVATE-TOKEN: <token>" "https://gitlab.com/api/v4/user"

示例输出(如果 token 有效):

{
  "id": 1,
  "username": "user",
  "email": "user@example.com"
}

如果 token 无效:

{"message":"401 Unauthorized"}

验证

应用解决方案后,验证修复是否生效:

  1. 触发一个 Git 事件(push 或创建 MR),并检查是否创建了 PipelineRun:

    kubectl get pipelinerun -n <namespace> --sort-by=.metadata.creationTimestamp | tail -1
  2. 检查 PipelineRun 状态:

    kubectl describe pipelinerun <name> -n <namespace>

    PipelineRun 应该已创建并开始执行。

找不到 task

症状

PipelineRun 失败并报出 "task not found" 错误。

故障排除步骤

  1. 检查 PipelineRun 状态:

    先列出 PipelineRuns 以找到名称:

    kubectl get pipelinerun -n <namespace>

    然后检查该 PipelineRun(将 <name> 替换为实际 PipelineRun 名称):

    kubectl get pipelinerun <name> -n <namespace> -o yaml
    kubectl describe pipelinerun <name> -n <namespace>

示例输出(节选,显示错误):

status:
  conditions:
  - status: "False"
    type: Succeeded
    reason: TaskNotFound
  taskRuns:
    task-run-name:
      status:
        conditions:
        - message: 'Task "my-task" not found'
  1. 检查 Task 引用:

    cat .tekton/pipelinerun.yaml | grep -A 5 taskRef

示例输出:

taskRef:
  name: my-task
  kind: Task
  1. 验证 Task 是否存在:

    # For local tasks
    kubectl get task <task-name> -n <namespace>

示例输出(如果 task 存在):

NAME       AGE
my-task    10m

如果 task 不存在:

Error from server (NotFound): tasks.tekton.dev "my-task" not found
# For DevOps Hub catalog tasks
curl http://artifacthub-shim-api.artifacthub-shim-system.svc.cluster.local/api/v1/packages/tekton-task/catalog/<task-name>

示例输出(如果 task 存在):

{
  "id": 1,
  "name": "git-clone",
  "kind": "Task",
  "catalog": {
    "id": 1,
    "name": "Tekton"
  }
}
  1. 检查网络连通性:

    # Test artifacthub-shim access
    curl http://artifacthub-shim-api.artifacthub-shim-system.svc.cluster.local/api/v1/packages/tekton-task/catalog/git-clone

示例输出(如果可访问):

{"id":1,"name":"git-clone",...}
# 测试远程 URL 访问
curl <remote-task-url>

示例输出(如果可访问):

apiVersion: tekton.dev/v1
kind: Task
...

常见原因

  • Task 名称错误:task 名称拼写错误
  • Task 不在当前 namespace:Task 定义在其他 namespace 中
  • DevOps Hub 不可用:访问 artifacthub-shim 时存在网络问题
  • 远程 URL 不可访问:无法从远程 URL 获取 task
  • Task resolver 错误:resolver 配置不正确

解决方案

  1. 验证 task 名称拼写
  2. 检查 task 是否存在于正确的 namespace 中
  3. 测试 artifacthub-shim 连通性
  4. 验证远程 URL 可访问
  5. 检查 task resolver 配置

变量未解析

症状

像 {{revision}} 这样的 pipeline 变量没有被替换。

故障排除步骤

  1. 检查变量语法:

    cat .tekton/pipelinerun.yaml | grep -E "\{\{|\}\}"

示例输出:

revision: {{revision}}
repo_url: {{repo_url}}
  1. 使用 Dry-Run 验证 YAML 语法:

    使用 kubectl apply --dry-run=client 验证 PipelineRun YAML 语法并尽早捕获错误:

    kubectl apply --dry-run=client -f .tekton/pipelinerun.yaml -n <namespace>

示例输出(如果语法有效):

pipelinerun.tekton.dev/my-pipeline created (dry run)

示例输出(如果存在语法错误):

error: error validating ".tekton/pipelinerun.yaml": error validating data: [ValidationError(PipelineRun.spec): unknown field "invalid-field" in tekton.dev.v1.PipelineRun.spec, ...]

注意:此 dry-run 检查会验证 YAML 语法和 Tekton schema,但不会验证变量解析(如 {{revision}} 这类变量在 dry-run 中仍会保持字面字符串)。对于变量解析问题,请检查 PAC controller 日志。

  1. 检查 PAC controller 日志:

    kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100 | grep -i variable

示例输出(日志示例):

{"level":"warn","ts":"2024-01-01T12:00:00Z","logger":"controller","msg":"Unknown variable","variable":"{{Revision}}"}
  1. 验证变量名称:

    • {{revision}} - 正确
    • {{Revision}} 或 {{REVISION}} - 错误(区分大小写)
    • 使用双大括号:{{variable_name}}
  2. 检查 PipelineRun 参数:

    先获取 PipelineRun 名称:

    kubectl get pipelinerun -n <namespace>

    然后检查参数(将 <name> 替换为实际 PipelineRun 名称):

    kubectl get pipelinerun <name> -n <namespace> -o jsonpath='{.spec.params}'

示例输出:

[
  {
    "name": "revision",
    "value": "abc1234"
  },
  {
    "name": "repo_url",
    "value": "https://gitlab.com/user/repo"
  }
]

常见原因

  • 语法错误:缺少大括号或格式不正确
  • 大小写敏感:变量名区分大小写
  • 变量不可用:当前事件类型无法使用该变量(例如,{{pull_request_number}} 只适用于 pull_request 事件)
  • PAC 版本:较旧的 PAC 版本可能不支持某些变量

解决方案

  1. 验证变量语法:使用 {{variable_name}} 格式,例如 {{revision}} 或 {{repo_url}}
  2. 检查变量名称是否正确(区分大小写):{{repo_owner}}、{{source_branch}}、{{pull_request_number}}
  3. 确保该变量可用于对应事件类型:某些变量如 {{pull_request_number}} 仅适用于 pull_request 事件
  4. 如有需要,将 PAC 更新到最新版本

有关可用变量的完整列表,请参阅 Parameterizing Commits and URLs。

验证

应用解决方案后,验证修复是否生效:

  1. 检查已创建的 PipelineRun 中变量是否已解析:

    kubectl get pipelinerun <name> -n <namespace> -o jsonpath='{.spec.params}' | jq .

    变量应被替换为实际值(例如,{{revision}} 应替换为 commit SHA)。

  2. 检查 PAC controller 日志,确认变量解析:

    kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=50 | grep -i variable

    不应出现关于未知变量的警告。

未向 GitLab 报告状态

症状

pipeline 执行成功,但状态没有显示在 GitLab 中。

故障排除步骤

  1. 检查 PAC watcher 日志:

    kubectl logs -n <pac-namespace> -l app.kubernetes.io/name=watcher --tail=100

示例输出(日志示例):

{"level":"error","ts":"2024-01-01T12:00:00Z","logger":"watcher","msg":"Failed to update status","error":"401 Unauthorized"}
  1. 检查 GitLab token:

    先从 Repository CR 中找到 Secret 名称:

    kubectl get repository <repo-name> -n <namespace> -o jsonpath='{.spec.git_provider.secret.name}'

    然后检查该 Secret(将 <gitlab-secret> 替换为实际 Secret 名称):

    kubectl get secret <gitlab-secret> -n <namespace> -o yaml

示例输出(节选,token 经过 base64 编码):

apiVersion: v1
kind: Secret
metadata:
  name: gitlab-secret
data:
  token: Z2xwYXQt...
  1. 测试 GitLab API 访问:

    TOKEN=$(kubectl get secret <gitlab-secret> -n <namespace> -o jsonpath='{.data.token}' | base64 -d)
    curl --header "PRIVATE-TOKEN: $TOKEN" "https://gitlab.com/api/v4/user"

示例输出(如果 token 有效):

{
  "id": 1,
  "username": "user",
  "email": "user@example.com"
}

如果 token 无效或已过期:

{
  "message": "401 Unauthorized"
}
  1. 检查 Repository CR:

    kubectl get repository <repo-name> -n <namespace> -o yaml

示例输出(节选):

apiVersion: pipelinesascode.tekton.dev/v1alpha1
kind: Repository
metadata:
  name: my-repo
spec:
  git_provider:
    type: gitlab
    secret:
      name: gitlab-secret
      key: token
  1. 验证 PipelineRun 状态:

    列出 PipelineRuns 以找到名称:

    kubectl get pipelinerun -n <namespace>

    然后检查状态(将 <name> 替换为实际 PipelineRun 名称):

    kubectl get pipelinerun <name> -n <namespace>

示例输出:

NAME                    STARTED        DURATION   STATUS
simple-pipeline-xxxxx   5 minutes ago  30s        Succeeded

常见原因

  • GitLab token 无效:token 已过期或不正确
  • token 权限不足:token 缺少所需 scope
  • 网络问题:无法访问 GitLab API
  • PAC watcher 未运行:watcher Pod 未启动
  • Repository CR 配置错误:GitLab 配置不正确

解决方案

  1. 验证 GitLab token 有效且未过期
  2. 确保 token 具有 api scope
  3. 测试 GitLab API 连通性
  4. 检查 PAC watcher Pod 是否正在运行
  5. 验证 Repository CR 的 GitLab 配置

验证

应用解决方案后,验证修复是否生效:

  1. 检查 PAC watcher 日志,确认状态更新成功:

    kubectl logs -n <pac-namespace> -l app.kubernetes.io/name=watcher --tail=50 | grep -i status

    你应该能看到表示状态更新已成功发送的日志条目。

  2. 检查 GitLab UI:

    • 进入你的 GitLab 项目
    • 检查 Merge Request 或 commit
    • 验证 pipeline 状态是否已显示(例如 "passed"、"failed"、"running")
  3. 验证 PipelineRun 已完成:

    kubectl get pipelinerun -n <namespace> --sort-by=.metadata.creationTimestamp | tail -1

    PipelineRun 应显示 Succeeded 或 Failed 状态,并且该状态应反映在 GitLab 中。

注释命令不起作用

症状

像 /retest 这样的注释命令没有触发 pipeline。

故障排除步骤

  1. 检查注解配置:

    cat .tekton/pipelinerun.yaml | grep on-comment

    示例输出:

    pipelinesascode.tekton.dev/on-comment: "retest"
  2. 验证评论格式:

    • 命令必须单独占一行,或位于行首
    • /retest - 正确
    • Please /retest - 错误(命令不在行首)
  3. 检查 PAC controller 日志:

    kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100 | grep -i comment

    示例输出(日志示例):

    {"level":"info","ts":"2024-01-01T12:00:00Z","logger":"controller","msg":"Processing comment command","command":"/retest"}
    {"level":"warn","ts":"2024-01-01T12:00:01Z","logger":"controller","msg":"Comment command not at start of line","comment":"Please /retest"}
  4. 验证 Merge Request 是否存在:

    • 注释命令仅适用于 Merge Request
    • 普通 commit 不可用
  5. 检查 webhook 配置:

    # In GitLab, verify webhook includes "Comments" trigger

常见原因

  • 缺少注解:未配置 on-comment 注解
  • 命令格式:命令不在行首
  • 不在 Merge Request 中:注释命令仅适用于 Merge Request
  • 未配置 webhook:webhook 中未启用 Comments 事件
  • 命令名称不匹配:评论中的命令与注解不一致

解决方案

  1. 添加 on-comment 注解:pipelinesascode.tekton.dev/on-comment: "retest"
  2. 确保命令位于行首
  3. 仅在 Merge Request 中使用命令
  4. 在 GitLab webhook 配置中启用 "Comments"
  5. 命令名称必须完全匹配(区分大小写)

PAC 设置不生效

症状

已将某个设置添加到 TektonConfig.spec.platforms.kubernetes.pipelinesAsCode.settings 并且应用时没有报错,但 PAC 的行为仍然像该设置保持默认值一样。TektonConfig 和派生的 OpenShiftPipelinesAsCode CR 都报告为 ready,没有记录任何事件或错误,而且重新读取 TektonConfig 时显示该 key 已从 settings 中消失。

这只影响 Alauda 扩展设置:custom-console-url-namespace-vars、replace-empty-template-vars-with-empty 和 enable-pull-request-number-on-push-events。

请注意,这里的症状是“默认值正在生效”,而不是“功能缺失”。当 key 在其 ConfigMap 中不存在时,PAC 会回退到该设置的内置默认值,因此关闭一个默认开启的设置与开启一个默认关闭的设置同样会受到影响。

故障排除步骤

下面的命令使用两个占位符。请先在同一个 shell 中设置它们,这样后续命令就可以直接粘贴:

SETTING=custom-console-url-namespace-vars   # the setting you configured
PAC_NS=tekton-pipelines                     # spec.targetNamespace of TektonConfig
  1. 检查该 key 是否仍保留在 TektonConfig 中:

    kubectl get tektonconfig config \
      -o jsonpath="{.spec.platforms.kubernetes.pipelinesAsCode.settings.$SETTING}"

    只有当你把 key 写入 settings 时,这一步才有意义;如果输出为空,则说明 operator 已将其丢弃。如果你已经把 key 移到了 options.configMaps,那么这里输出为空是预期结果——直接进入第 3 步。

  2. 检查派生的 CR。在 profile: all 下——这也正说明了该症状,因为 PAC 正在运行——operator 会将 TektonConfig 中的 settings 复制到该 CR 中,因此这里该 key 也会消失——这一步只能确认复制是否同步,并不是权威检查:

    kubectl get openshiftpipelinesascodes.operator.tekton.dev pipelines-as-code \
      -o jsonpath="{.spec.settings.$SETTING}"
  3. 检查 PAC 实际读取的 ConfigMap。这是权威检查——settings 只描述意图:

    kubectl get configmap pipelines-as-code -n "$PAC_NS" \
      -o jsonpath="{.data.$SETTING}"

    将输出与预期值进行比较。若出现其他值,则表示 PAC 没有使用你的配置。请注意,当你有意将该 key 设置为空字符串时,空输出就是正确结果,例如用于清除你不再需要的映射。

常见原因

  • key 写在 settings 下:operator 的默认值 webhook 会根据上游 Pipelines as Code settings 结构重新生成该 map。Alauda 扩展设置在该结构中没有字段,因此会在保存时被丢弃——静默发生,没有错误也没有事件。这发生在 TektonConfig 本身上,因此该 key 也永远不会进入派生的 CR。
  • key 写在派生的 OpenShiftPipelinesAsCode CR 上:在 profile: all 下,operator 会在下一次 reconcile 时把 settings 和 options 从 TektonConfig 复制回去,因此即使是它本来可能接受的 key,这次修改也会丢失。
  • key 直接写入 ConfigMap:手动编辑在常规 reconcile 中会保留下来,因为 operator 会将其渲染后的 manifest 与一个 hash 注解进行比较,而你的编辑并不会改变该注解。这个比较是按资源进行的,因此不会改变渲染后 ConfigMap 的 PAC 变更——例如 spec.config 或 Deployment 选项——会保留这次编辑。只有当渲染后的 ConfigMap 本身发生变化时,它才会被静默覆盖:对 settings 的任何编辑、对 options.configMaps 的任何编辑、operator 升级,或者 installer set 重建。因此,手动编辑 ConfigMap 看起来像是生效了,但会在不可预测的时刻停止工作。

解决方案

将该 key 移到 TektonConfig 中的 options.configMaps,operator 会按 key 将其合并到 ConfigMap 中,并且不会重写它:

spec:
  platforms:
    kubernetes:
      pipelinesAsCode:
        enable: true
        options:
          disabled: false
          configMaps:
            pipelines-as-code:
              data:
                custom-console-url-namespace-vars: "project=label:cpaas.io/project,cluster=label:cpaas.io/cluster"

然后重复第 3 步,确认该值已到达 ConfigMap。详细信息和完整的 key 列表请参阅 Where to Put Each Setting。

获取帮助

如果你仍然遇到问题:

  1. 查看日志:检查所有组件日志中的错误
  2. 验证配置:再次核对所有配置文件
  3. 检查文档:查看本指南中的 PAC 文档
  4. 回顾故障排除:检查本文档中的其他故障排除章节

下一步