环境:Dell PowerEdge R730 / Debian 13 宿主机 / KVM+libvirt / Debian 13 虚拟机
目标:将虚拟机磁盘从 30G 扩容到 50G,不影响已有数据
风险等级:⚠️ 中等(涉及分区表操作,务必先备份)
1. 扩容前准备
1.1 确认虚拟机信息
首先列出所有虚拟机,确认目标 VM 的名称和运行状态:
sudo virsh list --all# Id 名称 状态# ------------------------# 1 debian13 运行# 2 arch-vm 运行# - fedora-vm 关闭查看目标 VM 的磁盘配置:
sudo virsh domblklist debian13# 目标 源# ----------------------------------------------# vda /var/lib/libvirt/images/debian.qcow21.2 检查磁盘镜像详情
# VM 运行时需加 --force-sharesudo qemu-img info --force-share /var/lib/libvirt/images/debian.qcow2
# VM 关机后直接查sudo qemu-img info /var/lib/libvirt/images/debian.qcow2输出示例:
image: /var/lib/libvirt/images/debian.qcow2file format: qcow2virtual size: 30 GiB (32212254720 bytes) ← 虚拟大小(对 VM 可见)disk size: 27.4 GiB ← 实际占用宿主机空间cluster_size: 655361.3 确认 VM 内磁盘使用情况
通过 SSH 或 virsh console 进入 VM,查看分区布局和剩余空间:
lsblk# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS# vda 254:0 0 30G 0 disk# ├─vda1 254:1 0 28.4G 0 part /# ├─vda2 254:2 0 1K 0 part# └─vda5 254:5 0 1.6G 0 part [SWAP]
df -h /# 文件系统 大小 已用 可用 已用% 挂载点# /dev/vda1 28G 25G 1.5G 95% /95% 已用,必须扩容了!
判断分区表类型(影响后续操作):
sudo fdisk -l /dev/vda | grep "Disklabel type"# Disklabel type: dos → MBR 分区表# Disklabel type: gpt → GPT 分区表或使用 parted:
sudo parted /dev/vda print | grep "Partition Table"# Partition Table: msdos → MBR# Partition Table: gpt → GPT2. 备份(最重要的一步)
⚡ 无论对操作多有把握,这一步绝对不能跳过。
qemu-img resize本身不删数据,但后续分区调整一旦失误,分区表损坏可能导致数据全部丢失。
2.1 关闭虚拟机
扩容磁盘最好在 VM 关机状态下进行(部分格式支持在线扩容,但关机最安全):
sudo virsh shutdown debian13
# 等待关机完成sudo virsh list --all | grep debian13# - debian13 关闭2.2 检查宿主机剩余空间
确保有足够空间存放备份文件(备份和原文件一样大):
df -h /var/lib/libvirt/images/# 文件系统 大小 已用 可用 已用% 挂载点# /dev/sda1 251G 44G 195G 19% /195G 可用,备份 31G 的 qcow2 绰绰有余。
2.3 执行备份
# 带日期的备份文件名sudo cp /var/lib/libvirt/images/debian.qcow2 \ /var/lib/libvirt/images/debian.qcow2.bak.$(date +%Y%m%d)
# 确认备份完成ls -lh /var/lib/libvirt/images/debian.qcow2*# -rw------- 1 libvirt-qemu libvirt-qemu 31G 6月 3日 11:58 debian.qcow2# -rw------- 1 root root 31G 6月 3日 12:08 debian.qcow2.bak.20260603⚠️ 31G 文件拷贝需要约 2~3 分钟,磁盘 I/O 期间
ls等命令可能卡顿,耐心等待。
3. 扩展虚拟磁盘
3.1 qcow2 格式扩容
# 增加 20Gsudo qemu-img resize /var/lib/libvirt/images/debian.qcow2 +20G
# 或者指定最终大小sudo qemu-img resize /var/lib/libvirt/images/debian.qcow2 50G验证:
sudo qemu-img info /var/lib/libvirt/images/debian.qcow2 | grep "virtual size"# virtual size: 50 GiB (53687091200 bytes) ✅3.2 raw 格式扩容
如果是 raw 格式镜像,方法类似:
sudo qemu-img resize /var/lib/libvirt/images/debian.raw +20G3.3 启动虚拟机验证磁盘大小
sudo virsh start debian13
# 进入 VM 或用 SSH 确认磁盘已变大lsblk# vda 254:0 0 50G 0 disk ← 50G 了!# ├─vda1 254:1 0 28.4G 0 part / ← 但分区还是旧的磁盘总量已变为 50G,但分区和文件系统仍为原来的大小,需要继续扩容。
4. 扩容分区
分区扩容的复杂程度取决于分区表类型和布局。以下分场景说明。
4.1 场景一:GPT 分区表 + 根分区是最后一个分区(最简单)
这是现代 Linux 发行版的典型布局,使用 growpart 一键搞定:
# 安装工具(如未安装)sudo apt install cloud-guest-utils -y
# 扩容第 1 个分区到磁盘末尾sudo growpart /dev/vda 14.2 场景二:MBR 分区表 + 根分区后还有扩展分区和 swap(本文实战)
这是笔者遇到的真实场景——根分区 vda1 后面紧跟着扩展分区 vda2 和 swap vda5,无法直接扩容 vda1,必须先删除后面的分区再重建。
初始布局
vda (30G)├─ vda1 28.4G ext4 /├─ vda2 1K 扩展分区└─ vda5 1.6G swap第 1 步:关闭 swap 并注释 fstab
sudo swapoff /dev/vda5sudo sed -i '/swap/s/^/#/' /etc/fstab第 2 步:删除扩展分区和 swap
sudo parted /dev/vda rm 5 # 删除 swap 逻辑分区sudo parted /dev/vda rm 2 # 删除扩展分区第 3 步:扩容根分区
# 将 vda1 扩容到 48G(留 2G 给后面的 swap)sudo parted /dev/vda resizepart 1 48GiB
parted会警告分区正在使用中,输入Yes确认。resize2fs支持在线扩容,不影响正在运行的系统。
第 4 步:重建 swap 分区
扩容后磁盘布局:
vda (50G)├─ vda1 48G ext4 /└─ 空闲 2G使用 fdisk 重建扩展分区和 swap:
sudo fdisk /dev/vda# n → p → 回车(默认分区号)→ 回车(默认起始扇区)→ 回车(默认结束扇区)# t → 分区号 → 82(Linux swap)# w(写入并退出)也可以用 parted 非交互模式:
sudo parted -s /dev/vda mkpart extended 48GiB 100%sudo parted -s /dev/vda mkpart linux-swap 48GiB 100%第 5 步:格式化 swap 并恢复 fstab
sudo mkswap /dev/vda5sudo swapon /dev/vda5
# 获取新 swap 的 UUIDsudo blkid /dev/vda5# /dev/vda5: UUID="c7117931-8d4f-4145-a23a-9855dc8eb9a4" TYPE="swap"
# 写入 fstabecho 'UUID=c7117931-8d4f-4145-a23a-9855dc8eb9a4 none swap sw 0 0' | sudo tee -a /etc/fstab4.3 场景三:LVM 布局
如果 VM 使用了 LVM(逻辑卷管理),操作路径不同——不需要动分区表,直接在 LVM 层面扩容:
# 1. 让内核识别新磁盘大小echo 1 > /sys/block/vda/device/rescan
# 2. 扩容 PV(物理卷)sudo pvresize /dev/vda2 # 假设 LVM 在 vda2 上
# 3. 扩容 LV(逻辑卷)sudo lvextend -l +100%FREE /dev/mapper/vg0-root
# 4. 扩容文件系统(见第 5 节)LVM 的优势:无需关机、无需删分区、在线完成全部操作。
5. 扩容文件系统
分区扩容后,文件系统还不知道分区变大了,需要执行 resize2fs(ext4)或等价的命令。
5.1 ext4 文件系统
sudo resize2fs /dev/vda1输出示例:
resize2fs 1.47.2 (1-Jan-2025)Filesystem at /dev/vda1 is mounted on /; on-line resizing requiredold_desc_blocks = 4, new_desc_blocks = 6The filesystem on /dev/vda1 is now 12582656 (4k) blocks long.ext4 支持在线扩容(
resize2fs直接作用于已挂载的/),无需卸载或进入恢复模式。
5.2 XFS 文件系统
# XFS 只能在线扩容,且必须指定挂载点sudo xfs_growfs /⚠️ XFS 不支持缩容,只能扩大不能缩小。
5.3 Btrfs 文件系统
# 扩容到分区最大sudo btrfs filesystem resize max /
# 或指定大小sudo btrfs filesystem resize 48G /6. 验证结果
6.1 确认分区布局
lsblk# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS# vda 254:0 0 50G 0 disk# ├─vda1 254:1 0 48G 0 part /# ├─vda2 254:2 0 1K 0 part# └─vda5 254:5 0 2G 0 part [SWAP]6.2 确认文件系统
df -h /# 文件系统 大小 已用 可用 已用% 挂载点# /dev/vda1 48G 25G 20G 56% /6.3 确认 swap
free -h# total used free# 交换: 2.0Gi 0B 2.0Gi6.4 最终对比
| 项目 | 扩容前 | 扩容后 |
|---|---|---|
| 虚拟磁盘 | 30 GB | 50 GB |
根分区 /dev/vda1 | 28.4G (95% 已用) | 48G (56% 已用) |
| Swap | 1.6G | 2.0G |
7. 清理备份
确认系统稳定运行一段时间后(建议 3~7 天),可删除备份释放空间:
# 确认一切正常后执行sudo rm /var/lib/libvirt/images/debian.qcow2.bak.2026060331G 备份文件占地不小,但别急着删——等确认所有服务正常运行后再清理。
8. 常见问题排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
qemu-img: Failed to get shared "write" lock | VM 正在运行 | 加 --force-share 或先关机 |
growpart: unexpected output | 分区表非 GPT | 改用 parted 手动调整 |
parted: Can't have overlapping partitions | 新分区起始位置错误 | 用 unit GiB print free 查看精确边界 |
resize2fs: Bad magic number | 文件系统非 ext4 | 确认文件系统类型:df -T / |
| 扩容后 df 没变化 | 只扩了 PV/LV 没扩文件系统 | 执行 resize2fs/xfs_growfs 等 |
| VM 启动失败 | 分区表损坏 | 从备份恢复:cp debian.qcow2.bak.* debian.qcow2 |
9. 总结
核心流程
备份磁盘 ──► 关机 VM ──► qemu-img resize ──► 启动 VM │ ├── 调整分区 │ ├── GPT: growpart 一键 │ ├── MBR: 删重建 swap + resizepart │ └── LVM: pvresize + lvextend │ └── 扩容文件系统 ├── ext4: resize2fs ├── XFS: xfs_growfs └── Btrfs: btrfs filesystem resize关键要点
- 备份是第一优先级——31G 的磁盘备份只需几分钟,数据恢复可能永远做不到
- 关机扩容最安全——虽然 ext4/XFS 支持在线扩容,但分区表操作建议关机
- MBR 分区表是先删除后重建——根分区后的逻辑分区必须先删,扩容后再重建
- ext4
resize2fs支持在线扩容——即使是根分区/也可以在挂载状态下扩容 - swap 的 UUID 会变——重建 swap 后务必更新
/etc/fstab,否则重启后 swap 不生效
通用扩容命令速查
# === 宿主机 ===sudo virsh shutdown <vm-name>sudo cp <disk-path> <disk-path>.bak.$(date +%Y%m%d)sudo qemu-img resize <disk-path> +<增量>Gsudo virsh start <vm-name>
# === 虚拟机内 ===# GPT 分区sudo growpart /dev/vda 1sudo resize2fs /dev/vda1 # ext4sudo xfs_growfs / # XFSsudo btrfs filesystem resize max / # Btrfs
# LVMsudo pvresize /dev/vda2sudo lvextend -l +100%FREE /dev/mapper/vg0-rootsudo resize2fs /dev/mapper/vg0-root本文记录于 2026 年 6 月 3 日,环境 Debian 13 + libvirt 11.3.0 + QEMU 10.0.8
以下是可爱的评论们:

输入用户名和邮箱后自动检查登录状态。登录后用户名和邮箱将被绑定, 只可以修改头像和主页链接。