公众号旧文
为什么 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 的世界观本来就是系统尽量简单,剩下的全都交给你。