csdn-enterpriseGitLab Runner docker pull 慢:并行流水线镜像拉取排查

1. 问题现象

团队并行提交多个 MR 后,GitLab Runner 队列开始变长。业务测试本身没有明显变慢,但 job 卡在环境准备阶段:

text 复制代码
Preparing environment
Using Docker executor with image node:20 ...
Pulling docker image node:20 ...
context deadline exceeded

这类问题不要一上来就改测试脚本。先确认到底是测试执行慢,还是 runner 在拉镜像时已经被拖住。

本文记录一套排查顺序:从 runner executor、基础镜像、service 镜像、pull policy、镜像源和本地缓存逐层检查。

2. 环境示例

text 复制代码
GitLab Runner: Docker executor
Runner 节点:Linux / Docker Engine
并发场景:多个分支同时跑单测和集成测试
常见镜像:node:20、python:3.12、postgres:16-alpine、redis:7、ghcr.io/.../test-runner

如果是 GitHub Actions 自建 runner,也可以参考同样的排查思路。核心都是:job 开始前要先把容器镜像拉到 runner 节点。

3. 先区分 pending、preparing 和 script

看 job 卡在哪一段:

阶段 现象 方向
pending 没有 runner 接任务 runner 数量、tag、并发数
preparing 已分配 runner,正在拉镜像 Docker、镜像源、DNS、缓存
script 脚本已经执行 测试耗时、依赖缓存、数据库初始化

如果日志里出现 Pulling docker image,说明至少有一部分时间花在镜像拉取。

4. 在 runner 节点手工验证

进入 runner 节点,不通过 CI,直接拉关键镜像:

bash 复制代码
docker pull node:20
docker pull python:3.12
docker pull postgres:16-alpine
docker pull redis:7-alpine

如果团队使用 GHCR、MCR、Quay:

bash 复制代码
docker pull ghcr.io/your-org/test-runner:latest
docker pull mcr.microsoft.com/playwright:v1.44.0-jammy
docker pull quay.io/skopeo/stable:latest

常见错误包括:

text 复制代码
context deadline exceeded
i/o timeout
connection reset by peer
TLS handshake timeout

这时问题优先看 runner 节点的网络、DNS、镜像源和代理配置。

5. 配置 Docker 镜像源

可以先用 1ms-helper 处理 Docker 场景:

bash 复制代码
curl -sSL https://static.1ms.run/1ms-helper/install.sh | bash
sudo 1ms-helper config:docker

Linux Docker 的基础配置可以参考:

json 复制代码
{
  "registry-mirrors": ["https://docker.1ms.run"],
  "dns": ["8.8.8.8", "114.114.114.114"]
}

然后重启 Docker:

bash 复制代码
systemctl daemon-reload
systemctl restart docker
systemctl status docker

再验证:

bash 复制代码
docker pull docker.1ms.run/library/node:20
docker pull docker.1ms.run/library/postgres:16-alpine
docker pull ghcr.1ms.run/your-org/test-runner:latest

说明:毫秒镜像在这里解决的是多源镜像入口和拉取稳定性这一层,不替代 runner 并发、测试拆分和依赖缓存。

6. 检查 GitLab Runner pull policy

GitLab Runner Docker executor 支持 pull_policy。如果每次 job 都强制拉镜像,runner 本地缓存就很难发挥作用。

示例:

toml 复制代码
[[runners]]
  executor = "docker"
  [runners.docker]
    image = "docker.1ms.run/library/node:20"
    pull_policy = ["if-not-present", "always"]

实际生产里不要简单照抄。建议按镜像类型区分:

镜像类型 建议
高频基础镜像 固定 tag,配合本地缓存
安全扫描镜像 固定版本,关键场景考虑 digest
数据库 service 镜像 固定小版本,减少重复拉取
团队自建镜像 使用内部版本号,不长期依赖 latest

7. 检查 .gitlab-ci.yml

一个常见配置:

yaml 复制代码
test:
  image: docker.1ms.run/library/node:20
  services:
    - name: docker.1ms.run/library/postgres:16-alpine
      alias: postgres
  script:
    - npm ci
    - npm test

如果每个 job 都启动独立数据库 service,且并发很多,镜像拉取、容器启动、数据库初始化都会叠加。需要结合缓存、测试拆分和服务复用一起看。

8. 固定关键镜像版本

近期 Docker 官方复盘过 Trivy 和 KICS 相关的供应链攻击事件。CI 里常见的扫描器、构建器、测试工具镜像,不建议长期用模糊的 latest

至少做到:

  • 生产发布链路用明确 tag。
  • 关键扫描和构建镜像记录 digest。
  • 基础镜像升级走 MR,而不是静默变化。
  • runner 节点定期清理,但不要把高频镜像缓存清得太干净。

Docker 支持按 digest 拉取镜像,例如:

bash 复制代码
docker pull alpine@sha256:<digest>

Digest 不是为了让镜像拉得更快,而是为了让 CI 结果更可复现。

9. 排查清单

检查项 命令/位置
runner 是否接任务 GitLab job 状态、runner tag
是否卡在镜像 job 日志里的 Pulling docker image
Docker 是否正常 systemctl status docker
DNS 是否异常 1ms-helper check:dns
基础镜像能否拉取 docker pull node:20
多源镜像能否拉取 docker pull ghcr.io/...
pull policy 是否合适 config.toml
service 镜像是否过多 .gitlab-ci.yml

总结

CI 并行构建变慢时,不要只看测试脚本。runner 的镜像拉取阶段经常是隐藏瓶颈。

我的处理顺序是:

  1. 看 job 卡在 pending、preparing 还是 script。
  2. 在 runner 节点手工拉基础镜像和 service 镜像。
  3. 配置 Docker 镜像源并验证多源镜像入口。
  4. 检查 pull_policy 和本地缓存。
  5. 固定关键工具镜像版本,必要时记录 digest。

这样才能把"测试慢"和"runner 拉镜像慢"分开处理。

相关推荐
鹏大师运维4 小时前
为什么信创电脑装软件总提示“软件包架构不匹配”?
linux·运维·架构·国产化·麒麟·deb·统信uos
007张三丰4 小时前
软件测试专栏(11/20):测试框架开发:pytest深度解析与插件体系
运维·服务器·自动化测试·pytest·测试框架
weixin_604236676 小时前
华三 路由器 极简核心配置
运维·服务器·网络·h3c·h3c路由器
鹤落晴春6 小时前
【Linux复习】管理SELinux安全性
linux·运维·服务器
梦梦代码精6 小时前
2026年PHP开源商城系统实测对比:架构、多商户、商用授权,谁才是真·省心?
vue.js·docker·架构·开源·代码规范
AI智图坊6 小时前
多件装组合SKU图的批量生产效率分析:从PS手工到AI自动化的工作流改造
大数据·运维·人工智能·gpt·ai作画·自动化·aigc
鹤落晴春9 小时前
【K8s】Pod调度、configMaps
云原生·容器·kubernetes
极客先躯10 小时前
高级java每日一道面试题-2026年02月02日-实战篇[Docker]-如何实现容器的持久化存储?
docker·容器·面试宝典·持久化·存储·韵味·java高级面试题
云计算磊哥@11 小时前
运维开发宝典026-MySQL02数据库表操作
运维·数据库·运维开发
天天进步201511 小时前
Tunnelto 源码解析 #9:控制服务器设计:Warp、WebSocket、Ping/Pong 与连接保活
运维·服务器·websocket