Nexus常见报错处理
Nexus常见报错问题处理
Nexus常见报错问题处理
Docker仓库push镜像时,局部Layer报错,提示: blob unknown:blob unknown to registry
具体的报错可能如下:
xxxxxx: Layer already exists
yyyyyy: Layer already exists
errors:
blob unknown:blob unknown to registry
blob unknown:blob unknown to registry
blob unknown:blob unknown to registry
Nexus错误问题现象
先查看Nexus的日志,会发现 log/nexus.log 会有对应的报错:
2025-09-10 01:36:22,857+0000 ERROR [qtp226372090-117] llm org.sonatype.nexus.repository.docker.internal.datastore.recipe.V2ManifestUtilImpl - Manifest refers to missing layer: sha256:6414378b647780fee8fd903ddb9541d134a1947ce092d08bdeb23a54cb3684ac for: ctbots/base/llamafactory/pytorch2.7.1-cu12.8-flashattn2.7.4 in repository RepositoryImpl$$EnhancerByGuice$$2e20a720{type=hosted, format=docker, name='ctbots-docke
r'}
2025-09-10 01:36:22,858+0000 ERROR [qtp226372090-117] llm org.sonatype.nexus.repository.docker.internal.datastore.recipe.V2ManifestUtilImpl - Manifest refers to missing layer: sha256:ad69d38804778a7dd78e609a0b3cbeb96542df5c37738a8c398ec31498a1490b for: ctbots/base/llamafactory/pytorch2.7.1-cu12.8-flashattn2.7.4 in repository RepositoryImpl$$EnhancerByGuice$$2e20a720{type=hosted, format=docker, name='ctbots-docke
r'}
2025-09-10 01:36:22,858+0000 ERROR [qtp226372090-117] llm org.sonatype.nexus.repository.docker.internal.datastore.recipe.V2ManifestUtilImpl - Manifest refers to missing layer: sha256:2d01ee89ef0b66169d84c496b3175d51ff2a47b2e211d7e4f4fe69868681cd31 for: ctbots/base/llamafactory/pytorch2.7.1-cu12.8-flashattn2.7.4 in repository RepositoryImpl$$EnhancerByGuice$$2e20a720{type=hosted, format=docker, name='ctbots-docke
r'}
2025-09-10 01:36:22,859+0000 ERROR [qtp226372090-117] llm org.sonatype.nexus.repository.docker.internal.datastore.recipe.V2ManifestUtilImpl - Manifest refers to missing layer: sha256:7d21de8cade150523dfe4c80e31ded729bb70dce5336648c5d0ef4a618ef9e3c for: ctbots/base/llamafactory/pytorch2.7.1-cu12.8-flashattn2.7.4 in repository RepositoryImpl$$EnhancerByGuice$$2e20a720{type=hosted, format=docker, name='ctbots-docke
r'}
2025-09-10 01:36:22,859+0000 ERROR [qtp226372090-117] llm org.sonatype.nexus.repository.docker.internal.datastore.recipe.V2ManifestUtilImpl - Manifest refers to missing layer: sha256:4b650590013c9e92d469a7b5514dbe45cd755b8d75f0d6ae09e2a3e089b0c82c for: ctbots/base/llamafactory/pytorch2.7.1-cu12.8-flashattn2.7.4 in repository RepositoryImpl$$EnhancerByGuice$$2e20a720{type=hosted, format=docker, name='ctbots-docker'}
2025-09-10 01:36:22,871+0000 WARN [qtp226372090-117] llm org.sonatype.nexus.repository.docker.internal.V2Handlers - Error: PUT /v2/ctbots/base/llamafactory/manifests/pytorch2.7.1-cu12.8-flashattn2.7.4: 400 - org.sonatype.nexus.repository.docker.internal.V2Exception: Invalid Manifest
可以看到,其中的Layer层的如下id异常:
- 6414378b647780fee8fd903ddb9541d134a1947ce092d08bdeb23a54cb3684ac
- ad69d38804778a7dd78e609a0b3cbeb96542df5c37738a8c398ec31498a1490b
- 2d01ee89ef0b66169d84c496b3175d51ff2a47b2e211d7e4f4fe69868681cd31
- 7d21de8cade150523dfe4c80e31ded729bb70dce5336648c5d0ef4a618ef9e3c
这些layer的sha256的值实际可以拿到Nexus里测试下载,例如:
这时候,会发现其实是可以下载下来的,但是Nexus就是日志里报告,这个blobs找不到,无法定位。
为什么?为什么?
- 我们的ctbots 在docker push的时候,局部的Layer 是成功的,有些是失败的。
- 我们的失败的Layer为什么手动下载blobs的时候,又是可以下载的??并没有丢失
Nexus错误分析
其实是因为Docker的混合仓库配置错误的原因。
一般我们会配置3个Docker的repo仓库
- 代理翻墙加速仓库,一般是proxy类型,假设名字是 docker-proxy
- 私有内部仓库,一般是host类型,假设名字是 docker-inner
- 混合虚拟仓库,一般是group类型,假设名字是 docker-public
docker-public的混合仓库可以绑定多个仓库,并设置优先级(绑定 docker-inner,docker-proxy),当有人从本仓库 docker pull的时候,先从 docker-inner的私有仓库查找,如果找不到,从docker-proxy的代理仓库下载,如果还是没有,就报错。
而 proxy和host类型的仓库,都需要设置blob存储位置。Nexus默认只有一个。报错出现的有2个条件必须满足:
- docker-proxy 和 docker-inner 同时使用同一个blob的存储库。
- Nexus使用了Nginx反向代理,对外暴漏了一个443端口,如果是拉取镜像,走docker-public仓库,如果是推送,存储到docker-inner里。
报错原因是这样:
- 有一个公共镜像,例如 nginx:latest 被 docker-proxy 加速过,某个docker的 Layer id是 233xxx,就缓存在blob(docker-proxy仓库管理)中。
- 用户自己做了一个自定义nginx镜像,docker push 到 docker-inner中,此时 docker程序会通过 Nginx的反向代理区去查询Nexus 某一个Layer是否存在,如果存在就跳过上传,节约时间。
- Layer id是 233xxx的 GET请求到Nginx,反向代理到了 docker-public的虚拟库。虚拟库在docker-inner里找不到 233xxx的layer,但是在 docker-proxy里找到了,返回200。
- 一旦Layer在docker-proxy里找到了,docker程序就知道不需要上传这层Layer了,可以跳过了,剩余Layer上传到docker-inner(因为我们是虚拟仓库,加速库和私有库是分离的)。
- 最终上传完毕,docker-inner 私有库 需要对整个push镜像进行合并处理,需要跨repo建立符号引用(Nexus没有那么傻,知道有些Layer是用户上传的,有些Layer是缓存命中的,因为是走的 docker-public 库查询的,可能Layer是自己的,也可能是别的库的,要建立引用)。
- 但是因为docker-inner和 docker-proxy 使用的是同一个blob,同样的Layer的路径处理会有冲突,导致错误。
解决办法很简单:docker-proxy和docker-inner的blob存储库拆分开,不要互相干扰,导致Layer引用时失败; 或者 干脆不要用Nginx做反向代理进行推拉二合一(推拉二合一目前觉得坑有点多)。