公众号旧文

为什么 Alpine 升级软件,经常要更折腾?

作者:胖子阅读 —

本文结合真实的 Tailscale 升级过程,讲一讲 Alpine 的软件升级逻辑。

一、Alpine Linux 是什么?

Alpine 并不是 迷你版 Linux

Alpine 本质上是 极简用户态发行版

它追求的是,小、干净、可嵌入、容器友好。

所以 Alpine:

  • 默认没有 systemd
  • 默认没有 glibc
  • 默认软件很少
  • 默认 BusyBox
  • 默认 OpenRC

二、Alpine 为什么那么小?

因为 Alpine 删掉了很多东西。

例如:

Debian Alpine
glibc musl libc
GNU coreutils BusyBox
systemd OpenRC
apt apk

所以 Alpine ISO 甚至只有几十 MB。

但代价是兼容性会下降。

三、为什么 Alpine 升级软件容易出问题?

Alpine 不是兼容优先,而是极简优先。

因此很多软件:

  • 官方只重点支持 Debian
  • Alpine 只是能跑
  • 第三方仓库经常滞后

例如我们这次升级 Tailscale。

四、一次真实的 Alpine 升级事故

机器上的Tailscale版本:

Tailscale 1.96.5

执行官方安装脚本:

curl -fsSL https://tailscale.com/install.sh | sh

结果 Downgrading tailscale (1.96.5 -> 1.66.4)

升级脚本把新版降级了。

install.sh 本质上只是调用 apk,而 Alpine 官方仓库里的版本比机器当前版本更旧

apk 认为仓库才是权威,于是就给覆盖了。

五、apk 和 apt 的思路完全不同

Debian 用户会天然认为官方脚本 > 系统仓库

但 Alpine 更偏向系统仓库 > 一切

apk 的理念是软件必须被仓库管理

否则它就可能:

  • 覆盖你
  • 降级你
  • 清理你
  • 替换依赖

六、为什么 Alpine 特别适合“静态二进制”?

因为 Alpine 很干净。

像 Tailscale 这种 Go 程序,本身就是静态编译

意味着:

  • 不依赖 glibc
  • 不依赖系统库
  • 不依赖复杂环境

于是:

cp tailscale /usr/sbin/
cp tailscaled /usr/sbin/

就能直接运行。

很多 Alpine 老用户最后都会绕过 apk,直接覆盖二进制。

七、OpenRC 和 systemd 的区别

Debian 用户习惯:

systemctl restart xxx

但 Alpine 默认是:

OpenRC

因此:

rc-service tailscale restart

才是正确写法。

而且服务脚本本身也是独立文件

如果你卸载 apk 包,/etc/init.d/* 里的脚本可能一起被删。

于是程序还在,但 service 没了。

八、为什么会出现“版本不一致”?

升级后 tailscale status 提示:

client version != tailscaled server version

并不是升级失败了。

而是磁盘文件已经更新,但内存里的旧进程还在运行

Linux 中:

  • 可执行文件可以被覆盖
  • 但旧进程不会自动退出

所以还要再:

rc-service tailscale restart

才是真正完成升级。

九、总结

在 Alpine 上升级软件,核心思路是:不要太依赖 apk 仓库。

尤其是:

  • Tailscale
  • Docker
  • Golang 程序
  • 第三方服务

很多时候直接使用官方静态二进制反而最稳定。

因为 Alpine 的世界观本来就是系统尽量简单,剩下的全都交给你。