可通过Docker Registry HTTP API实现镜像自动迁移:先获取源manifest(带Accept头及鉴权token),再下载并上传layers/config blob(校验digest、处理registry差异),最后推送新manifest到目标仓库。

可以通过 Docker Registry HTTP API 实现镜像自动迁移,核心是拉取源仓库的 manifest 和 layers,再推送到目标仓库。关键在于正确处理鉴权、manifest 格式(v2 或 OCI)、digest 校验以及 blob 上传流程。
获取源镜像的 Manifest
Manifest 描述了镜像的配置和所有 layer 的 digest。需先向源 registry 发起 GET 请求:
- 请求地址:
https://<source-registry>/v2/<repo>/manifests/<tag|digest> - 必须携带
Accept头,如application/vnd.docker.distribution.manifest.v2+json或application/vnd.oci.image.manifest.v1+json - 若需鉴权,先用
GET /v2/触发 401,解析WWW-Authenticate头获取 token 服务地址,再申请 bearer token
下载并上传所有 Blob(layers 和 config)
从 manifest 中提取 layers[].digest 和 config.digest,逐个迁移:
- 对每个 digest,用
GET /v2/<repo>/blobs/<digest>下载(带 token) - 上传到目标仓库:先
POST /v2/<dest-repo>/blobs/uploads/获取 upload URL,再PUT上传内容(可带?digest=<digest>直接完成) - 注意:blob 上传必须使用原始 digest,不能改写;部分 registry(如 Harbor)要求上传前先发起
HEAD /v2/.../blobs/<digest>检查是否已存在
推送新 Manifest 到目标仓库
上传完所有 blobs 后,修改 manifest 中的 schemaVersion、mediaType(保持与源一致),并确保 layers 和 config 的 digest 字段准确无误:
- 用
PUT /v2/<dest-repo>/manifests/<tag>提交 manifest - 请求头必须设
Content-Type为 manifest 对应的 mediaType(如application/vnd.docker.distribution.manifest.v2+json) - 若目标 registry 启用不可变 tag,需先删除旧 tag 或使用 digest 推送后打新 tag
处理常见兼容性问题
不同 registry(Docker Hub、Harbor、ECR、ACR)在认证方式、API 响应细节、digest 算法或 redirect 行为上略有差异:
- Docker Hub 使用
auth.docker.io获取 token,且对未登录用户返回 401 不带 auth header,需主动构造 Basic Auth 请求 - Harbor 支持项目级 robot 账号,token 权限需包含
pull和push - 某些 registry(如 ECR)上传 blob 时要求
Content-Length显式设置,且不支持 chunked transfer - OCI 和 Docker v2 manifest 混用时,注意
mediaType和config.mediaType字段是否匹配,否则 push 后 pull 可能失败


















