海滨擎蟹

vagrant + virturalbox 的虚拟机扩容与缩容

前言

本地的环境是按照公司的文档搭建的 vagrant + virturalbox + docker-ce 的开发环境。其中的 vagrant + virturalbox 主要是为创建虚拟机服务的,之前的 Mac M1 下 vagrant + virturalbox + docker-ce 搭建开发环境 有提到,选择的是 ubuntu 22.04 arm64 版本。

之前因为实践了一把 mysql 导入导出大体积 sql 失败了,导致虚拟机磁盘使用率暴增,直接就满了。最后搞来搞去虚拟机里的 mariadb 服务彻底废了(正常无法启动的那种),不得已使用了宿主机上的 docker 的 mariadb 服务。

此时对于磁盘被占用隐约觉得是数据库的问题,但并没有清晰的认知,所以考虑的仍然是给虚拟机扩容,分配更多的磁盘空间。直接向 deepseek 要了一份扩容的步骤指令,将当前的 40 G 升级到 100 G。

vagrant 虚拟机扩容

因为原磁盘 vmdk 类型不适合扩展,需要先转换为 vdi 格式,之后再通过 VBoxManage 指令进行调整磁盘大小。

第 1 步:准备虚拟机
主要是清理垃圾为下一步复制做准备。

# 1. 登录虚拟机清理空间
vagrant ssh

# 清理系统垃圾
sudo apt clean
sudo apt autoremove --purge -y
sudo journalctl --vacuum-time=1d

# 2. 填充零(重要!这样压缩效果更好)
# 创建大文件填充未使用空间
sudo dd if=/dev/zero of=/zero.fill bs=1M
sudo rm -f /zero.fill

# 3. 关机
exit
vagrant halt

第 2 步:转换磁盘格式

# 在宿主机上执行(确保 VirtualBox 安装路径在系统 PATH 中)

# 1. 进入 Vagrant 项目目录
cd /path/to/your/vagrant-project

# 2. 找到 VMDK 文件(通常在 .vagrant 目录下)
# 或者使用 VirtualBox 管理界面查看磁盘文件路径

# 3. 转换 VMDK 到 VDI
VBoxManage clonehd "box-disk001.vmdk" "new-disk.vdi" --format vdi

# 如果要压缩转换后的磁盘
VBoxManage clonehd "box-disk001.vmdk" "new-disk.vdi" --format vdi --variant Standard

第 3 步:调整磁盘大小

# 1. 扩容到更大尺寸(如果需要)
VBoxManage modifymedium "new-disk.vdi" --resize 51200  # 单位 MB,这里是 50GB

# 或缩容到 20GB(你的需求)
VBoxManage modifymedium "new-disk.vdi" --resize 20480  # 20GB = 20480MB

# 2. 压缩磁盘(减少实际文件大小)
VBoxManage modifymedium disk "new-disk.vdi" --compact

第 4 步:替换虚拟机的磁盘
也可以在 virtualBox 中关闭虚拟机之后设置-存储-虚拟硬盘 进行切换。

# 1. 查看虚拟机名称
VBoxManage list vms

# 2. 找到要替换的虚拟机的 UUID 或名称
# 假设虚拟机名称为 "your-vagrant-project_default_1234567890"

# 3. 分离旧磁盘
VBoxManage storageattach "虚拟机名称" \
    --storagectl "SATA Controller" \
    --port 0 \
    --device 0 \
    --type hdd \
    --medium none

# 4. 附加新磁盘
VBoxManage storageattach "虚拟机名称" \
    --storagectl "SATA Controller" \
    --port 0 \
    --device 0 \
    --type hdd \
    --medium "new-disk.vdi"

第 5 步:扩展文件系统(重要!)

# 1. 启动虚拟机
vagrant up
vagrant ssh

# 2. 查看磁盘分区
sudo fdisk -l
# 你会看到类似 /dev/sda 的磁盘

# 3. 如果使用了 LVM(你的系统显示是 LVM)
# 查看物理卷、卷组、逻辑卷
sudo pvdisplay
sudo vgdisplay
sudo lvdisplay

# 4. 扩展物理卷
# 先查看 LVM 结构
lsblk
# 示例输出:
# └─sda3                  8:3    0    95G  0 part
#   └─ubuntu--vg-ubuntu--lv 253:0    0    95G  0 lvm /

# 5. 如果有可用空间,扩展逻辑卷
# 扩展逻辑卷到所有可用空间
sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv

# 或指定大小
sudo lvextend -L 20G /dev/ubuntu-vg/ubuntu-lv

# 6. 调整文件系统大小
# 对于 ext4 文件系统
sudo resize2fs /dev/ubuntu-vg/ubuntu-lv

