You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重新标记Docker镜像时如何跨Registry保留Digest?

Docker跨Registry镜像标记时保留Digest的解决方案

背景

我们的镜像仓库有两个访问地址:一个是VPC内部地址,供内部使用;另一个是外部地址,供客户拉取镜像。目前已切换为基于digest的引用系统,通过sha256摘要拉取镜像。现在希望为客户提供离线安装选项,使用docker save导出镜像后再通过docker load加载,但此过程无法保留digest信息。

核心问题

使用docker tag重新标记镜像时,如何将digest从一个Registry名称转移到另一个?

场景示例

1. 拉取内部Registry镜像并查看Digest

$ docker pull internal.registry.local/development/img:0.23.0@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267
internal.registry.local/development/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267: Pulling from development/img
Digest: sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267
Status: Image is up to date for internal.registry.local/development/img:0.23.0@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267
internal.registry.local/development/img:0.23.0@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267

查看镜像digest信息:

$ docker image ls --digests
internal.registry.local/development/img   0.23.0                               sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267   dc9c4901ced1   8 weeks ago    10.7GB

通过inspect查看镜像元数据:

$ docker image inspect internal.registry.local/development/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267 | jq '.[] | { Id, RepoTags, RepoDigests }'
{
  "Id": "sha256:dc9c4901ced19676f90c95d0f82c85ba97d15ba1c39d38ca9d692f3d3658bd43",
  "RepoTags": [
    "internal.registry.local/development/img:0.23.0"
  ],
  "RepoDigests": [
    "internal.registry.local/development/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267"
  ]
}

2. 同一Registry内打标签,Digest保留

$ docker tag internal.registry.local/development/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267 internal.registry.local/development/img:0.23.0-custom

查看结果:

$ docker image ls --digests
internal.registry.local/development/img   0.23.0          sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267   dc9c4901ced1   8 weeks ago    10.7GB
internal.registry.local/development/img   0.23.0-custom   sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267   dc9c4901ced1   8 weeks ago    10.7GB

3. 跨Registry打标签,Digest丢失

$ docker tag internal.registry.local/development/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267 external.example.org/production/img:0.23.0

查看结果:

$ docker image ls --digests
internal.registry.local/development/img   0.23.0          sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267   dc9c4901ced1   8 weeks ago    10.7GB
internal.registry.local/development/img   0.23.0-custom   sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267   dc9c4901ced1   8 weeks ago    10.7GB
external.example.org/production/img       0.23.0          <none>                                                                    dc9c4901ced1   8 weeks ago    10.7GB

4. 通过外部Registry拉取Digest可关联(但非离线场景所需)

$ docker pull external.example.org/production/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267
external.example.org/production/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267: Pulling from production/img
Digest: sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267
Status: Downloaded newer image for external.example.org/production/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267
external.example.org/production/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267

查看结果:

$ docker image ls --digests
internal.registry.local/development/img   0.23.0          sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267   dc9c4901ced1   8 weeks ago    10.7GB
internal.registry.local/development/img   0.23.0-custom   sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267   dc9c4901ced1   8 weeks ago    10.7GB
external.example.org/production/img       0.23.0          sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267   dc9c4901ced1   8 weeks ago    10.7GB

我们尝试过以下命令均无法直接实现跨Registry保留Digest:

docker tag A/img@sha B/img:tag
docker tag A/img:tag B/img:tag
docker tag A/img:tag@sha B/img:tag
docker tag A/img@sha B/img@sha  # 执行报错

可行解决方案

方案1:临时推送镜像到外部Registry(推荐)

由于两个Registry指向同一仓库,推送仅更新元数据,不会重复上传镜像层,速度极快:

# 标记外部Registry标签
docker tag internal.registry.local/development/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267 external.example.org/production/img:0.23.0
# 推送到外部Registry
docker push external.example.org/production/img:0.23.0
# 推送完成后,本地镜像自动添加对应RepoDigests条目
docker image inspect external.example.org/production/img:0.23.0 | jq '.[] | .RepoDigests'
# 导出带Digest关联的镜像
docker save external.example.org/production/img:0.23.0@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267 -o img-0.23.0.tar

方案2:为离线镜像附带Digest验证文档

若无法推送,可在离线包中附带文档说明镜像对应的Digest值,客户加载后手动验证:

# 客户加载镜像
docker load -i img-0.23.0.tar
# 查看镜像ID
docker image ls
# 验证镜像ID的sha256是否与文档中的Digest匹配
docker image inspect [image-id] | jq '.[] | .Id'
# 手动标记外部Registry标签
docker tag [image-id] external.example.org/production/img:0.23.0

后续客户使用Digest拉取时,Docker会自动匹配本地镜像,无需重新下载。

方案3:手动修改本地镜像元数据(不推荐)

直接修改Docker存储的镜像配置文件添加RepoDigests条目,但此操作不被官方支持,易导致镜像损坏:

  1. 找到镜像配置文件:/var/lib/docker/images/[image-id]/config.json
  2. 在RepoDigests数组中添加条目:"external.example.org/production/img@sha256:9c3c425cc0114e358c58800b544e104be5d5c8f3b594871dafbaf9f28444d267"
  3. 重启Docker服务生效

内容的提问来源于stack exchange,提问作者Philipp Stephan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 23:35:32