钉钉群弹出一条告警:DiskUsageHigh,某台服务器磁盘使用率超过 90%。登上去查,df -hT 一看,数据盘已经没过警戒线,再晚一会儿,日志一涨服务就会被带崩。这不是我第一次被磁盘告警叫起来,但这次我把「应急、治本、预防」三件事一次性做完了。这篇文章就是这套完整闭环,从盘满的那一刻怎么处理,到怎么长效解决,再到怎么让它不再半夜喊你。
先想清楚:磁盘为什么会满
磁盘告警的本质是「饱和度」——资源余量不足。这是最好的先行指标,它先于错误出现,给你留出反应时间。最常见的两个元凶:
- • 日志不分卷。Docker 默认把容器的 stdout/stderr 写进 JSON 文件,不自动轮转也不限大小。一个打印日志特别凶猛的服务,几天就能把磁盘吃满。这是生产环境磁盘告警的头号来源。
- • 文件只增不减。备份、临时文件、下载包、deleted 但还被进程占用的文件,堆在一起毫无察觉。
所以磁盘告警的处理,从来不是「清一次就完事」,而是「清掉 → 堵住 → 提前看见」三步走。
紧急处理:盘满了,先止血
收到告警别慌,先定位是哪个分区、什么东西占的。按下面这套顺序走,能覆盖 90% 的场景。
1. 看磁盘整体情况
df -hT
-h 以可读方式显示(GB/MB),-T 显示文件系统类型。先确认是哪个挂载点告警,心里有数。
2. 定位占用目录
du -sh *
s 只显示总计大小,* 遍历当前目录下所有文件和文件夹。一级一级往下钻,找到那个「异常大的目录」。
3. 排查 Docker 容器日志(最常见)
/var/lib/docker/containers 目录很大,基本就是容器日志占满了。先看哪个容器日志最大:
sudo find /var/lib/docker/containers/ -name "*-json.log" -exec du -sh {} \; | sort -hr | head -20
确认后,临时清空日志释放空间(容器不会中断):
sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log
4. 找大文件
find / -size +1G -type f -exec du -sh {} \; | sort -hr
-size +1G 找大于 1GB 的文件,-type f 只找文件不找目录。一次性把系统里的大头捞出来。
5. 找已删除但仍被占用的文件
rm 之后磁盘空间没释放?多半是进程还握着这个文件。用 lsof 查:
lsof | grep deleted
看到 deleted 字样,找到对应 PID,重启进程释放。注意:MySQL 在 /tmp 下偶尔会有临时文件,这是正常行为,文件很小的话不用处理,别为了清它去重启数据库。
6. 清系统日志
ls -lhS /var/log/ | head -20 # 看哪些日志占空间sudo journalctl --vacuum-size=1G # systemd 日志保留 1G
到这里,磁盘空间基本释放了,服务保住了。但只是止血,不治本。
长远处理:扩容治本,堵住复发的源头
紧急清完只是缓兵之计。要长效解决,两条路:要么扩容,要么堵住日志。
扩容:云盘扩容后要手动扩分区和文件系统
以华为云为例,控制台扩容云硬盘后,分区和文件系统并不会自动扩容,必须登录服务器手动操作。这是最容易踩的坑——以为扩完就完了,其实 df 看的还是老容量。
growpart /dev/vdb 1 # 扩容 /dev/vdb 的第一个分区(编号以 lsblk 为准)resize2fs /dev/vdb1 # 扩容该分区对应的 ext4 文件系统
注意:lsblk 显示的是分区容量,扩容后立即生效;df -hT 显示的是文件系统容量,需要单独执行 resize2fs 才能扩展。两者不一致很常见,别在 df 上干着急。
堵日志:给 Docker 配置日志轮转
Docker 日志不配置轮转,迟早再爆。修改 /etc/docker/daemon.json:
{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" }}
改完重启 Docker 生效。这里有个坑:这个配置只对新创建的容器生效,之前已经存在的容器不受限制。所以改完配置后,要把关键容器重建一次,让限制真正落在它们身上。
提前预防:配置告警,别等满了才发现
到了这一步,才真正解决「半夜被叫醒」的问题。磁盘告警有两种配法,优先用云厂商云监控,别自己搭。
省事首选:云厂商云监控
如果服务器在云上,华为云、阿里云、腾讯云都自带云监控服务。装好云监控 Agent,在控制台配一条磁盘告警策略:监控指标选「磁盘使用率」,阈值设 90%,持续 5 分钟,通知渠道选短信、钉钉或企业微信。几分钟就配完,不用自己部署和维护,平台还帮你兜底高可用。这是绝大多数企业最该选的路。
什么场景才自建 Prometheus
只有一种情况值得自己搭:你在混合云、自建机房,或者已经有完整的 Prometheus + Grafana 监控栈,想让磁盘告警和其他指标统一进一个大盘。这种场景才用 Prometheus + Node Exporter 采集,Alertmanager 推到钉钉:
- alert: DiskUsageHigh expr: (1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})) * 100 > 90 for: 5m labels: severity: warning annotations: summary: "{{ $labels.mountpoint }} 磁盘使用率超过 90%"
几个要点:
- • 阈值定 90%。磁盘是硬约束,不像业务指标可以宽松,90% 是普遍的合理警戒线,给自己留出处理时间。
- •
for: 5m 持续 5 分钟才告警。避免瞬时抖动误报,也避免告警疲劳——告警响得太多等于没响。 - • 告警要可行动。消息里带上挂载点、当前使用率、已经指向哪份排查文档,凌晨三点的大脑只能执行说明书,做不了阅读理解。
告警配好之后,还差一步:每个新告警上线前,故意触发一次,验证它真的会响、响给对的人。别等真出事才发现规则写错了。
避坑指南
- • 日志轮转只对新建容器生效,老容器要重建才受限制,这是最常见的「配置了却没用」的坑。
- • 云盘扩容≠分区扩容,
df 界面不变化就以为失败,其实是分区和文件系统没手动扩。 - • deleted 文件别急着处理,
lsof 里 MySQL 的临时文件是正常行为,文件小就不动它,别为了清它重启数据库。 - • 告警阈值别乱拍,90% 是普遍经验值,但如果你有周期性的半夜备份任务,要考虑到备份高峰对磁盘的瞬时占用。
总结
磁盘告警处理不是「清一次空间」这种救火,而是一个闭环:紧急用 6 步排查止血,治本靠扩容和日志轮转,最后用告警规则提前看见问题。把这三步走完,磁盘告警基本不会再半夜把你叫起来——它只会在你有空处理的时候,安静地提醒你。
你遇到过最让人头疼的磁盘告警是什么?是日志一天涨几个 G,还是文件删了空间却不释放?评论区聊聊。
#Linux #磁盘告警 #运维实战