soarli

从宕机到扩容:ESXi中Ubuntu虚拟机“磁盘已满”实战救援全记录
前言:恐慌的开端“周末的早晨,告警邮件如期而至。” —— 这恐怕是每个运维工程师的噩梦。当我尝试启动一台重要的 G...
扫描右侧二维码阅读全文
19
2025/10

从宕机到扩容:ESXi中Ubuntu虚拟机“磁盘已满”实战救援全记录

前言:恐慌的开端

“周末的早晨,告警邮件如期而至。” —— 这恐怕是每个运维工程师的噩梦。当我尝试启动一台重要的 GitLab 虚拟机(运行在 ESXi 上的 Ubuntu Server)时,屏幕上滚动着熟悉的启动日志,最后却无情地停在了一行红色的 [FAILED] 上:

[FAILED] Failed to start Create Volatile Files and Directories.
see 'systemctl status systemd-tmpfiles-setup.service' for details.
...
[FAILED] Failed to start Network Name Resolution.
...

系统无法正常启动,服务全面中断。这就是我们今天故事的开始:一次由磁盘空间耗尽引发的“血案”,以及一次从紧急救援到彻底根治的全过程记录。

Part 1:紧急救援 - 在只读的世界里杀出一条血路

systemd-tmpfiles-setup.service 失败通常指向一个根本原因:根分区 (/) 被 100% 占满了。系统连创建临时文件的空间都没有,后续所有服务自然接连崩溃。

我们的首要目标是进入系统,清理出哪怕只有几百MB的空间,让系统能成功启动。

  1. 进入恢复模式:重启虚拟机,在 GRUB 菜单选择 "Advanced options for Ubuntu",然后进入 "Recovery mode"。
  2. 获取读写权限的 Shell:在恢复菜单中,选择 root (Drop to root shell prompt)。此时你会进入一个命令行,但注意,文件系统默认是只读 (read-only) 的。必须执行以下命令,将其重新挂载为可读写,否则任何删除操作都会失败:

    mount -o remount,rw /
  3. 定位并清理空间:现在,我们可以开始“瘦身”了。

    • 确认病因df -h 果不其然,根分区 /Use% 显示为 100%
    • 分析元凶:通过 du -h --max-depth=1 /var | sort -rh 逐层分析,我们很快定位到 /var/lib/docker (47G) 和 /var/lib/snapd (3.9G) 是两大元凶。
    • 安全清理

      • 清理 Docker:Docker 提供了安全清理的命令,它只会删除未被使用的资源,不会影响正在运行的服务。

        # 清理所有未使用的容器、网络、镜像和构建缓存
        docker system prune
        
 - **清理 Snap**:Snap 会保留旧版本的包,非常占用空间。以下脚本可以安全地删除所有被禁用的旧版本:
snap list --all | awk '/disabled/{print $1, $3}' | while read snapname revision; do snap remove "$snapname" --revision="$revision"; done

经过这两步,我们成功释放了数GB的空间。此时,执行 reboot,虚拟机终于正常启动了!

Part 2:防患未然 - 在扩容前备份一切

系统虽然恢复了,但治标不治本。为了彻底解决问题,我们决定扩容磁盘。但在进行这种“高危操作”之前,备份是雷打不动的铁律

幸运的是,这台 GitLab 是通过 Docker 数据卷部署的,所有数据都映射在主机的 /mnt/gitlabdata 目录下。

我们使用 tar 命令进行打包,但有一个技巧:必须将生成的备份包自身从打包范围中排除,否则会陷入无限循环。

# -C 参数先切换到目标目录,避免打包时带有绝对路径
# --exclude 参数排除了备份文件自身
sudo tar --exclude='gitlab-backup-*.tar.gz' \
     -czvf /mnt/gitlabdata/gitlab-backup-$(date +%F).tar.gz \
     -C /mnt/gitlabdata .

执行完毕后,一个以日期命名、包含所有数据的完整备份包静静地躺在了 /mnt/gitlabdata 目录中。我们心中大定。

Part 3:核心操作 - 扩容硬盘并让系统识别

扩容分为两步:在 ESXi 层面扩大虚拟磁盘,然后在 Ubuntu 系统内部让分区和文件系统识别到新空间。

1. ESXi层面:搞定“快照”拦路虎

  • 关机并尝试扩容:我们先关闭虚拟机,在 ESXi 的“编辑设置”中尝试将硬盘从 60GB 改为 160GB。
  • 遭遇报错:“设备‘3’的操作无效”。这是一个经典错误,99% 的原因是虚拟机存在快照。ESXi 不允许在有快照的情况下修改虚拟磁盘的结构。
  • 解决:右键虚拟机 -> 快照 -> 快照管理器,点击 “全部删除”。注意,这里的“删除”实际上是将快照数据合并回主磁盘,会保留所有数据。等待合并任务完成后,我们再次编辑设置,成功将硬盘容量扩展到了 160GB。

2. Ubuntu系统层面:从分区到文件系统

这是最关键也最容易出错的一步。

  • 第一道坎:找对设备名

教程常以 /dev/vda 为例,但我们的系统识别为 /dev/sda。永远不要盲从教程,lsblk 命令才是你的真相之源。

lsblk
# NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
# sda      8:0    0   160G  0 disk 
# └─sda1   8:1    0    60G  0 part /

输出清晰地告诉我们:硬盘是 /dev/sda,需要操作的分区是 /dev/sda1

  • 第二步:扩展分区 (parted)

parted 是一个强大的分区工具,它的操作对象是整块硬盘。

sudo parted /dev/sda

进入 (parted) 交互模式后,我们执行 resizepart 命令。

(parted) resizepart
Partition number? 1
End? [64.4GB]? 100%

输入分区号 1,并将结束位置设为 100%,这是一个绝佳的技巧,能自动将分区扩展到磁盘的全部可用空间。完成后输入 quit 退出。

  • 第三步:扩展文件系统 (resize2fs)

分区边界虽然扩大了,但分区内部的文件系统(你可以理解为货架)还停留在旧的大小。resize2fs 的作用就是通知文件系统去铺满整个分区。它的操作对象是分区。

sudo resize2fs /dev/sda1

命令瞬间执行完毕。

  • 最后验证

    df -h

输出结果中,/dev/sda1 的 Size 一栏赫然显示着 157G。至此,扩容大功告成!

总结

这次从宕机到扩容的经历,再次印证了几个系统管理的基本原则:

  1. 监控是生命线:主动的磁盘空间监控能避免 99% 的此类事故。
  2. 理解工具而非死记命令:知道 lsblk 比记住 /dev/sda 重要得多;理解“硬盘vs分区”的区别,才能正确使用 partedresize2fs
  3. 快照是双刃剑:快照是备份和恢复的利器,但也是日常运维(如扩容)的“拦路虎”。要养成定期清理、合并快照的习惯。
  4. 备份,备份,还是备份:在任何高危操作前,一个可靠的备份是你敢于点击“确认”按钮的最大底气。

希望这次的实战记录,能为遇到类似问题的朋友提供一份清晰的行动指南。

最后修改:2025 年 10 月 19 日 03 : 58 AM

发表评论