调试CI/CD流水线
- 层级:Free、Premium、Ultimate
- 提供方式:GitLab.com、GitLab 自托管、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模式来验证基本语法问题。任何支持Schemastore的编辑器默认都会使用GitLab CI/CD模式。
如果需要直接链接到该模式,请使用此URL:
https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/editor/schema/ci.json要查看CI/CD模式涵盖的自定义标签完整列表,请查看模式的最新版本。
使用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" && $CI_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问题的关键部分之一是验证管道中存在哪些变量及其值。很多管道配置依赖变量,而验证它们是找到问题根源的最快方法之一。
导出所有变量的完整列表,查看有问题的作业中可用的变量。检查预期变量是否存在,以及它们的值是否符合预期。
用变量给CLI命令添加标志
你可以定义在标准管道运行中未使用的CI/CD变量,但可以按需用于调试。如果添加如下示例中的变量,可以在手动运行pipeline或individual job时添加它来修改命令行为。例如:
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 # 这不会意外变更
script:
- my-test-script.sh
job2:
image: alpine:latest # 可能突然变更
script:
- my-test-script.sh你仍应定期检查依赖和镜像的更新,因为可能有重要的安全更新。然后你可以手动更新版本,作为验证更新的镜像或依赖仍适用于你的管道流程的一部分。
验证作业输出
让输出更详细
如果使用--silent减少作业日志的输出量,可能难以识别作业出错的原因。此外,尽可能使用--verbose以获取更多细节。例如:
job1:
script:
- my-test-tool --silent # 若此命令失败,可能无法识别问题。
- my-other-test-tool --verbose # 此命令更易调试。将输出和报告保存为工件
有些工具可能在作业运行期间生成仅临时需要的文件,但这些文件的内容可用于调试。你可以用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或类似替代工具在你的本地机器上运行作业的容器镜像。然后在容器中运行作业的script命令并验证其行为。
用根因分析排查失败作业
你可以使用GitLab Duo聊天中的GitLab Duo根因分析功能来排查失败的CI/CD作业。
作业配置问题
许多常见的流水线问题可通过分析用于控制何时将作业添加到流水线的 rules 或 only/except 配置的行为来解决。你不应在同一流水线中同时使用这两种配置,因为它们的行为不同。很难预测混合使用这两种配置时流水线的运行方式。rules 是控制作业的首选方案,因为 only 和 except 已不再积极开发。
如果你的 rules 或 only/except 配置使用了像 CI_PIPELINE_SOURCE、CI_MERGE_REQUEST_ID 这样的预定义变量,应先将验证这些变量作为故障排查的第一步。
作业或流水线未按预期运行
rules 或 only/except 关键字决定了是否将作业添加到流水线。如果流水线运行了,但某个作业未被添加到流水线中,通常是由于 rules 或 only/except 配置问题引起的。
如果流水线似乎完全没有运行,且没有任何错误信息,这也可能是由于 rules 或 only/except 配置,或是 workflow: rules 关键字导致的。
如果你正在从 only/except 迁移到 rules 关键字,应仔细查看rules 配置详情。only/except 和 rules 的行为不同,在两者之间迁移时可能导致意外行为。
适用于 rules 的常见 if 子句 对于编写符合预期的规则示例非常有帮助。
如果流水线中仅包含 .pre 或 .post 阶段的作业,它不会运行。必须至少有一个位于不同阶段的作业。
当 .gitlab-ci.yml 文件中存在字节顺序标记(BOM)时的意外行为
.gitlab-ci.yml 文件或其他包含的配置文件中的UTF-8 字节顺序标记(BOM) 可能导致不正确的流水线行为。字节顺序标记会影响文件的解析,导致某些配置被忽略——作业可能会丢失,变量的值也可能出错。一些文本编辑器如果在配置中启用了该选项,可能会插入 BOM 字符。
如果你的流水线出现异常行为,你可以使用能够显示这些字符的工具来检查是否存在 BOM 字符。管道编辑器无法显示这些字符,因此你必须使用外部工具。有关更多详细信息,请参阅issue 354026。
带 changes 关键字的作业意外运行
作业被意外添加到流水线的常见原因是 changes 关键字在某些情况下始终为真。例如,在包括定时流水线和标签流水线在内的某些流水线类型中,changes 始终为真。
changes 关键字与 only/except 或 rules 结合使用。建议仅在 rules 的 if 部分或 only/except 配置中使用 changes,以确保作业仅被添加到分支流水线或合并请求流水线。
两个流水线同时运行
当你向关联有开放合并请求的分支推送提交时,可能会有两个流水线同时运行。通常一个流水线是合并请求流水线,另一个是分支流水线。
这种情况通常是由 rules 配置引起的,有几种方法可以避免重复流水线。
没有流水线运行或运行了错误的流水线类型
在流水线运行之前,GitLab 会评估配置中的所有作业,并尝试将它们添加到所有可用的流水线类型。如果在评估结束时没有作业被添加到流水线中,则该流水线不会运行。
如果流水线未运行,很可能是因为所有作业的 rules 或 only/except 都阻止了它们被添加到流水线中。
如果运行了错误的流水线类型,则应检查 rules 或 only/except 配置,确保作业被添加到了正确的流水线类型。例如,如果合并请求流水线未运行,作业可能被添加到了分支流水线中。
也有可能是你的 workflow: rules 配置阻止了流水线,或允许了错误的流水线类型。
如果你在使用拉取镜像,可以查看拉取镜像流水线的故障排除条目。
包含大量作业的流水线无法启动
当流水线的作业数量超过实例定义的CI/CD限制时,该流水线会无法启动。
若要减少单个流水线中的作业数量,你可以将.gitlab-ci.yml配置拆分为更多独立的父级-子级流水线。
流水线警告
当你执行以下操作时,会显示流水线配置警告:
“作业可能允许对单个操作运行多个流水线” 警告
当你使用带有when子句(无if子句)的 rules 时,可能会运行多个流水线。这种情况通常发生在你向关联有开放合并请求的分支推送提交时。
为避免重复流水线,请使用 workflow: rules 或重写规则以控制哪些流水线可以运行。
流水线错误
“合并前必须成功运行CI/CD流水线” 消息
如果项目中启用了Pipelines must succeed 设置,且流水线尚未成功运行,则会显示此消息。若流水线尚未创建,或你在等待外部CI服务响应时,也会出现此情况。
如果你的项目未使用流水线,则应禁用 Pipelines must succeed 以便接受合并请求。
“正在自动检查合并能力” 消息
如果你的合并请求卡在“Checking ability to merge automatically”消息上,且几分钟后仍未消失,可尝试以下解决方法:
- 刷新合并请求页面。
- 关闭并重新打开合并请求。
- 使用
/rebase快速操作 对合并请求进行变基。 - 如果你已确认合并请求已准备好合并,可以使用
/merge快速操作合并它。
此问题已在 GitLab 15.5 中修复。
“正在检查流水线状态” 消息
当合并请求的最新提交尚未关联流水线时,会显示此消息及旋转状态图标( )。原因可能是:
- GitLab 尚未完成流水线创建。
- 你在使用外部CI服务,且GitLab尚未收到服务响应。
- 你的项目未使用CI/CD流水线。
- 你的项目使用了CI/CD流水线,但配置阻止了流水线在合并请求的源分支上运行。
- 最新流水线已被删除(这是一个已知问题)。
- 合并请求的源分支位于私有fork中。
流水线创建后,消息会更新为流水线状态。
在某些情况下,若开启了Pipelines must succeed 设置,消息可能会因图标持续旋转而卡住。详情见issue 334281。
“项目 <group/project> 未找到或访问被拒绝” 消息
当你添加使用 include 的配置时,若出现以下情况会显示此消息:
- 配置引用的项目找不到。
- 运行流水线的用户无法访问任何包含的项目。
解决方法是检查:
- 项目路径格式为
my-group/my-project,且不包含仓库中的文件夹。 - 运行流水线的用户是包含文件所在项目的成员。用户还必须在相同项目中拥有运行CI/CD作业的权限。
“The parsed YAML is too big message”
此消息在YAML配置过大或嵌套过深时显示。 包含大量include且总行数达数千行的YAML文件更易触发此内存限制。例如,一个200 KB的YAML文件很可能达到默认内存限制。
要减小配置大小,你可以:
- 检查流水线编辑器中完整配置标签页下展开的CI/CD配置长度。查找可移除或简化的重复配置。
- 将较长的或重复的
script部分移至项目中独立的脚本里。 - 使用父级与子级流水线,将部分工作转移到独立子流水线的作业中。
在GitLab自托管版中,你可以增大尺寸限制。
“500 error when editing the .gitlab-ci.yml file”
当使用网页编辑器编辑.gitlab-ci.yml文件时,包含的配置文件循环引用可能导致500错误。
确保包含的配置文件不会相互创建循环引用。
“Failed to pull image messages”
当CI/CD作业尝试拉取容器镜像时,Runner可能会返回Failed to pull image消息。
当从另一个项目的容器注册表中获取由image定义的容器镜像时,Runner会使用CI/CD作业令牌进行身份验证。
如果作业令牌设置阻止了对其他项目容器注册表的访问,Runner会返回错误消息。
例如:
-
警告:使用策略“always”拉取镜像失败:来自守护进程的错误响应:对registry.example.com/path/to/project的拉取访问被拒绝,仓库不存在或可能需要'docker login':被拒绝:请求对该资源的访问被拒绝 -
警告:使用策略“”拉取镜像失败:镜像拉取失败:rpc错误:code = Unknown desc = 无法拉取并解压镜像“registry.example.com/path/to/project/image:v1.2.3”:无法解析引用“registry.example.com/path/to/project/image:v1.2.3”:拉取访问被拒绝,仓库不存在或可能需要授权:服务器消息:insufficient_scope:授权失败
若以下条件同时成立,则可能出现这些错误:
- 私有项目中托管镜像的限制对此项目的访问选项已启用。
- 尝试获取镜像的作业运行的项目未列入私有项目的白名单。
要解决此问题,请将任何具有从容器注册表获取镜像的CI/CD作业的项目添加到目标项目的作业令牌白名单中。
当尝试使用项目访问令牌访问另一个项目中的镜像时,也可能出现这些错误。项目访问令牌的作用域仅限于单个项目,因此无法访问其他项目的镜像。你必须使用其他类型的令牌,其作用域更广。
“Something went wrong on our end message or 500 error when running a pipeline”
运行流水线时,你可能会收到以下错误:
- 推送或创建合并请求时出现“我们这边出了点问题”消息。
- 通过API触发流水线时出现
500错误。
若项目导入后内部ID记录不同步,则可能出现这些错误。
要解决此问题,请参阅issue 352382中的解决方法。
“config should be an array of hashes error message”
当你使用!reference标签配合parallel:matrix关键字时,可能会看到类似以下的错误:
此GitLab CI配置无效:jobs:my_job_name:parallel:matrix 配置应为哈希数组。parallel:matrix关键字不支持同时使用多个!reference标签。请改用YAML锚点。
issue 439828提议改进parallel:matrix中对!reference标签的支持。