使用 regctl 将远程镜像复制到目标可用区 Registry
regctl 可以直接在两个远程 Registry 之间复制镜像,不要求本地设备安装或启动 Docker Engine,也不会把镜像导入本地 Docker 镜像存储。本教程适用于本地设备能够访问源 Registry 和目标可用区 Registry 公网地址的场景。
如果镜像已经存在于本地 Docker Engine,直接使用 docker push;在同一平台、同一租户的可用区之间迁移镜像时,优先使用镜像中心的 同步 功能。完整的平台导入和迁移方式参见导入或跨可用区迁移镜像。已有经过验证的 crane 脚本,或依赖 --all-tags、--no-clobber 等 crane 选项时,可以继续使用使用 crane 检查、管理和传输容器镜像。
注意
第三方可选工具
regctl 是需要自行安装的第三方工具,不属于平台服务等级协议的保障范围。本文命令按 v0.11.5 核对;用于生产环境或 CI 时,请固定并验证所用版本。
安装并确认 regctl 版本
macOS 可以通过 Homebrew 安装:
brew install regclient
regctl versionLinux 和 Windows 用户可以从 regclient Releases下载与操作系统及架构匹配的二进制文件,并按官方安装说明验证下载内容。安装后运行:
regctl version确认 regctl 已加入 PATH,并且输出版本符合预期。
登录目标可用区 Registry
平台的 Registry 按可用区相互独立。先在镜像中心选择镜像实际要使用的目标可用区,复制页面显示的 Registry 公网访问地址、用户名和密码。地址选择规则参见镜像仓库地址与可用区。
从本地设备执行复制时,必须使用目标可用区 Registry 公网访问地址。cr.infini-ai.com 是平台实例访问其所在可用区 Registry 的内部地址,不能用于本地导入。
export DST_REGISTRY="<目标可用区 Registry 公网访问地址>"
export DST_USERNAME="<镜像中心提供的用户名>"
read -rsp 'Registry password: ' DST_PASSWORD
printf '%s' "$DST_PASSWORD" |
regctl registry login "$DST_REGISTRY" \
--user "$DST_USERNAME" \
--pass-stdin
unset DST_PASSWORD--pass-stdin 可以避免密码出现在 Shell 历史和进程参数中。regctl 会把凭证写入当前用户的配置;不要打印或提交该配置文件。
登录私有 Docker Hub 镜像
Docker Hub 公有镜像通常可以匿名读取。源镜像为私有镜像,或需要避免匿名读取限额时,再使用 Docker Hub 用户名和访问令牌登录:
export DOCKERHUB_USERNAME="<Docker Hub 用户名>"
read -rsp 'Docker Hub access token: ' DOCKERHUB_TOKEN
printf '%s' "$DOCKERHUB_TOKEN" |
regctl registry login docker.io \
--user "$DOCKERHUB_USERNAME" \
--pass-stdin
unset DOCKERHUB_TOKEN复制目标架构的镜像
定义源镜像、目标镜像和目标平台。以下示例把 Docker Hub 中的 Ubuntu 22.04 Linux AMD64 镜像复制到目标可用区 Registry:
export PLATFORM="linux/amd64"
export SRC_IMAGE="docker.io/library/ubuntu:22.04"
export DST_IMAGE="$DST_REGISTRY/<租户 ID>/ubuntu:22.04"
SRC_DIGEST="$(
regctl image digest \
--platform "$PLATFORM" \
"$SRC_IMAGE"
)"
regctl image copy \
--platform "$PLATFORM" \
"$SRC_IMAGE" \
"$DST_IMAGE"读取源摘要同时会确认源镜像包含目标平台。如果命令找不到 linux/amd64,请改选合适的上游镜像,或返回构建流程生成目标架构。
--platform linux/amd64 只复制该平台对应的镜像配置和镜像层。需要保留完整多架构镜像时,不要添加 --platform,并在验证时比较同一层级的摘要。
regctl 只会传输目标端缺失且无法挂载复用的镜像层。镜像数据仍会经过运行 regctl 的设备,因此速度受源端下载、目标端上传和本地网络共同影响。
验证目标摘要并试运行镜像
复制完成后,读取目标镜像的同平台摘要,并与复制前记录的源摘要比较:
DST_DIGEST="$(
regctl image digest \
--platform "$PLATFORM" \
"$DST_IMAGE"
)"
printf 'source: %s\ndestination: %s\n' \
"$SRC_DIGEST" \
"$DST_DIGEST"
test "$SRC_DIGEST" = "$DST_DIGEST"摘要一致后,返回镜像中心确认镜像出现在预期可用区,并创建测试实例,验证平台能够拉取、启动和运行目标镜像。用于开发机前,还要确认镜像包含开发机基础组件。
为单个大镜像层启用分块上传
普通镜像和稳定链路先使用默认的 regctl image copy。已知镜像包含数百 MiB 至数 GiB 的单个层、上传链路容易超时,或同一个大层已经反复上传失败时,再为目标 Registry 主机配置分块上传。
需要确认单层大小时,查看镜像清单中 Layers 下每个 descriptor 的 Size:
regctl manifest get \
--platform "$PLATFORM" \
"$SRC_IMAGE"regctl 默认会尝试完整上传,并在失败且输入可以重新读取时回退到分块上传。与 crane copy 相比,regctl 还提供目标主机级别的完整上传阈值和分块大小设置,可以让已知的大层直接使用分块协议:
regctl registry set "$DST_REGISTRY" \
--blob-max 536870912 \
--blob-chunk 33554432这组配置表示:
- 大于 512 MiB 的 blob 直接使用分块协议;
- 每次分块数据请求最多传输 32 MiB。
在没有明确网关限制或既往失败数据时,512 MiB 是兼顾兼容性和大层上传稳定性的建议起点:普通小层仍使用完整上传,较大的 AI、CUDA 或自制镜像层则直接分块。32 MiB 分块可以降低单次失败的重传量,但过小会增加协议开销,过大则可能再次触发超时或请求体限制。这组值不是 regclient 或所有 Registry 的通用默认值。
如果已经知道最小失败层的大小,将 blob-max 设置在该大小以下;如果 Registry 网关公布了请求体限制,则同时确保 blob-max 和 blob-chunk 低于该限制。
确认配置已保存,然后重新执行复制命令:
regctl registry config "$DST_REGISTRY"
regctl image copy \
--platform "$PLATFORM" \
"$SRC_IMAGE" \
"$DST_IMAGE"复制完成后,按照验证目标摘要并试运行镜像检查结果。需要恢复该目标主机的默认 blob 上传策略时,清除显式配置:
regctl registry set "$DST_REGISTRY" \
--blob-max 0 \
--blob-chunk 0重要
分块上传不是跨进程断点续传
regctl 可以在同一个复制进程中重试分块请求。进程退出后重新运行时,目标端已经完整提交的镜像层通常可以复用,但未完整提交的单个层仍可能从头上传。
排查复制失败
第一个请求就返回 401 或 403
这类错误与单层大小无关。确认使用了目标可用区的正确公网地址,并检查账号是否具有目标 Repository 的推送权限。能够读取或列出镜像不表示能够推送。
无法同时连接源端和目标端
regctl 运行设备必须同时能够访问源 Registry 和目标 Registry。访问 Docker Hub 需要代理、而目标可用区 Registry 应当直连时,让 Docker Hub 及其镜像层下载域名走代理,并把目标 Registry 公网主机名加入 NO_PROXY。NO_PROXY 中只填写主机名,不要包含 https:// 或路径。
不要通过关闭 TLS 校验绕过连接或证书错误。目标 Registry 公网地址应使用镜像中心提供的正式 HTTPS 入口。
分块请求仍然反复失败
按以下顺序检查:
- 确认
regctl registry config "$DST_REGISTRY"显示预期的blobMax和blobChunk; - 检查代理、VPN、网关和防火墙是否会重置长连接或拦截
PATCH上传; - 逐步减小
blobChunk,观察单次请求能否稳定完成; - 确认目标 Registry 存储空间和租户配额充足;
- 如果目标 Registry 不接受分块上传,改用 Docker
pull、tag、push流程,或联系平台支持确认 Registry 限制。
保存配置后的连通性探测不适用
regctl registry set 默认会在保存配置后检查 Registry 连通性。只有该额外探测已知不适用,或需要在 Registry 尚不可达时预写配置,才添加 --skip-check。该选项不参与镜像上传,也不能修复 TLS、认证或网络错误;真正复制时仍会发出 Registry 请求。
重新运行后仍从大层开头传输
分块重试主要发生在同一个 regctl 进程内。设备休眠、进程退出或上传会话过期后,未完整提交的单个层仍可能从头开始。长时间复制时,请在不会随终端关闭而退出的环境中运行,例如持久服务器的 tmux 会话或受控 CI Runner。
了解 regctl 的使用边界
- regctl 不负责执行 Dockerfile、构建镜像或运行容器;
- 分块上传不能修复错误凭证、权限不足、目标存储不足或不受支持的 Registry API;
--platform会改变目标镜像包含的平台范围,需要保留完整多架构镜像时不要使用该选项。