Ubuntu服务器磁盘空间耗尽往往是运维工作中最被动的事故之一。日志文件瞬间写满、数据库膨胀、旧内核堆积、Docker镜像残留,任何一个环节失控都可能让业务中断。磁盘监控不能等到报警才处理,而是要在空间占用达到阈值前就掌握趋势并自动干预。下面直接给出可落地的监控方案,涵盖阈值设定、核心命令、脚本实现、定时任务、日志轮转、异常清理与告警联动。
一、先明确监控对象和阈值Ubuntu服务器上需要重点监控的挂载点通常是根分区/、/var、/home、/tmp以及独立的数据分区。先用df -h查看当前各分区使用情况,再用du -sh逐层定位大目录。监控阈值建议分三级:70%为预警线,80%为警告线,90%为严重线。预警线触发时只记录日志并发送低优先级通知;警告线触发时开始自动清理可安全删除的缓存和旧日志;严重线触发时除了清理,还要暂停可能继续写入的非核心服务,并立即通知运维人员介入。阈值不能设得太低,否则频繁告警会让人麻木;也不能太高,否则留给清理的时间窗口太短。
二、核心命令组合与快速排查方法日常巡检最常用的命令是df -h和df -i。df -h看空间占用,df -i看inode占用。很多运维只关注空间百分比,却忽略了inode耗尽同样会导致无法创建新文件。小文件数量激增时,空间可能还剩很多,但inode已经用完。排查大目录用du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -20,这条命令能快速列出根目录下占用最大的20个一级目录。如果要深入某个目录,把路径替换掉即可。对于已删除但被进程占用的文件,用lsof | grep deleted查找,这类文件不释放空间,需要重启对应进程或服务。
三、编写磁盘空间监控脚本手动检查只能应对临时情况,持续监控必须依赖脚本。下面是一个可直接使用的bash脚本,它检查所有挂载点的使用率,超过阈值时记录日志并执行清理动作。
#!/bin/bash
# 磁盘空间监控脚本
THRESHOLD_WARN=80
THRESHOLD_CRIT=90
LOG_FILE="/var/log/disk_monitor.log"
df -P | grep '^/dev' | awk '{print $5, $6, $1}' | while read output; do
usage=$(echo $output | awk '{print $1}' | sed 's/%//')
mountpoint=$(echo $output | awk '{print $2}')
device=$(echo $output | awk '{print $3}')
if [ "$usage" -ge "$THRESHOLD_CRIT" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') CRITICAL: $device mounted on $mountpoint is at ${usage}%" >> $LOG_FILE
# 严重级别:清理journal日志和临时文件
journalctl --vacuum-size=200M 2>/dev/null
find /tmp -type f -mtime +3 -delete 2>/dev/null
find /var/tmp -type f -mtime +7 -delete 2>/dev/null
elif [ "$usage" -ge "$THRESHOLD_WARN" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') WARNING: $device mounted on $mountpoint is at ${usage}%" >> $LOG_FILE
# 警告级别:清理apt缓存和旧日志
apt-get clean 2>/dev/null
find /var/log -type f -name "*.log" -mtime +15 -delete 2>/dev/null
fi
done
这个脚本的核心逻辑是遍历所有物理磁盘分区,提取使用率百分比,与阈值比较后执行分级清理。注意df -P保证输出格式统一,grep '^/dev'过滤掉虚拟文件系统。清理动作要保守,只删除确认安全的文件。journalctl --vacuum-size=200M限制systemd日志总大小,apt-get clean清除已下载的包缓存,find删除超过修改时间的临时文件和旧日志。脚本保存为/usr/local/bin/disk_monitor.sh,赋予执行权限chmod +x /usr/local/bin/disk_monitor.sh。
四、配置cron定时执行监控脚本需要定时运行才能发挥作用。建议每15分钟执行一次,频率太高会增加系统负担,太低则可能错过快速增长的窗口。编辑crontab -e,添加以下行:
*/15 * * * * /usr/local/bin/disk_monitor.sh
如果担心cron任务本身在磁盘满时无法写入日志,可以在脚本开头检查日志文件所在分区的可用空间,低于5%时停止写入日志,直接发送告警。另外,cron执行环境与交互式shell不同,PATH变量可能不完整,脚本中所有命令最好使用绝对路径,或者显式设置PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin。
五、日志轮转与journald配置Ubuntu服务器磁盘空间被日志写满是最常见的原因。rsyslog和systemd journald是两大日志来源。对于rsyslog,默认配置已经包含logrotate,但需要检查/etc/logrotate.d/rsyslog中的保留策略。建议将rotate从默认的7改为4,压缩方式从delaycompress改为compress,并添加maxsize 100M限制单个日志文件大小。对于journald,编辑/etc/systemd/journald.conf,设置SystemMaxUse=500M、SystemKeepFree=1G、MaxFileSec=1week。修改后执行systemctl restart systemd-journald使配置生效。这些设置能从根本上控制日志占用的空间上限。
六、Docker环境下的磁盘空间治理如果服务器上运行Docker,磁盘空间问题会复杂得多。Docker的镜像、容器、卷、构建缓存分别存储在不同位置。定期执行docker system df查看各类资源占用。清理无用资源的命令是docker system prune -a --volumes,但这会删除所有未运行容器关联的卷,执行前必须确认没有重要数据。更安全的做法是分步清理:docker image prune -a清理未使用的镜像,docker container prune清理停止的容器,docker volume prune清理未使用的卷,docker builder prune清理构建缓存。建议将Docker数据目录/var/lib/docker单独挂载分区,避免与根分区争抢空间。同时配置/etc/docker/daemon.json中的log-driver为json-file,并设置max-size和max-file限制容器日志大小。
七、定位异常增长的具体目录当监控报警后,快速定位是哪个目录在短时间内增长最快。使用du配合sort只能看当前大小,无法判断增长速度。可以间隔一段时间执行两次du,对比差异。更高效的方法是用ncdu工具,安装apt install ncdu后运行ncdu /,它能交互式浏览目录大小,按M键可以按修改时间排序,快速找到最近写入的大文件。对于持续增长的文件,用lsof +L1查看被删除但仍被进程占用的文件,或者用iotop观察哪个进程在大量写入。如果发现是某个应用日志疯狂输出,先停止应用或调整日志级别,再清理日志文件,最后排查应用异常原因。
八、告警通知与自动化响应监控脚本记录日志只是第一步,关键是要让人知道。在脚本中添加邮件通知或webhook推送。邮件通知可以用mail命令,但需要配置SMTP。更轻量的方式是接入企业微信、钉钉或飞书的机器人webhook,用curl发送JSON格式消息。在脚本的CRITICAL分支中添加:
WEBHOOK_URL="https://your-webhook-url"
curl -s -X POST -H "Content-Type: application/json" \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"磁盘告警:$device 挂载点 $mountpoint 使用率 ${usage}%\"}}" \
$WEBHOOK_URL
自动化响应除了清理缓存,还可以根据业务特点执行更精准的操作。例如MySQL数据库服务器上,如果binlog占用过大,可以执行PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY)清理三天前的二进制日志。Nginx服务器上,可以清空过期的access.log并重新加载配置。这些操作需要根据实际业务编写,不能盲目套用。
九、长期容量规划与预防措施监控和清理解决的是短期问题,长期稳定需要容量规划。每月分析一次磁盘使用趋势,用df -h记录各分区使用率,生成趋势图。如果某个分区使用率每月稳定增长5%以上,就要提前扩容或迁移数据。对于日志类数据,建立集中日志服务器,将各服务器日志通过rsyslog或filebeat发送到远端存储,本地只保留少量日志。对于数据库,定期执行OPTIMIZE TABLE回收碎片空间。对于应用产生的临时文件,在代码层面设置定期清理任务。预防永远比救火成本低。
磁盘空间监控方案的核心不是脚本本身,而是建立一套从检测、告警、自动清理到人工介入的完整闭环。脚本要足够健壮,清理动作要足够保守,告警渠道要足够可靠,容量规划要足够前瞻。把这套方案部署到所有Ubuntu服务器上,并根据每台服务器的角色调整清理策略,磁盘空间事故的发生概率会大幅降低。