# 对于 xfs 文件系统
sudo xfs_growfs /

第 6 步:如果没有使用 LVM(直接分区)

# 1. 安装分区工具
sudo apt-get update
sudo apt-get install -y gparted cloud-guest-utils

# 2. 使用 growpart 扩展分区
# 查看分区号
lsblk
# 假设是 /dev/sda3

# 扩展分区
sudo growpart /dev/sda 3

# 3. 扩展文件系统
# 对于 ext4
sudo resize2fs /dev/sda3

# 对于 xfs
sudo xfs_growfs /dev/sda3

如何判断是否使用了 lvm

1、df -h 输出中有 /dev/mapper/ 开头的设备

2、lsblk 输出中有 lvm 类型

3、/dev/mapper/ 目录中有控制文件以外的设备

4、pvsvgslvs 命令有输出

5、/etc/fstab 中有 /dev/xx/mapper//dev/xx/dm- 设备

> ll /dev/mapper/
total 0
drwxr-xr-x  2 root root      80 Feb  4 07:30 ./
drwxr-xr-x 19 root root    4000 Feb  4 07:30 ../
crw-------  1 root root 10, 236 Feb  4 07:30 control
lrwxrwxrwx  1 root root       7 Feb  4 07:30 ubuntu--vg-ubuntu--lv -> ../dm-0

> cat /etc/fstab | grep -v "^#"
/dev/disk/by-id/dm-uuid-LVM-WpGMeyH4J1q2c5oVktJ36ByDdcpEOGHwe0oIjht4ej4DpIZ9r6981Ha9HeQ0MHI7 / ext4 defaults 0 1
/dev/disk/by-uuid/0ea2276c-df80-4c2e-9600-97ba7c7c7fb2 /boot ext4 defaults 0 1
/dev/disk/by-uuid/9079-E89A /boot/efi vfat defaults 0 1
/swap.img    none    swap    sw    0    0

vagrant 虚拟机清理大文件

虚拟机里的磁盘空间被占满了,在扩容之后缓解了这种情况。但个人还是想要清理一下虚拟机的空间,因为感觉上现有内容不会占用到这么多。

df -h 查看当前磁盘使用情况,一开始被 vagrant NFS共享文件夹吸引了,因为显示的大小是整个宿主机的磁盘大小,太大了。结果通过 udo du -sh * .[^.]* 2>/dev/null | sort -rh | head -20 排查目录下实际大小并没有那么大,不是项目文件过大,而是由NFS共享引起的统计异常或文件系统误报。

进一步查看是那个文件夹占用了最大的空间:

sudo du -xh / 2>/dev/null | grep -v '/var/lib/project_name' | sort -rh | head -20
63G    /
57G    /var
46G    /var/lib
42G    /var/lib/mysql
11G    /var/log
8.4G    /var/log/mysql
3.1G    /var/lib/docker
3.0G    /var/lib/docker/overlay2
...

因为这里的 mysql 已经迁移走了,所以虚拟机内部的 mysql 可以直接删除。删除之后 df -lh 发现分配的空间又多了很多,下一步就需要释放一些用不到的空间。

vagrant 虚拟机缩容

宿主机空间有限,需要尽可能的压缩不需要的虚拟机空间。问了 deepseek 可以( vdi 100G->50G),但需要先缩小文件系统,再缩小虚拟磁盘。这个顺序很重要,与扩容相反。

第 1 步:准备虚拟机
# 1. 登录虚拟机
vagrant ssh

# 2. 清理系统垃圾
sudo apt clean
sudo apt autoremove --purge -y
sudo journalctl --vacuum-time=1d

