Linux虚拟机硬盘空间不足时,先别急着加硬盘,用df -h和du -sh定位空间去哪儿了,再判断是清理还是扩容多数生产环境下的长期方案是扩容虚拟磁盘。
linux虚拟机磁盘空间不足怎么解决:先分清现状再动手
空间不足的场景分两类:一类是临时性拥堵,日志和缓存把根分区塞满;另一类是结构性不足,系统盘本身太小,前者清理就能缓解,后者需要从虚拟机层面扩大磁盘。
三分钟定位空间占用大户
执行df -h,先看哪个分区达到了90%以上,通常是根分区,接着用du -sh /var /usr /home等目录逐一排查,如果发现/var/log占了好几个G,直接进入下一步清理;usr或/home体积异常,要看看是不是装了太多软件或数据。
目录排查顺序建议从这几个最常出问题的地方开始:
- /var/log:日志文件,长期不清理会持续膨胀
- /var/cache:apt或yum的安装包缓存
- /tmp:临时文件堆积
- /var/lib/docker:容器日志和镜像层
清理还是扩容,怎么选
| 场景 | 推荐做法 | 原因 |
|---|---|---|
| 日志缓存占满 | 清理 | 恢复速度快,不动磁盘结构 |
| 根分区本身只有20G | 扩容 | 治标也治本,避免反复告警 |
| LVM分区且有多余空间 | 扩容 | lvextend操作不影响现有数据 |
| 单机测试环境 | 清理或快照回滚 | 优先级取决于时间成本 |
如果你只有一台测试用的KVM虚拟机,清理完日志能继续跑就先用着;如果是生产环境的centos虚拟机,建议直接把磁盘扩容一步到位,省得隔两周又告警一次。
linux虚拟机扩容硬盘空间命令:从宿主机到虚拟机逐步操作
扩容不只是在fdisk里加分区那么简单,整个链路是:宿主机调整虚拟磁盘→虚拟机内识别新空间→分区扩展→文件系统扩展,任何一环漏了,df -h里都不会有变化。
第一步:在宿主机把虚拟磁盘变大
vmware虚拟机linux磁盘扩容最直观,在vSphere或Workstation里找到虚拟机的"编辑设置",把硬盘大小从20G调到40G,点击确定就能完成,KVM环境则用virsh vol-resize /var/lib/libvirt/images/test.qcow2 40G,或者对qcow2执行qemu-img resize。
这一步不会损坏现有数据,但强烈建议操作前先做一次快照,尤其是生产环境,磁盘扩容本身不影响虚拟机关机或开机状态,但后续分区调整最好在虚拟机内操作,尽量选业务低峰期。
第二步:虚拟机内让系统识别到新空间
进入虚拟机,执行lsblk查看块设备,如果原磁盘是/dev/vda,扩容后通常会看到未分配的空间出现在末尾,此时要用fdisk或parted把新空间划入原有分区,以fdisk为例:
- fdisk /dev/vda
- p查看当前分区表,记下起始扇区
- d删除原分区(或创建新分区),但删除后要立即n重新建同一个分区,起始位置保持一致
- w写入分区表
这个过程很多初学者会慌,担心数据会丢,实际上只要起始扇区不变、文件系统没动,数据都在,稳妥起见,操作前把分区表备份一份到文件里。
第三步:扩展文件系统完成最后一步
分区表更新后,用partprobe重新加载,然后根据文件系统类型选择命令:
- ext4:resize2fs /dev/vda1
- xfs:xfs_growfs /mnt(或挂载点)
- 如果用了LVM:先用pvresize扩展物理卷,再lvextend -l +100%FREE扩展逻辑卷,最后resize2fs
操作完成后,df -h里就能看到容量变化,整个流程大约需要5到10分钟,难点不在命令,在于理解分区、物理卷、逻辑卷这三层关系,LVM架构下,逻辑卷可以单独调整,灵活性更高,这也是很多Linux生产环境默认用LVM的原因。
不想扩容?那就用这些linux虚拟磁盘空间清理方法
有些场景下扩容不是最优解,比如你手上的虚拟磁盘已经几百G,实际只是日志写满了,那清理是更快的方案。
journald日志:占空间的隐形大户
systemd的日志组件journald默认会一直保留日志,时间长了体积很可观,用journalctl --disk-usage看占用,然后执行:
- journalctl --vacuum-size=100M:保留日志总大小不超过100M
- journalctl --vacuum-time=7d:只保留最近7天的日志
这两个命令立即生效,删完能腾出好几个G都常见,顺便把/etc/systemd/journald.conf里的SystemMaxUse改成100M,之后日志会自动轮转,不会再无限膨胀。
清理包管理器缓存和无用内核
apt和yum都会把下载的安装包缓存到本地,一个包几百M很常见。
- Debian/Ubuntu:apt-get clean && rm -rf /var/lib/apt/lists/
- CentOS/RHEL:yum clean all
内核升级后旧版本不会自动删除,/boot分区经常因此告警,执行dpkg --list | grep linux-image看看有几个内核,旧版本用apt-get purge卸载,CentOS里则用yum remove卸载旧内核,卸载前务必保留至少一个当前使用的内核,别把系统搞到起不来。
容器环境下,/var/lib/docker/containers目录下的json.log日志也经常撑爆磁盘,截断日志文件用cat /dev/null > 对应json.log,或者直接在docker run时加--log-opt max-size=10m参数限制日志大小。
找找被删除但还占着空间的文件
进程还在写某个已经删除的文件,文件系统不会真正释放空间,df -h显示满了,但du统计各个目录怎么加都对不上,执行lsof | grep deleted,找出这些文件,重启对应进程或kill掉,空间就回来了,这种情况在nginx写日志、数据库临时文件的场合经常出现。
虚拟磁盘文件瘦身完成后,宿主机的磁盘能还回来吗
虚拟机里的文件删了,宿主机上的磁盘文件不一定会变小,因为qcow2这种稀疏格式需要专门的回收机制,如果你用的是KVM/qcow2,在虚拟机内执行fstrim释放未使用块,然后在宿主机上执行qemu-img measure或virt-sparsify对镜像进行瘦身,行业共识认为,这个操作能帮助虚拟磁盘文件保持合理的物理大小,避免宿主机存储被大量占用。
VMware的环境里,这个环节对应的是"收缩磁盘"功能,需要在虚拟机关机状态下执行,效果就是让vmdk文件恢复到接近实际使用量的大小。
关于linux虚拟机硬盘空间不足的3个高频问题
Q: linux虚拟机磁盘空间不足怎么解决最省事?
A: 先清理journald日志和包缓存,通常能腾出好几个G,如果根分区本身只有二三十G,直接扩容虚拟磁盘并扩展文件系统,一步到位,不用反复清理。
Q: 扩容分区时提示分区表损坏或无法写入怎么办?
A: 大概率是分区还在挂载中或磁盘有保留扇区,确认原分区已卸载,或使用parted的resizepart命令在线调整,修改结束后同步更新/etc/fstab里对应分区的UUID。
Q: 为什么扩容了df -h没有显示变化?
A: 文件系统层面没扩展,扩容链路是虚拟磁盘→分区→文件系统,只完成第一层是不够的,用lsblk确认新空间是否已划入分区,再对文件系统执行resize2fs或xfs_growfs。
Linux虚拟机的空间管理是持续的事情,日志轮转、缓存清理、定期检查占用应该成为一种习惯,遇到告警别急着加硬盘,先看清空间去哪儿了,再决定清理还是扩容,两种方法结合起来,虚拟机的硬盘空间问题基本都能在半小时内解决。