近期公司内部部分 Ubuntu 服务器升级到了 22.04(Jammy)。由于生产环境禁止直连外网,所有 APT 的更新与软件安装都必须通过 Nexus Repository Manager 作为内网代理源来完成。

然而,新的 Ubuntu 22 在 Nexus 上却出现了一系列诡异的问题。

本文记录我整个排查、踩坑、升级、最终解决的全部过程,希望能给遇到相同问题的人一点参考。


一、问题现象:apt update 正常,apt install 却 502

Ubuntu 22.04 使用内网 Nexus 作为 apt 源时:

  • apt update ✔️ 正常
  • apt install <package> ❌ 报错

报错如下:

E: Failed to fetch http://内网源/repository/apt-tuna/ubuntu/pool/universe/t/tree/tree_2.0.2-1_amd64.deb 502 Bad Gateway
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

浏览器或 curl 访问:

http://内网源/repository/apt-tuna/ubuntu/pool/universe/t/tree/tree_2.0.2-1_amd64.deb

也提示 502 Bad Gateway

但奇怪的是:

访问目录:

http://内网源/repository/apt-tuna/ubuntu/pool/universe/t/tree/

是能看到 tree_2.0.2-1_amd64.deb 文件的。

并且:

  • Ubuntu 18 ✔️ 正常
  • Ubuntu 20 ✔️ 正常
  • 只有 Ubuntu 22 ❌ 出现 502

关于这个问题,也没必要问 AI,真没什么好解决方案给你。


二、最初的误解:Nexus 不就是代理 http 吗?为什么下载失败?

一开始我的理解很简单:

Nexus 做 apt 代理,不就是帮我把文件从外网拉过来,然后转发给客户端么?

既然 .deb 文件列表能看到,那为什么不能直接下载?

直到我深入查资料并抓包后才发现:APT update 跟 APT install 走的流程完全不同。


三、核心原因:Ubuntu 22 引入了 zstd,Nexus 旧版本不支持

Ubuntu 22 的 .deb 结构有重大变化 —— control.tar 改成了 zstd 压缩格式

旧系统是:

  • control.tar.gz
  • data.tar.gz

而 22.04 变成:

  • control.tar.zst
  • data.tar.xz

为什么 update 能成功?

update 只是下载:

  • Packages.gz
  • Release
  • InRelease

这些都是普通的 gzip 或 plain text 文件,Nexus 不需要解包,只是透明转发即可。


为何 install 会 502?

install 时流程是:

  1. 客户端向 Nexus 请求 .deb
  2. Nexus 从外网源下载 .deb
  3. Nexus 会尝试解包 .deb(以便缓存与索引)
  4. 遇到 control.tar.zstNexus 3.32 不认识这种格式
  5. 解包失败 → 报 502 Bad Gateway

这就是 Ubuntu 22 失败而 Ubuntu 18/20 正常的根本原因。


四、确认官方说法:3.38 才加入 zstd 支持

在 Sonatype 官方社区找到类似讨论:

https://community.sonatype.com/t/problem-with-apt-proxy-for-ubuntu-21-10-impish/7600

官方人员回答:

APT zstd 支持将会在 3.38 修复
在这里插入图片描述

我使用的版本是:

Nexus Repository OSS 3.32.0

因此 不支持 Ubuntu 22 的 zstd 是确定的。

解决方案就是:
升级 Nexus 版本

我选择升级到 3.39.0(不跨版本太远,比较稳妥)。

DockerHub 上找的 nexus3 官方镜像


五、升级前的意外事故:NFS(vSAN)竟然撑不住

我在 Kubernetes 中部署 Nexus,使用的是:

  • vSAN → NFS → nexu-data(Nexus blob store)

为了升级,我想:

先拷贝一份 Nexus 的 data 目录以做备份。

结果一复制就出问题了:

  • NFS 挂载直接崩溃
  • vSAN 相关服务挂掉
  • 监控没有触发任何报警
  • 修复后再次尝试仍然崩

只要复制 Nexus 的文件,就会爆炸
复制大文件正常
复制小文件密集读写 → 崩溃

我一度怀疑:

vSAN 导出的 NFS 不适合承载大量小文件操作(Nexus 的 blob store 就是大量小文件)

虽然没有官方证据,但现象的确如此。


六、开干!升级 Nexus 3.39

我决定不再折腾 NFS 和复制:

直接升级 Nexus
数据也不重要,就一些外网源缓存而已
反正有备份数据(每日备份)
实在不行存储就换成本地的

但升级依然踩坑不断。


坑 1:给错权限导致索引重建失败

因为之前的复制操作报 I/O Error,我怀疑是权限不对,于是:

  • 给 DB 文件加了过高权限(给了执行权限)

结果导致:

  • Nexus 启动 → 发现 metadata 不对
  • 自动 rebuild index → 失败
  • 没报错,只是直接退出

参考备份文件权限与官方建议,把权限改回去:

  • 不要给执行权限
  • 保持原本 600~640 即可

坑 2:内存不够,重建索引直接卡死

直接使用 nexus3:3.39.0 镜像启动时,日志提示:

Upgrade xxxx

启动后:

  • 自动 rebuild 索引
  • 过程中直接挂掉
  • 没有报错

查容器性能 + 文档才发现:

  • Nexus 默认 JVM Heap 是 2GB
  • Rebuild Index(尤其是 APT)要吃非常多内存
  • ElasticSearch 在这个阶段会明显爆内存

准备下午调大内存……


结果:一个中午自己 rebuild 好了

下午一看:

  • Nexus 已经启动成功
  • 索引全部重建完毕

因为我也没管它,他一直重启 + 重建索引,一点一点干完了

不用调整任何配置。


七、最终验证:Ubuntu 22 APT install 终于正常了!

升级完成后,我在 Ubuntu 22.04 上再次测试:

  • apt update
  • apt install tree
  • 直接下载 .deb

所有问题全部解决。

Ubuntu 22 可以正常使用 Nexus APT 代理了。


总结

  1. Nexus 3.32.x 不支持 zstd,无解,必须升级
  2. 建议直接升级到 >= 3.38
  3. 升级前确保已备份过了
  4. NFS(尤其是 vSAN)可能不适合承载 Nexus 的大量小文件 I/O
  5. Nexus rebuild 索引很吃内存,2GB 不太够,但也不是不能跑
  6. 不要乱改 db等 目录权限,Nexus 很敏感
  7. 升级成功后 Ubuntu 22 APT 源完全正常
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