差别
这里会显示出您选择的修订版和当前版本之间的差别。
| 后一修订版 | 前一修订版 | ||
| cicd:nexus:nexus问题排查:nexus的docker仓库报错处理汇总 [2025/10/29 04:54] – 创建 ctbots | cicd:nexus:nexus问题排查:nexus的docker仓库报错处理汇总 [2025/10/29 05:17] (当前版本) – [问题背景:] ctbots | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| ====== Nexus的docker仓库报错问题汇总 ====== | ====== Nexus的docker仓库报错问题汇总 ====== | ||
| - | E1: blob unknown to registry | + | ===== 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,可以推送私库),就可能类似的问题。 | ||
| + | |||
| + | ==== 问题成因 ==== | ||
| + | |||
| + | - 假设你 docker pull nginx/ | ||
| + | - 然后你修改了 nginx/ | ||
| + | - 因为Docker的特性是Layer层的叠加,所以本质分为3步: 1.上传原有的Nginx的镜像的Layer;2:上传自己定制的Layer的数据;3:上传镜像的Meta元数据,真正在仓库里新增一条记录。 | ||
| + | - 步骤1:上传原有Nginx镜像的Layer的时候,先用HEAD协议探测,对应的Layer层的 sha256的id值,如果存在就不上传了,节约速度。此时GET请求到 Nginx,HEAD协议分流到仓库3中,然后仓库3是group合并仓库,会在仓库1的proxy仓库中查到sha256的值,返回结果提示blob二进制存在,无需上传。 | ||
| + | - 步骤2:上传自定义的Layer数据,先HEAD请求,使用sha256的值到Nginx探测,转发到的仓库3是group合并仓库,分别在仓库1和仓库2找,找不到。提示要上传,走PUT POST协议上传到Nginx上,Nginx分流到 仓库2中,直接写入仓库2的私库。 | ||
| + | - 步骤3:上传镜像元数据的Meta,走的 PUT POST协议,经过Ngnix转发到仓库2,此时报错了,因为仓库2是私库,找不到 nginx原来的Layer的blob,原有的blob的缓存在仓库1的代理加速库中, 仓库1和仓库2是隔离的。 | ||
| + | - 最终:导致docker push的时候,一直提示 Layer already exists,但是最后一步一直报错,提示 blob unknown to registry,无法让自定义镜像关联到所有相关的blob | ||
| + | |||
| + | ==== 彻底的问题解决方式 ==== | ||
| + | |||
| + | 经过一番折腾测试,不建议在Nginx上做各种花活,进行复杂的trick,我们就用最简单的方法发解决问题。 | ||
| + | |||
| + | 搞2个域名,分别负责 pull和push。例如: | ||
| + | |||
| + | - pull.ctbots.com 域名配置到Ngnix里,直接转发到 仓库3的端口上。走合并拉取方式,可以同时拉取到仓库1和仓库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的问题。因为 推送操作已经切分到其他域名。 | ||