# 3. 清理 lims2 目录的大文件(这是你之前的大头)
sudo du -sh /var/lib/lims2/*
# 清理不需要的备份、缓存、日志等

第2步:缩小文件系统
根据你的输出,你使用的是 LVM,所以需要缩小逻辑卷:

# 1. 查看当前磁盘使用情况
df -h
lsblk

# 输出示例:
# /dev/mapper/ubuntu--vg-ubuntu--lv   96G   10G   82G  11% /
# 这显示逻辑卷当前是 96G

# 2. 卸载目标分区(如果是根分区,需要进入救援模式)
# 因为不能在线缩小根分区,需要从 Live CD/USB 启动
# 但我们可以尝试使用 systemd-nspawn 或其他方法

# 3. 检查文件系统类型
sudo blkid /dev/mapper/ubuntu--vg-ubuntu--lv

# 4. 先缩小文件系统(EXT4 示例)
# 估算当前实际使用量,留出20%余量
sudo du -sh /  # 查看实际使用空间,假设是 15G
# 我们目标 50G,足够

# 对于在线缩小(如果支持)
sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv 40G

第3步:缩小逻辑卷

# 1. 缩小文件系统到 45G(先于逻辑卷缩小)
sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv 45G

# 2. 缩小逻辑卷到 50G
sudo lvreduce -L 50G /dev/mapper/ubuntu--vg-ubuntu--lv

# 3. 再次调整文件系统填满逻辑卷
sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv

第4步:使用 Live 环境缩小根分区
...
第5步:缩小虚拟磁盘(在宿主机)

# 1. 填充零以优化压缩
vagrant ssh
sudo dd if=/dev/zero of=/zero.fill bs=1M
sudo rm -f /zero.fill
exit

# 2. 关闭虚拟机
vagrant halt

# 3. 尝试直接缩小 VDI(VirtualBox 可能不支持直接缩小)
# 但可以克隆到更小的磁盘
VBoxManage clonehd "ubuntu-22.04-aarch64-disk001.vdi" "ubuntu-50g.vdi" --format vdi --variant Standard

# 4. 如果上面命令不行,需要先转换到 raw 格式
VBoxManage clonemedium "ubuntu-22.04-aarch64-disk001.vdi" "temp.raw" --format raw

# 5. 使用 truncate 或 qemu-img 缩小 raw 镜像
# 安装 qemu-utils 如果还没有
sudo apt-get install qemu-utils
qemu-img resize -f raw "temp.raw" 50G

# 6. 转换回 VDI
VBoxManage convertfromraw "temp.raw" "ubuntu-50g.vdi" --format vdi --variant Standard

# 7. 压缩
VBoxManage modifymedium disk "ubuntu-50g.vdi" --compact

结果在缩小文件系统的时候就报错了:

sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv 40G
resize2fs 1.46.5 (30-Dec-2021)
resize2fs: New size smaller than minimum (25873329)

也不知道怎么搞的,缩容的时候占用的磁盘空间 10 几个GB,但按照 NFS共享目录的占用(100GB)去判断的。结果就是没办法在线缩,只能采用另一种填充零的方式进行压缩:

# 1. 清理虚拟机内的无用文件
vagrant ssh
sudo apt clean  # 清理 apt 缓存
sudo journalctl --vacuum-time=3d  # 清理日志
exit

# 2. 在虚拟机内填充零(供压缩)
vagrant ssh
sudo dd if=/dev/zero of=/EMPTY bs=1M
sudo rm -f /EMPTY
exit

# 3. 关闭虚拟机
vagrant halt

# 4. 压缩虚拟磁盘
# 找到你的磁盘文件路径(在 VirtualBox 管理界面查看)
cd "你的Vagrant项目目录"

# 压缩磁盘
VBoxManage modifymedium disk "你的磁盘路径.vdi" --compact

这个方法非常有效,vdi 虚拟机文件一下子由之前的 75GB 降到了 9.6GB。

压缩 vagrant 虚拟机磁盘空间后,启动报错

vagrant up 启动报错:

default: Configuring and enabling network interfaces...
/opt/vagrant/embedded/gems/gems/net-scp-4.1.0/lib/net/scp.rb:412:in `await_response_state': scp: /tmp/vagrant-network-entry-1769506445: No space left on device (Net::SCP::Error)

在一些 vim 编辑保存文件时,也会因为 No Space 报错。在执行 deepseek 给的一些清理指令,如:sudo apt autoremove 都无法成功。

> VBoxManage showmediuminfo "VirtualBox VMs/xx_default_1753346716353_7111/ubuntu-22.04-aarch64-disk001.vdi"
UUID:           a6e7810c-8181-497e-b6f4-f14935026607
Parent UUID:    base
State:          created
Type:           normal (base)
Location:       /Users/xx/VirtualBox VMs/xx_default_1753346716353_7111/ubuntu-22.04-aarch64-disk001.vdi
Storage format: VDI
Format variant: dynamic default
Capacity:       102400 MBytes
Size on disk:   9281 MBytes
Encryption:     disabled
Property:       AllocationBlockSize=1048576
In use by VMs:  jasonli_default_1753346716353_7111 (UUID: dfcc2cc2-6e0a-4154-b2a4-6ca915cc2592)

当前磁盘容量是 102400 MBytes (100GB),但磁盘上实际只用了 9281 MBytes (约9GB)。这意味着您之前尝试缩小到 20GB 应该是可以的(因为实际数据只有9GB),但 VirtualBox 不支持缩小操作(或者说操作失败)。是因为磁盘空间已经 100% 被占用了:

df -h
Filesystem                              Size  Used Avail Use% Mounted on
tmpfs                                   379M  5.7M  373M   2% /run
/dev/mapper/ubuntu--vg-ubuntu--lv        96G   96G     0 100% /
tmpfs                                   1.9G     0  1.9G   0% /dev/shm
tmpfs                                   5.0M     0  5.0M   0% /run/lock
/dev/sda2                               2.0G  124M  1.7G   7% /boot
/dev/sda1                               1.1G  6.4M  1.1G   1% /boot/efi
192.168.33.1:/Users/xx/Code/yy  229G  137G   92G  60% /var/lib/yy
tmpfs                                   379M  4.0K  379M   1% /run/user/1000

尝试扩充磁盘到 120 GB,但 LVM 逻辑卷没有自动扩展,手动操作还是会因为空间不足而失败:

> sudo growpart /dev/sda 3
mkdir: cannot create directory ‘/tmp/growpart.1602’: No space left on device
FAILED: failed to make temp dir
vagrant@vagrant:~$ sudo pvresize /dev/sda3
  /etc/lvm/archive/.lvm_vagrant_1614_1579752142: write error failed: No space left on device
  0 physical volume(s) resized or updated / 1 physical volume(s) not resized
vagrant@vagrant:~$ sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
  New size (24818 extents) matches existing size (24818 extents).
vagrant@vagrant:~$ sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
resize2fs 1.46.5 (30-Dec-2021)
The filesystem is already 25413632 (4k) blocks long.  Nothing to do!

之后偶然清理了内核文件,释放了大概几百M 的空间,然后就不报错了。

# 清理旧的内核文件
# 查看当前内核
uname -r

# 列出所有已安装的内核
dpkg -l | grep linux-image

# 删除旧的内核(保留当前运行的)
sudo apt-get remove --purge $(dpkg -l 'linux-image-*' | awk '/^ii/{print $2}' | grep -v $(uname -r)) -y

这时候扩展逻辑卷并查看磁盘使用情况:

# 1. 先扩展分区
sudo growpart /dev/sda 3

# 2. 重新扫描磁盘分区
sudo partprobe /dev/sda

# 3. 扩展物理卷
sudo pvresize /dev/sda3

# 4. 查看可用的扩展空间
sudo vgdisplay ubuntu-vg | grep Free

# 5. 扩展逻辑卷
sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv

# 6. 扩展文件系统
sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv

# 7. 验证
df -lh
Filesystem                         Size  Used Avail Use% Mounted on
tmpfs                              379M  1.7M  377M   1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv  115G   95G   16G  87% /
tmpfs                              1.9G     0  1.9G   0% /dev/shm
tmpfs                              5.0M     0  5.0M   0% /run/lock
/dev/sda2                          2.0G  124M  1.7G   7% /boot
/dev/sda1                          1.1G  6.4M  1.1G   1% /boot/efi
xx                                 229G  129G  100G  57% /var/lib/xx
tmpfs                              379M  4.0K  379M   1% /run/user/1000

此时可以看到,根目录占用的太大了,这与我之前清理 mysql 之后的预期不符,再次查看是什么大文件导致的:

sudo du -sh /* 2>/dev/null | sort -h
0    /bin
0    /dev
0    /lib
0    /proc
0    /sbin
0    /sys
4.0K    /cdrom
4.0K    /media
4.0K    /mnt
4.0K    /srv
4.0K    /vagrant
16K    /lost+found
64K    /tmp
144K    /root
1.7M    /run
6.0M    /etc
14M    /opt
131M    /boot
946M    /data
963M    /home
1.4G    /snap
1.8G    /usr
3.7G    /swap.img
86G    /EMPTY

看着这个 /EMPTY 有点眼熟,再三确认,这就是之前压缩磁盘空间应该删除掉的用零填充的文件。

> head -c 100 /EMPTY | xxd | head -5
00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
> tail -c 100 /EMPTY | xxd | head -5
00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................

删除 EMPTY 之后,磁盘终于恢复正常使用大小。

> sudo rm -f /EMPTY
> df -h
Filesystem                                 Size  Used Avail Use% Mounted on
tmpfs                                      379M  1.7M  377M   1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv          115G  9.6G  101G   9% /
tmpfs                                      1.9G     0  1.9G   0% /dev/shm
tmpfs                                      5.0M     0  5.0M   0% /run/lock
/dev/sda2                                  2.0G  124M  1.7G   7% /boot
/dev/sda1                                  1.1G  6.4M  1.1G   1% /boot/efi
192.168.33.1:/Users/xx/Code/yy             229G  128G  101G  57% /var/lib/yy
192.168.33.1:/Users/xx/Code/zz.            229G  128G  101G  57% /data/zz
tmpfs                                      379M  4.0K  379M   1% /run/user/1000

之后可以再尝试正常的缩容。

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »