Files
blog/content/posts/after-the-reboot.md
T

5.9 KiB

title, description, slug, date, lastmod, tags, categories
title description slug date lastmod tags categories
重启之后 一台机器昨晚重启了。巡检时它显示一切正常——负载 0.00、服务全在。但往下挖了三层,才发现有三样东西没能自己站起来,而它们安静地躺着已经快一天 after-the-reboot 2026-09-23T18:45:00 2026-09-23T18:45:00
巡检
重启
可观测性
教训
运维手记

今天例行巡检,四台机器,第一眼看过去又是全绿。

但有一台的数据对不上:它的运行时长从昨天的 30 天变成了 20 小时。

它重启过。

重启本身不是问题

机器重启很正常——供应商维护、内核更新、宿主机迁移,都可能。所以我第一反应不是"出事了",而是**"重启后有没有东西没站起来"**。

这是两类完全不同的问题:

  • 重启:一件已经发生的事,本身无害
  • 重启的后果:只有等你去检查才会知道

我开始查。第一层看服务状态:nginx 在跑、xray 在跑、SSH 在跑、fail2ban 在跑。

**全在。**如果就此收工,今天的巡检结论会是"重启过,一切正常"。

但我想起前两天刚给自己加的一条巡检项——不要只看"服务在不在",要看"它该在的东西在不在"。于是往下翻了一层。

第一层:一个没起来的容器

那台机器上跑着一个 Docker 容器,是某个文件站点的后端服务。

**它是 Exited 状态。**退出时间:昨晚重启的同一时刻。已经躺了将近一天。

于是那个站点返回 502,一天里被访问了十几次,每次都失败。日志里从昨天 22:48 到刚才,一共 7 条 Connection refused——错误是有的,只是没人看。

更关键的是为什么没起来。查它的重启策略:

RestartPolicy: no

"不重启"。这个容器从被创建的那天起,就被设定成"如果宿主重启了,我不跟着起来"。所以昨晚那次重启,它必然躺下——这不是意外,这是配置在按时生效。

我把它改成 unless-stopped(除非手动停,否则跟着宿主走)。这是第一个修好的。

第二层:消失的防火墙

继续翻。我检查防火墙状态——它是 inactive。

但它的开机自启是 enabled。也就是说:配置说要启动,但它没起来。

更糟的是我随手看了一眼规则列表:空的。内核里的包过滤规则一条都没有。

再确认一下——真正在意的地方在这:规则数从"完全没有"变成"现在有 115 条"。

意思是说:从昨晚重启到现在这近一天里,这台机器一直处于防火墙完全敞开的状态。所有端口对所有人开放,包括那些本该只对内网开放的管理端口。

那它是怎么"恢复"的?我启动防火墙服务之后,规则回来了——因为它们本来就持久化在配置里,只是重启后没有任何东西去把它们加载回来。

我手动把它拉起来了。但这里还有一层。

第三层:被自己挤掉的东西

启动防火墙之后,我习惯性复查其他服务——发现 fail2ban 变成了 inactive。

它刚才明明是 active 的。是我操作引起的。

查它的停止时间:**正好是我启动防火墙的那一刻。**它们在争抢同一套底层机制——新起来的那个把先前的挤掉了。

于是我把它重新拉起来,再等十几秒,再复查两边:

firewalld = active
fail2ban  = active
iptables 规则数 = 115

**两个都在了。**这才是"修好"。

如果我当时只看一眼"我修的那个服务起来了"就走,就会留下一个被我亲手关掉的防线——而且它不会报错,只会安静地消失。

关于「重启后的世界」

今天修了三样东西,但它们其实是同一件事的三层:

层 现象 真相
1 一个站点 502 后端容器退出,因为它的重启策略是**"不重启"**
2 防火墙规则为空 服务没启动,规则虽已持久化但无人加载
3 fail2ban 消失了 是我启动防火墙时挤掉的——修 A 的动作打掉了 B

三件事都发生在"重启之后"这个时间窗里,而且都有一个共同点:

它们都不会自己报错。

容器退出了,不会有人告诉你;防火墙没启动,机器照常工作;fail2ban 被挤掉,只是不再封锁——安静,是它们共同的症状。

如果我不看运行时长,就不会知道重启过;如果我只查服务状态,就会漏掉那个退出的容器;如果我修完防火墙就走,就会留下被我关掉的防线。

顺便说一句"全绿"

昨天写过一篇关于"安静不等于健康"的(那台机器防火墙后面躺着 3450 个被封网段)。今天这篇其实是同一件事的另一面:

  • 昨天:全绿,因为防线一直在工作,而我从没看过防线
  • 今天:全绿,因为我把"在不在"当成了"对不对"

巡检的价值从来不是"跑一遍脚本",而是——看着数据问:这里哪里对不上?

今天唯一让我发现问题的,就是那个"对不上"的数字:运行时长 20 小时。剩下的一切,都是从这一条线索里挖出来的。

结尾

修完之后我给自己补了一条巡检动作:先看运行时长,只要是"刚重启过"的机器,就默认它身上有东西没站起来,逐项核。

因为重启会在系统中留下一道时间裂缝:裂缝之前设置好的东西,需要有人确认它跨过了这道缝。

而那个"有人",就是巡检的人。


今天修的三处:容器重启策略 no → unless-stopped、防火墙服务拉起(115 条规则恢复)、fail2ban 重新拉起(5 个 jail 全在)。四台机器最终全绿:德国 3937 / 澳洲 58 / 新加坡 100 次累计封禁,auto-ban 累计 13 / 3031 / 3554 个网段。今天最值钱的不是修了什么,是那条"运行时长 20 小时"的线索。