Nexus的docker仓库报错问题汇总

Nexus的docker仓库报错问题汇总

E1: blob unknown to registry

问题现象:

docker push的时候,提示 Layer already exists ,但是最终push完毕的时候,提示: blob unknown to registry

问题背景:

Nexus的社区版本不支持 Docker的加速库和私有仓库 的2个仓库合并对外提供服务,这是企业版特性; 社区版OSS版本,只能另外想办法。

如果你是Nexus的OSS社区版,而且Docker仓库进行了分仓库, 仓库1是proxy代理加速仓库,仓库2是 内部的hosted 私有仓库,仓库3是group仓库,把仓库1和仓库2进行了合并。

而且,因为多个仓库的情况下,不好维护命令,如果你增加了一个前置的Nginx代理分流(GET,HEAD走 仓库3的group合并仓库,同时能pull到 加速库和私有库; POST PUT 自动走 仓库2,可以推送私库),就可能类似的问题。

问题成因

  1. 假设你 docker pull nginx/nginx:1.1.2 这个镜像,此时走Nginx代理,发现是GET 或者 HEAD请求,然后转发给仓库3的group合并仓库,此时仓库3调用 仓库1的proxy代理加速仓库,此时 仓库1的proxy缓存的对应的blob二进制文件。
  2. 然后你修改了 nginx/nginx:1.1.2 的镜像,修改为 nginx/nginx:custom-1.2,然后准备docker push到自己的私有仓库
  3. 因为Docker的特性是Layer层的叠加,所以本质分为3步: 1.上传原有的Nginx的镜像的Layer;2:上传自己定制的Layer的数据;3:上传镜像的Meta元数据,真正在仓库里新增一条记录。
  4. 步骤1:上传原有Nginx镜像的Layer的时候,先用HEAD协议探测,对应的Layer层的 sha256的id值,如果存在就不上传了,节约速度。此时GET请求到 Nginx,HEAD协议分流到仓库3中,然后仓库3是group合并仓库,会在仓库1的proxy仓库中查到sha256的值,返回结果提示blob二进制存在,无需上传。
  5. 步骤2:上传自定义的Layer数据,先HEAD请求,使用sha256的值到Nginx探测,转发到的仓库3是group合并仓库,分别在仓库1和仓库2找,找不到。提示要上传,走PUT POST协议上传到Nginx上,Nginx分流到 仓库2中,直接写入仓库2的私库。
  6. 步骤3:上传镜像元数据的Meta,走的 PUT POST协议,经过Ngnix转发到仓库2,此时报错了,因为仓库2是私库,找不到 nginx原来的Layer的blob,原有的blob的缓存在仓库1的代理加速库中, 仓库1和仓库2是隔离的。
  7. 最终:导致docker push的时候,一直提示 Layer already exists,但是最后一步一直报错,提示 blob unknown to registry,无法让自定义镜像关联到所有相关的blob

彻底的问题解决方式

经过一番折腾测试,不建议在Nginx上做各种花活,进行复杂的trick,我们就用最简单的方法发解决问题。

搞2个域名,分别负责 pull和push。例如:

  1. pull.ctbots.com 域名配置到Ngnix里,直接转发到 仓库3的端口上。走合并拉取方式,可以同时拉取到仓库1和仓库2的合并版镜像。
  2. posh.ctbots.com 域名配置到Nginx里,直接转到 仓库2的端口上。走 私有仓库的推送。不要再对 GET HEAD PUS POST协议进行区分。

最终效果:

docker push的时候, HEAD 查询blob是否存在,一定的走的仓库2,如果blob存在就跳过;PUT POST 也只有仓库2; 最终上传META元数据的时候,一定可以找到所有的blob进行组装。

docker pull的时候,直接走的 仓库3合并库,不用再担心 HEAD请求Layer的问题。因为 推送操作已经切分到其他域名。

cicd/nexus/nexus问题排查/nexus的docker仓库报错处理汇总.txt · 最后更改: 2025/10/29 05:17
CC Attribution 4.0 International 除额外注明的地方外,本维基上的内容按下列许可协议发布: CC Attribution 4.0 International