Ubuntu Server 磁盘空间不足的原因与解决方法
Ubuntu Server(尤其是24.04 LTS及后续版本)在生产环境中经常遇到根分区(/)或 /var 分区磁盘空间耗尽的问题,导致出现“No space left on device”错误、无法写入新文件、服务崩溃甚至系统无法登录。这种情况通常不是硬件故障,而是可预测、可预防的累积性占用。
一、常见原因分类(从高频到低频)
- 日志文件无限增长(最常见,占50%以上案例)
- /var/log/journal/(systemd-journald持久化日志)
- /var/log/syslog、auth.log、kern.log 等传统文本日志
- 高负载服务(如nginx、postgresql、docker)产生大量debug/info级日志
- 包管理缓存与旧版本残留
- /var/cache/apt/archives/ 中的 .deb 包(apt 未 clean)
- snap 缓存 /var/lib/snapd/cache/
- 旧内核镜像(/boot/ 空间紧张时常见)
- 容器与虚拟化相关
- Docker/Podman 镜像、容器层、volume、overlayfs(/var/lib/docker/)
- MicroK8s / k3s 等轻量k8s 的 etcd、镜像缓存
- 临时文件与缓存爆炸
- /tmp/、/var/tmp/ 中未清理的临时文件
- 用户缓存(如 ~/.cache/、浏览器缓存若有服务运行)
- 应用程序生成的临时大文件(如备份、导出)
- Inode 耗尽(空间有余但无法创建文件)
- 极小文件数量过多(常见于邮件队列、日志碎片、git仓库滥用)
- 已删除文件句柄未释放(df 显示满,du 显示空闲)
- 大文件被删除但进程仍持有打开句柄(常见于日志轮转失败的服务)
- 分区/文件系统预留空间 + 根分区过小
- ext4 默认预留5%给root(非root用户无法使用)
- 云服务器初始分区过小(10–25GB),snap/docker安装后快速耗尽
- 其他少见但致命
- core dump 文件(ulimit 未限制)
- 监控工具(如Prometheus)数据目录膨胀
- ZFS/ btrfs 快照未清理
二、诊断流程(推荐顺序)
- 整体概览df -hT → 查看哪个挂载点满(重点看 / 和 /var) df -i → 检查 inode 是否耗尽
- 快速定位大户sudo du -sh /* 2>/dev/null | sort -hr | head -15 通常前几名是 /var、/home、/usr
- 深入 /var(几乎总是罪魁) sudo du -sh /var/* | sort -hr 重点检查:
- /var/log
- /var/lib/docker
- /var/cache
- /var/lib/snapd
- journald 占用journalctl --disk-usage
- 被删除但未释放文件sudo lsof / | grep deleted 或 sudo ls -l /proc/*/fd/* | grep deleted
三、针对性解决方法
1. 清理 journal 日志(最常见解法)
临时清理:
- 保留最近2周:sudo journalctl --vacuum-time=2weeks
- 限制总大小500MB:sudo journalctl --vacuum-size=500M
永久限制(推荐生产环境): 编辑 /etc/systemd/journald.conf(或创建 /etc/systemd/journald.conf.d/override.conf):
text
[Journal]
SystemMaxUse=500M
SystemKeepFree=2G
MaxRetentionSec=4weeks然后 sudo systemctl restart systemd-journald
2. 包管理缓存清理
Bash
sudo apt clean # 清空已下载的deb包
sudo apt autoclean
sudo apt autoremovesnap 清理:
Bash
sudo snap set system refresh.retain=2
sudo snap list --all | awk '/disabled/{print $1, $3}' | while read snapname revision; do sudo snap remove "$snapname" --revision="$revision"; done3. Docker/Podman 清理
Bash
docker system prune -a --volumes # 极致清理(慎用)
# 或分步:
docker image prune -a
docker container prune
docker volume prune4. 释放被删除文件空间
找到占用进程 → 重启/杀掉进程(服务会自动重启) 最安全方式:sudo systemctl restart 对应服务
5. Inode 耗尽解决
查找小文件大户:
Bash
sudo find / -xdev -type f | xargs -I {} ls -l {} | sort -n -k 5 | tail -n 100常见清理:邮件队列、缓存文件、临时小日志。
6. ext4 预留空间调整(可选)
sudo tune2fs -m 1 /dev/sdX1(降到1%)
7. 长期预防机制
- 设置 logrotate 严格轮转 /var/log/*.log
- 监控告警:Netdata/Prometheus + node_exporter 磁盘使用率 >85% 告警
- 云环境:定期扩容根磁盘 + 使用 LVM 动态扩展
- 规划分区:/var、/var/lib/docker、/home 独立挂载点
四、总结优先级处理顺序
- 检查 df -h + df -i
- 清理 journalctl(vacuum-size 500M–1G)
- apt clean + autoremove
- snap 清理旧版本
- docker prune(如果用容器)
- du 定位其他大目录逐个清理
- 重启相关服务释放 deleted 文件
- 如果仍不足 → 扩容磁盘(云平台控制台 + growpart + resize2fs)
磁盘空间不足是服务器运维中最常见的“慢性病”,通过以上诊断+自动化清理(cron + journald 配置),绝大多数情况都能在5–15分钟内解决,并避免反复发生。
版权声明:
作者:后浪云
链接:https://idc.net/help/442451/
文章版权归作者所有,未经允许请勿转载。
THE END
