- 适用套餐:Free、Premium、Ultimate
- 适用服务:GitLab.com、GitLab Self-Managed、GitLab Dedicated
GitLab 提供了多种工具,帮助你更方便地调试 CI/CD 配置。
如果无法解决流水线问题,可以向以下渠道求助:
- GitLab 社区论坛
- GitLab 支持
如果问题与某项具体的 CI/CD 功能有关,请查看该功能对应的故障排查章节:
- 缓存
- CI/CD 作业令牌
- 容器镜像仓库
- Docker
- 下游流水线
- 环境
- GitLab Runner
- ID 令牌
- 作业
- 作业制品
- 合并请求流水线、合并结果流水线和合并列车
- 流水线编辑器
- 变量
- YAML 的 includes 关键字
- YAML 的 script 关键字
调试方法
验证语法
最先需要排查的常见问题是语法错误。如果发现语法或格式问题,流水线会显示 yaml invalid 标记,并且不会开始运行。
使用流水线编辑器编辑 .gitlab-ci.yml
推荐使用流水线编辑器,而不是单文件编辑器或 Web IDE。它提供以下功能:
- 代码补全建议,帮助确保只使用受支持的关键字。
- 自动语法高亮和验证。
- CI/CD 配置可视化,以图形方式展示 .gitlab-ci.yml 文件。
在本地编辑 .gitlab-ci.yml
如果更喜欢在本地编辑流水线配置,可以在编辑器中使用 GitLab CI/CD Schema 检查基本语法。支持 Schemastore 的编辑器默认会使用 GitLab CI/CD Schema。
如果需要直接链接到 Schema,请使用以下 URL:
https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/editor/schema/ci.json
CI/CD Schema 支持的全部自定义标签,可以在最新版 Schema 中查看。
使用 CI Lint 工具验证语法
可以使用 CI Lint 工具验证 CI/CD 配置片段的语法。粘贴完整的 .gitlab-ci.yml,或只粘贴单个作业配置,即可检查基本语法。
当项目中已经存在 .gitlab-ci.yml 时,还可以用 CI Lint 模拟完整流水线的创建,对配置语法进行更深入的验证。
为流水线命名
使用 workflow:name 为每种流水线设置名称,便于在流水线列表中识别。例如:
variables:
PIPELINE_NAME: "Default pipeline name"
workflow:
name: '$PIPELINE_NAME'
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
variables:
PIPELINE_NAME: "Merge request pipeline"
- if: '$CI_PIPELINE_SOURCE == "schedule" && $PIPELINE_SCHEDULE_TYPE == "hourly_deploy"'
variables:
PIPELINE_NAME: "Hourly deployment pipeline"
- if: '$CI_PIPELINE_SOURCE == "schedule"'
variables:
PIPELINE_NAME: "Other scheduled pipeline"
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
variables:
PIPELINE_NAME: "Default branch pipeline"
- if: '$CI_COMMIT_BRANCH =~ /^\d{1,2}\.\d{1,2}-stable$/'
variables:
PIPELINE_NAME: "Stable branch pipeline"
CI/CD 变量
核对变量
CI/CD 故障排查的关键步骤之一,是确认流水线中实际存在哪些变量,以及它们的值。大量流水线配置依赖变量,因此核对变量是快速定位问题来源的方法之一。
导出每个有问题的作业所能访问的完整变量列表。确认预期的变量是否存在,变量值是否符合预期。
通过变量向命令行工具添加选项
可以定义在标准流水线运行时不使用、但需要时可用于调试的 CI/CD 变量。添加变量后,在手动运行流水线或单个作业时设置其值,就能改变命令行为。例如:
my-flaky-job:
variables:
DEBUG_VARS: ""
script:
- my-test-command $DEBUG_VARS /test-dirs
在这个示例中,DEBUG_VARS 在标准流水线中默认是空值。需要调试作业时,可以手动运行流水线,并将 DEBUG_VARS 设置为 –verbose,以获得更多输出。
依赖项
与依赖相关的问题,也是流水线发生意外行为的常见原因。
核对依赖版本
为了确认作业使用了正确的依赖版本,可以在主要脚本命令执行前输出版本。例如:
job:
before_script:
- node --version
- yarn --version
script:
- my-javascript-tests.sh
固定版本
虽然可能希望始终使用依赖项或镜像的最新版本,但更新有时会意外引入不兼容改动。可以考虑固定关键依赖与镜像版本,避免突如其来的变化。例如:
variables:
ALPINE_VERSION: '3.18.6'
job1:
image: alpine:$ALPINE_VERSION # This will never change unexpectedly
script:
- my-test-script.sh
job2:
image: alpine:latest # This might suddenly change
script:
- my-test-script.sh
仍应定期查看依赖和镜像的更新,因为其中可能包含重要安全修复。之后再通过一个验证流程手动升级,确认更新后的镜像或依赖仍与流水线兼容。
查看作业输出
增加输出详细程度
可以使用 –silent 减少作业日志,但这也可能让问题更难定位。在支持的情况下,考虑使用 –verbose,以显示命令正在执行的更多细节。
job1:
script:
- my-test-tool --silent # If this fails, it might be impossible to identify the issue.
- my-other-test-tool --verbose # This command will likely be easier to debug.
将输出和报告保存为制品
某些工具会生成只在作业运行期间需要的文件,但这些文件的内容可能有助于调试。可以通过 artifacts 将其保存,以供后续分析:
job1:
script:
- my-tool --json-output my-output.json
artifacts:
paths:
- my-output.json
通过 artifacts:reports 配置的报告默认不能下载,但其中也可能包含有助于调试的信息。可以使用相同方法,使这些报告能够下载和查看:
job1:
script:
- rspec --format RspecJunitFormatter --out rspec.xml
artifacts:
reports:
junit: rspec.xml
paths:
- rspec.xmp
不要把令牌、密码或其他敏感信息保存到制品中,因为任何有权访问流水线的用户都可能看到这些内容。
在本地运行作业命令
可以使用 Rancher Desktop 或类似工具,在本地计算机上运行作业使用的容器镜像。然后在容器中执行作业脚本命令,观察其行为。
通过根因分析排查失败作业
可以在 GitLab Duo Chat 中使用 GitLab Duo Root Cause Analysis,排查失败的 CI/CD 作业。
作业配置问题
许多常见流水线问题,可以通过分析 rules 或 only/except 的行为解决。这些配置决定何时将作业加入流水线。不要在同一流水线中混用两套配置,因为它们行为不同,混用后很难预测运行结果。推荐使用 rules 控制作业,因为 only 和 except 已不再积极开发。
如果 rules 或 only/except 使用 CI_PIPELINE_SOURCE、CI_MERGE_REQUEST_ID 等预定义变量,应首先核对这些变量。
作业或流水线没有按预期运行
rules 或 only/except 关键字决定作业是否被加入流水线。如果流水线运行了,但某个作业没有出现,通常是这些配置存在问题。
如果流水线完全没有运行,也没有报错,同样可能与 rules、only/except 或 workflow: rules 配置有关。
如果正在从 only/except 迁移到 rules,应仔细查看 rules 的配置细节。两者行为不同,迁移时可能出现意外结果。
可以参考 rules 的常用 if 条件示例,编写符合预期的规则。
如果流水线只包含 .pre 或 .post 阶段的作业,它不会运行。必须至少有一个位于其他阶段的作业。
.gitlab-ci.yml 包含字节顺序标记时行为异常
.gitlab-ci.yml 或被包含的其他配置文件中存在 UTF-8 字节顺序标记(BOM)时,可能导致流水线行为错误。BOM 会影响文件解析,进而造成部分配置被忽略、作业缺失或变量值错误。某些文本编辑器在特定配置下会自动插入 BOM。
如果流水线行为令人困惑,可以使用能够显示 BOM 的工具检查文件。流水线编辑器无法显示这些字符,必须使用外部工具。更多信息见问题单 354026。
使用 changes 的作业意外运行
作业意外加入流水线的一个常见原因,是 changes 在某些情况下始终返回 true。例如,在定时流水线及标签流水线等类型中,changes 总是为 true。
changes 与 only/except 或 rules 配合使用。建议只在能够确保作业仅加入分支流水线或合并请求流水线的配置中使用它,例如在 rules 中结合 if 条件,或添加相应的 only/except 限制。
同时运行了两条流水线
向一个已经有关联合并请求的分支推送提交时,可能触发两条流水线。通常一条是合并请求流水线,另一条是分支流水线。
这种情况通常由 rules 配置引起,可以通过多种方式避免重复流水线。
流水线没有运行,或运行了错误类型
在流水线开始之前,GitLab 会评估配置中的全部作业,并尝试将它们加入所有适用的流水线类型。如果评估结束后某条流水线中没有作业,它就不会运行。
如果流水线没有运行,很可能是所有作业的 rules 或 only/except 都阻止了它们加入该流水线。
如果运行了错误类型的流水线,应检查 rules 或 only/except,确保作业被加入正确类型。例如,合并请求流水线没有运行时,作业可能被加入了分支流水线。
也可能是 workflow: rules 阻止了目标流水线,或允许了错误类型的流水线。
如果使用拉取镜像同步,可以查看拉取镜像流水线的故障排查说明。
作业过多导致流水线无法启动
流水线中的作业数量如果超过实例配置的 CI/CD 限制,就无法启动。
为了减少单条流水线中的作业数量,可以将 .gitlab-ci.yml 拆分为更多独立的父子流水线。
流水线警告
执行以下操作时,可能显示流水线配置警告:
- 通过 CI Lint 工具验证配置。
- 手动运行流水线。
警告:一个操作可能触发多条流水线
在 rules 中使用不带 if 的 when 条件时,可能运行多条流水线。通常发生在向已有关联合并请求的分支推送提交时。
为避免重复流水线,可以使用 workflow: rules,或重写 rules,明确允许哪些流水线运行。
流水线错误
错误:运行 CI 作业前需要身份验证
- 适用套餐:Free
- 适用服务:GitLab.com
在 GitLab.com 免费套餐中使用 GitLab 托管 Runner 时,如果看到“Identity verification is required in order to run CI jobs”,就必须完成身份验证。
这是为了防止免费计算资源被滥用。根据风险评分,可能需要验证电子邮件地址、电话号码,或添加付款方式。更多信息见身份验证说明。
完成验证的步骤如下:
- 在提示横幅中选择“验证我的账户”(Verify my account)。
- 按照提示完成身份验证,可能需要验证电话号码或添加付款方式。
- 创建新的提交,或手动触发新流水线。
也可以选择其他方式:
- 升级到付费套餐。
- 为命名空间购买额外计算分钟数。
- 使用项目或群组 Runner,替代 GitLab 托管 Runner。
- 请群组所有者配置自管理 Runner。
提示:合并之前必须成功运行 CI/CD 流水线
如果项目启用了“流水线必须成功”(Pipelines must succeed),而流水线尚未成功运行,就会出现此提示。尚未创建流水线,或仍在等待外部 CI 服务时,也会显示。
如果项目不使用流水线,应禁用“流水线必须成功”,以便接受合并请求。
提示:正在检查能否自动合并
如果合并请求一直停留在“Checking ability to merge automatically”,几分钟后仍未消失,可以尝试以下办法:
- 刷新合并请求页面。
- 关闭后重新打开合并请求。
- 使用 /rebase 快捷操作,对合并请求进行变基。
- 如果已经确认合并请求可以合并,可以使用 /merge 快捷操作完成合并。
提示:正在检查流水线状态
如果合并请求的最新提交尚未关联流水线,会显示此消息及旋转状态图标。可能原因包括:
- GitLab 尚未完成流水线创建。
- 使用外部 CI 服务,而 GitLab 尚未收到其回复。
- 项目没有使用 CI/CD 流水线。
- 项目使用 CI/CD,但配置阻止了合并请求源分支上的流水线运行。
- 最新流水线已被删除,这是一个已知问题。
- 合并请求源分支位于私有派生仓库中。
创建流水线后,消息会更新为相应状态。
在某些情况下,如果启用了“流水线必须成功”,消息可能一直停留,图标不断旋转。更多信息见问题单 334281。
提示:找不到项目或无权访问
通过 include 添加配置时,如果出现以下任一情况,会显示“Project <group/project> not found or access denied”:
- 配置引用的项目不存在或找不到。
- 运行流水线的用户无法访问某个被包含的项目。
要解决这个问题,请确认:
- 项目路径采用 my-group/my-project 格式,不包含仓库中的文件夹路径。
- 运行流水线的用户是包含配置文件的项目成员,并且在这些项目中具有运行 CI/CD 作业的权限。
提示:解析后的 YAML 过大
当 YAML 配置过大或嵌套过深时,会出现“The parsed YAML is too big”。包含大量 include、总行数达到数千行的 YAML 更容易触及内存限制。例如,大小为 200 KB 的 YAML 文件可能达到默认内存上限。
可以通过以下方式缩减配置:
- 在流水线编辑器的“完整配置”(Full configuration)标签页查看展开后的配置长度,寻找可以删除或简化的重复配置。
- 将较长或重复的 script 内容移到项目中的独立脚本文件。
- 使用父子流水线,把部分工作移到独立子流水线的作业中。
在 GitLab Self-Managed 中,还可以提高大小限制。
编辑 .gitlab-ci.yml 时出现 500 错误
如果包含的配置文件形成循环引用,通过网页编辑器编辑 .gitlab-ci.yml 时可能出现 500 错误。
请确保被包含的配置文件之间没有循环引用。
提示:无法拉取镜像
Runner 在 CI/CD 作业中尝试拉取容器镜像时,可能返回“Failed to pull image”。
当 image 指定的容器镜像来自另一个项目的容器仓库时,Runner 会使用 CI/CD 作业令牌进行身份验证。
如果作业令牌设置阻止访问目标项目的容器仓库,Runner 就会报错。
例如:
WARNING: Failed to pull image with policy "always": Error response from daemon: pull access denied for registry.example.com/path/to/project, repository does not exist or may require 'docker login': denied: requested access to the resource is deniedWARNING: Failed to pull image with policy "": image pull failed: rpc error: code = Unknown desc = failed to pull and unpack image "registry.example.com/path/to/project/image:v1.2.3": failed to resolve reference "registry.example.com/path/to/project/image:v1.2.3": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
如果同时满足以下条件,可能发生这些错误:
- 保存镜像的私有项目启用了“限制对此项目的访问”(Limit access to this project)。
- 尝试获取镜像的作业运行在另一个项目中,而该项目未列入镜像项目的允许列表。
要解决此问题,应将所有需要通过 CI/CD 作业获取镜像的项目,加入目标项目的作业令牌允许列表。
尝试使用项目访问令牌访问另一个项目的镜像时,也可能出现这些错误。项目访问令牌仅限于一个项目,不能访问其他项目的镜像;必须改用作用范围适当且更广的令牌类型。
随机或间歇性无法拉取镜像
CI/CD 作业中可能间歇性出现“Failed to pull image”。
当不同用户具有不同镜像访问权限,而 Runner 又缓存镜像时,就可能发生这类问题。机器人用户尤其容易受影响,因为其权限往往与其他项目成员不同。
例如,流水线使用的镜像存放在另一个项目的容器仓库中。如果所有用户都能访问两个项目,就没有问题;但如果机器人等用户无权访问存放镜像的项目,就可能遇到镜像拉取失败。
当 Runner 曾经为有权限的用户成功拉取并缓存镜像时,错误就可能变得间歇性。此时 Runner 本地已经有镜像,无需再次访问目标项目,所以即使没有目标项目权限的用户,也能运行使用该镜像的作业。但如果 Runner 从未拉取或缓存这个镜像,无权访问镜像项目的用户就会收到“Failed to pull image”。
要解决此问题,应确保所有运行流水线的用户,包括机器人用户,都能访问提供镜像的项目。
运行流水线时显示服务端错误或 500
可能遇到以下流水线错误:
- 推送提交或创建合并请求时,显示“Something went wrong on our end”。
- 通过 API 触发流水线时出现 500 错误。
如果项目导入后内部 ID 记录不同步,就可能出现这些错误。
解决方法可参考问题单 352382 中的变通方案。
错误:配置应为哈希对象数组
在数组中使用多个 !reference 标签时,可能出现类似下面的“config should be an array of hashes”错误:
This GitLab CI configuration is invalid: jobs:my_job_name:parallel:matrix config should be an array of hashes.
script、rules 和 stages 支持多个引用标签,但其他需要数组的关键字不支持。可以通过嵌套规避这一限制,或者改用 YAML 锚点。
错误:作业配置必须包含 trigger 或 needs:pipeline
如果 .gitlab-ci.yml 中某个作业使用了 needs,但没有使用 script: 或 trigger:,就可能出现“jobs:<job-name> config should contain either a trigger or a needs:pipeline.”。
每个作业都必须使用 script 或 trigger,因此应为缺少这两者的作业添加适当关键字。
错误:配置包含未知键
可能看到类似“<keyword> config contains unknown keys: <key-name>”的错误。
可能原因包括:
- 关键字拼写错误,例如把合法的 image 写成无效的 imag。
- 关键字或作业的空格及缩进不正确。
例如:
test-job:
artifacts:
path: # This is a typo, it should be `paths`
- test
image: test # This indentation is incorrect, it should be at the same level as `script`.
script:
- echo
原文:Debugging CI/CD pipelines。作者/来源:GitLab 文档贡献者。本文依据所列原文整理为中文,代码、命令与配置示例保留原文。











暂无评论内容