为什么你的 Linux 服务器没有自动更新?排查与配置指南

最近看到有朋友在折腾服务器时遇到一个挺经典的问题:“为什么我的服务器没有自动升级?” 相信不少手里捏着好几台 VPS 的博主或者运维老手,都有过类似的抓狂时刻。明明记得好像装了自动更新工具,为什么登录一看,内核版本还是几个月前的?

今天我们就抛开那些复杂的官方文档,像老朋友聊天一样,把这个问题彻底掰扯清楚。这里不谈特定社区的细节,我们只聊技术本身和实实在在的解决方案。

一、先搞清楚:你真的开启自动更新了吗?

User checking unattended-upgrades configuration in Linux terminal

检查 unattended-upgrades 配置文件

很多时候,“以为”和“实际”中间差了好几行代码。在 Linux 世界里,不同的发行版处理自动更新的策略完全不同。你不能用 CentOS 的脑子去想 Ubuntu 的逻辑。

1. Debian / Ubuntu 系

这俩系算是比较亲民的,默认或者通过 unattended-upgrades 包就能搞定。但很多时候,这个包并没有默认安装,或者安装了没给你开启。

你需要检查这么几个地方:

  • 软件包是否安装?

    dpkg -l | grep unattended-upgrades
    

    如果空空如也,赶紧先装上:

    sudo apt install unattended-upgrades
    
  • 配置文件是否写对? 配置文件通常在 /etc/apt/apt.conf.d/50unattended-upgrades。很多人打开这个文件会被里面那一堆注释吓退。其实你只需要关注这几行是不是被注释掉了(也就是前面有没有 //):

    Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}-security";
    //    "${distro_id}:${distro_codename}-updates";
    //    "${distro_id}:${distro_codename}-proposed";
    //    "${distro_id}:${distro_codename}-backports";
    };
    ```
    这里默认只开启安全更新。如果你想常规的软件补丁也自动打,就把 `updates` 那一行的注释去掉。**注意:** 强烈建议不要开启 `proposed` 或 `backports` 的自动更新,除非你想体验一下“惊喜”。

*   **开关是否打开?**
    装了包、改了配置还不够,还得告诉系统:“嘿,请开始工作”。通常运行这条命令交互式配置一下就行:
    ```bash
    sudo dpkg-reconfigure -plow unattended-upgrades
    ```

### 2. CentOS / Rocky Linux / AlmaLinux 系
红帽系的逻辑稍微硬核一点,尤其是 CentOS 7 以前,主要靠 `yum-cron`。到了 8/9 系列虽然变成了 `dnf-automatic`,但道理差不多。

![Linux systemctl list-timers showing inactive status](/media-load/019f21c8-52ea-75f2-86e4-e259bef841a0)

*检查 systemd 定时器状态*

```bash
# 安装
dnf install dnf-automatic

# 启用并启动服务
systemctl enable --now dnf-automatic.timer

你要去 /etc/dnf/automatic.conf 里面看看 emit_via 是什么。如果是 motd,那意思是更新完会在你登录时发个消息通知你;如果是 email,那就得确保你的服务器能发邮件或者配置了转发。最重要的 upgrade_type 要看清是 default(跟普通升级一样)还是 security(只安安全补丁)。

二、排坑指南:为什么还是没动静?

如果你自信满满地检查了上面所有步骤,发现配置完全没问题,但系统依然顽固地停留在旧版本。那多半是掉进下面这几个坑里了。

1. “只读”心态的安全更新策略

这是一个为了稳定性而设计的“坑”。很多云服务商提供的镜像,或者你自己为了求稳设置的策略,默认只会自动更新安全补丁,而不会进行大版本升级(比如内核升级)

这就导致了一个现象:你跑的服务组件(如 Nginx, OpenSSL)可能都已经修了洞,但 uname -r 显示的内核依然是刚开机时的那个版本。因为这涉及到重启服务器,而自动更新工具默认不敢随便重启你的生产环境机器。

怎么办? 如果你愿意为了新内核承担短暂的重启风险,可以在配置文件里开启自动重启(当然,这步操作要非常慎重,最好加上时间窗口限制)。对于 Ubuntu,可以在 50unattended-upgrades 里设置:

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";

这样它就会在凌晨两点趁你睡觉的时候悄悄重启并应用新内核。

2. 锁了文件,谁来了也别想动

有时候为了防止手滑把关键服务给误升级了,我们会执行这样的命令:

sudo apt-mark hold nginx

或者使用 apt_preferences 锁定版本。一旦被 hold 的包,就算自动更新服务跑断腿,它也是不会动的。

排查方法:

dpkg -l | grep -E "^hi|^	hi"
``n
看看有哪些包前面标着 `hi`,这些就是被按住不让动的包。

### 3. 定时器没跑起来
systemd 的时代,服务是跑起来了,但计时器没点着也是个常见问题。

检查一下 timer 状态:
```bash
systemctl list-timers --all

找找看有没有 apt-daily.timer 或者 dnf-automatic.timer。如果它们是 inactive (dead),你的自动更新就是个摆设。用 systemctl start 把它拉起来。

4. 网络源拉跨

有时候纯粹是因为配置的软件源太慢或者间歇性抽风。自动更新任务每次执行的时间窗口很短(通常就几分钟),如果连不上源或者下载超时,它就默默放弃了,也不会给你弹窗报错。

换一个国内的优质镜像源(比如阿里云、腾讯云的源),往往能解决玄学问题。

三、除了系统自带,还有更优雅的方式吗?

说实话,系统自带的工具虽然稳定,但有时候反馈不够直观。如果你像我一样,手里管着好几台不同发行版的服务器,统一管理会更头疼。

这时候可以考虑一些现代化的运维工具,比如 Ansible 写个定时任务,或者把服务器接入 Cockpit 这类 Web 管理面板。甚至有些更高级的玩法是用 Tailscale 结合自建的更新推送脚本,一旦有更新成功或失败,直接发消息到你的手机或 Telegram。

四、总结一下

如果你发现服务器没自动升级,别慌,按这个顺序查:

  1. 装没装? 对应的包有没有安装。
  2. 开没开? 配置文件里的开关是不是选了“No”。
  3. 锁没锁? 关键包是不是被 hold 住了。
  4. 跑没跑? systemd 的 timer 状态对不对。
  5. 敢不敢? 是不是只更新了软件包,却不敢重启升级内核。

服务器自动更新是把双刃剑,它既能让你免于繁琐的手动维护,也可能在不恰当的时机给你“惊喜”。建议大家在测试环境先充分验证策略,再应用到生产环境中。希望这篇碎碎念能帮到你,让你的服务器乖乖听话!

标签: none

AI Skills Smart Station on Nick Launches

评论已关闭