预热镜像需用skopeo按digest拉取并分发tar包,避免docker pull串行等待;必须统一存储驱动或改用skopeo推回registry再pull;load后验证RepoDigests字段。

pull 镜像时卡在 “Waiting” 状态,其实是没预热
集群批量部署前不预热镜像,节点拉取会撞上 registry 并发限流或网络抖动,导致部分节点卡在 Waiting 或超时失败。这不是 Docker 问题,是部署节奏和 registry 能力不匹配。
- 预热本质是提前触发一次完整 pull(含 manifest + layers),让 registry 缓存热起来,也把 layer 下到本地磁盘
- 别用
docker pull在每个节点上串行跑——那是“等”,不是“预热” - 真正有效的预热:选 1–2 个网关节点集中拉取,再用
docker save+scp+docker load分发,绕过重复下载 - 如果 registry 支持
HEAD /v2/…/manifests/…,可先检查 manifest 是否存在,避免无效 pull
用 skopeo 替代 docker pull 做无守护进程预热
在 CI 或中控机上预热,不想启 dockerd?skopeo 是更轻、更可控的选择,它不依赖本地 daemon,直接跟 registry HTTP API 对话。
-
skopeo copy docker://nginx:1.25 docker-archive:/tmp/nginx.tar—— 拉取并打包,不碰本地镜像库 - 比
docker pull && docker save少一次解压/重压缩,layer 层原样保留,快 30%+ - 注意加
--insecure-policy(私有 registry 自签证书)或--tls-verify=false,否则静默失败 - 失败时错误信息是
FATA[0005] unable to retrieve auth token,说明没配--src-creds或凭据过期
脚本里硬写 latest 标签等于埋雷
预热脚本里写死 nginx:latest,上线时可能拉到未经测试的版本。镜像标签必须锁定 digest,否则“预热了,但不是那个镜像”。
- 正确做法:用
skopeo inspect docker://nginx:1.25拿到Digest字段,如sha256:abc123... - 预热命令必须用 digest 拉:
skopeo copy docker://nginx@sha256:abc123... docker-archive:/tmp/nginx.tar - CI 构建完立刻记录 digest 到配置中心或文件,脚本读它,而不是读 tags
- 用 tag 拉完再
docker images --digests反查 digest?不可靠——docker pull可能只更新 manifest,layer 还在旧缓存里
分发 tar 包后 docker load 失败:别忽略存储驱动差异
在 overlay2 节点上生成的 .tar,直接 load 到 aufs 或 btrfs 节点,大概率报 failed to register layer 或 invalid diffID。
- 根本原因:不同存储驱动对 layer tar 的校验方式不同,
docker save输出的是“内容无关”的 tar,但docker load会按本地 driver 重新计算 diffID - 安全做法:所有节点统一存储驱动;若无法统一,改用
skopeo copy docker-archive:/tmp/x.tar docker://$REGISTRY/ns/x:tag推回 registry 再 pull - 验证是否成功:load 后立刻
docker inspect $(docker images -q nginx),确认RepoDigests字段非空且含预期 digest
docker pull,关键在“可控拉取 + 精确分发 + digest 锁定”。最容易被跳过的,是验证 load 后的 RepoDigests 和跨节点存储驱动兼容性。










