调整 KVM 虚拟硬盘大小

在 OpenNebula 上创建 KVM 虚拟机如果没有事先规划好虚拟机硬盘,运行一段时间后可能过小的硬盘会成为麻烦,需要能自由的增加虚拟机硬盘容积,有两个办法:一是可以在 OpenNebula 上动态加入第二块硬盘解决第一块硬盘过小的问题;二是直接在第一块硬盘上扩大容积。第一种办法好办,直接用 virsh attach-disk 就可以。如果和调整 Xen 虚拟硬盘大小一样,不想加第二块硬盘,只想在第一块硬盘上扩大容积呢?这里只讨论虚拟机文件形式的硬盘,LVM 形式的 “硬盘” 更容易一些,可以用 lvextend + fsck 调整硬盘大小。

最简单的办法是使用 GParted,挂载 gparted-live iso 文件后启动图形化界面操作分区,很容易:

# kvm -m 512 -hda disk.0 -cdrom /root/gparted-live-0.12.1-5.iso -boot d -vnc :1

这里主要介绍不用 GParted 的办法,分区用 fdisk 就可以了,没有必要也不适合在服务器上使用图形化工具。扩大硬盘镜像:

# qemu-img resize disk.0 +100GB

找一个空闲的 loop 设备并挂上硬盘镜像:

# losetup -f
/dev/loop0

# losetup /dev/loop0 disk.0

用 fdisk 把以前的分区都删除,然后重新创建分区,如果有 swap 区依然要用类型 82 标注,boot 区要标明 bootable,要非常小心:

# fdisk /dev/loop0

挂载硬盘里面的 LVM 分区、强制校验文件系统并扩大文件系统:

# kpartx -av /dev/loop0 
# e2fsck -f /dev/mapper/loop0p1 
# resize2fs -f /dev/mapper/loop0p1 

用 mount 测试一下扩大后的文件系统是否能正常 mount:

# mount /dev/mapper/loop0p1 /mnt
# ls /mnt

卸载和清理:

# umount /mnt
# kpartx -dv /dev/loop0 
# losetup -d /dev/loop0

把上面的步骤弄个小脚本,只对 http://cloud-images.ubuntu.com/ 下载的镜像有效,如果是自己做的镜像需要调整 fdisk 分区时候的指令。注意这里 fdisk 分区的时候 d 是删除分区 n 是创建分区 p 是主分区 1 是第1个 2是第2个 w 是保存,具体看 fdisk 帮助:

#!/bin/bash

DISK=$1
SIZE=$2

qemu-img resize $DISK $SIZE

losetup /dev/loop0 $DISK
fdisk /dev/loop0 <<EOF
d
n
p
1
2

w
EOF

kpartx -av /dev/loop0
e2fsck -f /dev/mapper/loop0p1
resize2fs -f /dev/mapper/loop0p1
kpartx -dv /dev/loop0

losetup -d /dev/loop0

评论 (8 Comments)

  1. 能否这样做到:如果原来vm有2块硬盘(用qemu-img create -f qcow2 os.img 10G;qemu-img create -f qcow2 data.img 40G创建),第一块是虚拟机os所在的硬盘,第二块是存放用户数据的磁盘并分了一个分区sb1,且sdb1上没有使用lvm,当对第二块磁盘进行扩容的时候,如40G=>100G后;能否可以直接看到vm系统里面sb1大小为100G,并且不损坏原来的数据??如果可以怎么做??谢谢!

  2. @wopub
    可以,方法和 http://www.vpsee.com/2009/09/resize-xen-vm-image/ 差不多:
    1、dd if=/dev/zero bs=1024k count=60000 >> data.img
    2、e2fsck -f data.img
    3、resize2fs data.img

  3. qemu-img resize 可以一试.最近在思考个问题,Openstack现在怎样了?

  4. 1、dd if=/dev/zero bs=1024k count=60000 >> data.img
    2、e2fsck -f data.img
    3、resize2fs data.img
    无法实现啊,错误如下:

    [root@localhost test2]# dd if=/dev/zero bs=1024k count=1024 >> data.img
    记录了10+0 的读入
    记录了10+0 的写出
    10737418240字节(11 GB)已复制,375.078 秒,28.6 MB/秒
    [root@localhost test2]# ls
    os.img
    [root@localhost test2]# e2fsck -f data.img
    e2fsck 1.41.12 (17-May-2010)
    e2fsck: 超级块无效, trying backup blocks…
    e2fsck: Bad magic number in super-block 当尝试打开 data.img 时

    The 超级块 could not be read or does not describe a correct ext2
    文件系统. If the 设备 is valid and it really contains an ext2
    文件系统 (and not swap or ufs or something else), then the 超级块
    is corrupt, and you might try running e2fsck with an alternate 超级块:
    e2fsck -b 8193

    [root@localhost test2]#

  5. @wopub
    要确认 data.img 里面的内容,是否包含多个分区、是否包含 lvm 等,上面办法只适合一个 / 分区的情况,有多个分区的话会更麻烦。

  6. vpsee大侠,我按照你的方法步骤,到这步骤就不行了:
    # fdisk /dev/loop0
    里面根本没有分区信息的,本来我的虚拟镜像文件,是有很多分区的,现在为什么没有呢。能否麻烦vpsee大侠再测试一遍,找个有一个或多个分区的虚拟磁盘文件。谢谢(qcow2的哦)!

  7. 我下载个img文件wget
    https://launchpad.net/cirros/trunk/0.3.0/
    +download/cirros-0.3.0-x86_64-disk.img (20M大小的镜像文件),按照你的方法,不行哦,谢谢vpsee大侠,帮我验证下。谢谢!

  8. 多个分区需要用virt-resize了

发表评论