缩小根分区(Root Partition)无法在系统运行中在线完成。常规做法是通过Rescue Mode 或 Debian Live ISO 引导后再用下面的三个工具。
而我的服务商没有提供iso镜像,rescue进去后也很简陋,工具缺失。gemini提供了这个有趣的方案。完美解决了问题。(我正好有用dropbear,如果没有,也可以新装)。因为正好有sdb,上次我需要修改lvm时候用的办法是dd一个live iso到sdb,更换启动顺序(需要面板支持)。所以下面这个方案简直是简单优雅。

💡 还学到了以后怎么打包其他工具到initramfs。

🚨 警告:在操作前,请务必备份重要数据。

在 Debian/PVE 的默认配置中,e2fsck 会被包含在 initramfs 中用于开机自动修复文件系统,而 resize2fs 被认为是“维护工具”,默认是不会放进启动镜像的。

你需要在正常进入系统手动通过 Hook 脚本将它塞进去。

请按照以下步骤操作:

1. 在运行中的 PVE 中创建 Hook 脚本

你需要创建一个指令文件,告诉 update-initramfs 工具在打包时包含这个二进制文件。

# 创建一个新的 hook 脚本
nano /etc/initramfs-tools/hooks/add_resize2fs

在文件中粘贴以下内容:

#!/bin/sh
PREREQ=""
prereqs() {
    echo "$PREREQ"
}
case $1 in
prereqs)
    prereqs
    exit 0
    ;;
esac

. /usr/share/initramfs-tools/hook-functions

# 强制将 resize2fs 及其依赖库复制到 initramfs 的 /sbin 目录
copy_exec /sbin/resize2fs /sbin

2. 赋予执行权限

这一步非常重要,否则生成镜像时会忽略这个脚本。

chmod +x /etc/initramfs-tools/hooks/add_resize2fs

3. 重新生成 initramfs

执行以下命令来更新你当前的内核启动镜像:

update-initramfs -u

(如果你安装了多个内核,这个命令默认会更新最新的那个。)

4. 关键:验证是否成功包含

在重启之前,你可以直接在当前的 PVE 系统中检查镜像内容,确保 resize2fs 已经在里面了:

# 查看最新的 initrd 镜像中是否含有 resize2fs
lsinitramfs /boot/initrd.img-$(uname -r) | grep resize2fs

如果输出了 /sbin/resize2fs,说明成功了!


5. 现在可以重启进入 Dropbear 操作了

重启 VPS,通过 SSH 连入 Dropbear 界面:

  1. 手动解锁: cryptsetup open /dev/vda3 vda3_crypt
  2. 激活 LVM: lvm vgchange -ay vg
  3. 缩小流程:

    # 先检查(这个你已经有了)
    /sbin/e2fsck -f /dev/mapper/vg-gen
    
    # 现在你应该可以用这个命令了!
    /sbin/resize2fs /dev/mapper/vg-gen 20G
    
    # 缩小 LV 到 20G
    lvm lvreduce -L 20G /dev/vg/gen
    
    # 再次确认对齐
    resize2fs /dev/mapper/vg-gen

    💡 因为配置了 LUKS 加密,层级关系是:物理分区 (vda3) -> 加密层 (vda3_crypt) -> 卷组 (vg) -> 逻辑卷 (gen) -> 文件系统 (ext4)。

    你要调整最里面的“文件系统”和“逻辑卷”,必须在不挂载的情况下,一层层穿透进去操作。

💡 为什么这个方法最好?

  • 无需 ISO: 避开了 VPS 厂商不给挂载 ISO 或救援模式太简陋的问题。
  • 环境纯净: initramfs 阶段没有任何进程占用 / 磁盘,绝对不会出现 "Device or resource busy" 的错误。
  • 远程操作: 只要你能 SSH 进 Dropbear,你就能完成所有底层操作。

注意: 如果你在 initramfs 里运行命令提示 command not found,请尝试使用绝对路径(如 /sbin/resize2fs)。