pve 之上的虚拟机,需要依托硬盘使用。
虚拟机的硬盘实际上是分配在宿主机的一个块文件,然后由 pve 核心转换使用。
其中,pve 常用的有两种格式,qcow2 跟 raw。vmware 有自己的格式 vmdk。这三种格式的虚拟硬盘文件都有工具相对应转换。

RAW格式

raw 的本意是 “未加工的”,像数码相机的照片也有raw格式。
对于存储而言,raw 格式就是一块纯纯的块文件,用 dd 指令生成出来的文件,差不多就是这种格式的样子了。

优点

raw 的性能很强,而且由于是直接的块文件,除了能随时挂载、卸载设备,甚至在扩容的时候,可以直接合并、追加。

# 用0初始化一个4G的块,if = input file, of = output file, bs = block size, count = block count
dd if=/dev/zero of=zeros.raw bs=1024k count=4096
# 合并输出到新的文件,new 就是 old 扩容4G的样子
cat old.img zeros.raw > new.img

把 new.img 重新挂到虚拟机之后,就相当于 pve 内置工具 qume-img 以下操作。

qemu-img resize old.img +4G
缺点

首先,原始格式往往意味着没有优化,类似数码相机的 raw 往往是最大的,raw 格式的存储也很大。raw 格式需要预分配且不能伸缩,在新建虚拟机的使用场景下,需要提前准备好容量(即使虚拟机还没占用这么大的容量空间)。

不过由于 Linux 对空洞文件的支持很好,所以实际上用 du 指令去查看大小的时候,显示会比 ls 查看的更小。

root@pve:~# ls -lh /mnt/mnme0n1p1/images/104/vm-104-disk-0.raw 
-rw-r----- 1 root root 107G Mar 17 16:49 /mnt/mnme0n1p1/images/104/vm-104-disk-0.raw
root@pve:~# du -lh /mnt/mnme0n1p1/images/104/vm-104-disk-0.raw 
56G	/mnt/mnme0n1p1/images/104/vm-104-disk-0.raw

这种情况下对空洞文件的支持,会让系统出现一些不容易理解的现象,比如通过 df -lh 查看容量的时候,发现 Avail 已经是 0,结果还是能往里面写东西。

在这里插入图片描述
此外,对于 raw 格式的逻辑也是按照设定大小来的。比如 rsync 上面的 raw 文件就要传输 107G 的数据。

再就是快照的问题。raw 格式的原始,使得快照没有什么捷径(比如qcow2格式快照差异即可)。所以 pve 并不提供 raw 格式的快照能力。当然有黑科技做二进制的差异版本管理来实现快照也有可行性,但终究还是黑科技了点。

QCOW2格式

QCOW2 = QEMU copy-on-write format 2。
亦即 QEMU (一款模拟处理器软件,PVE 支持的虚拟方式之一)的写时拷贝格式。

听到写时拷贝就有既视感了,没错,其实跟 docker 的 overlay 有点相似的意思。

优点

这种格式优点就很明显了,首先就是简单的快照化。只要做差异分层即可回滚到指定的快照去。而且快照速度很快。

再就是能动态伸缩大小,虚拟出来的虚拟机用多少,再在宿主机中申请出来多少。这种特性下不支持空洞文件的操作系统也无所谓优化了,du 跟 ls 命令下看到的容量是一致的。

root@pve:~# ls -lh /mnt/mnme0n1p1/images/103/vm-103-disk-0.qcow2
-rw-r----- 1 root root 289G Mar 17 17:11 /mnt/mnme0n1p1/images/103/vm-103-disk-0.qcow2
root@pve:~# du -lh /mnt/mnme0n1p1/images/103/vm-103-disk-0.qcow2
286G	/mnt/mnme0n1p1/images/103/vm-103-disk-0.qcow2

速度方面,跟 raw 比有差距,但差距已经很小了。这里有 redhat 官方的测试:KVM qcow2 Performance

缺点

这里提的缺点是个人在生产中遇到的,不知道是不是非必现 bug。
qcow2 格式在频繁的使用下,会出现宿主占用比实际内部占用更大,而且大很多的问题。如图,在发版机经历过 30TB/W 15TB/R(读写量)后,虚拟机内部:
在这里插入图片描述

宿主机PVE看到的:
在这里插入图片描述
硬盘读写情况:
在这里插入图片描述

猜测是大量的小文件操作之后,qcow2 产生了大量的碎片无法合并,进而越来越膨胀。
出现这种情况后,qcow2 并没有直接的 gc 指令,但理论上可以通过转换格式,来去掉中间的碎片。

qemu-img convert -f qcow2 -O raw vm-104-disk-0.qcow2 vm-104-disk-0.raw
qemu-img convert -f raw -O raw vm-104-disk-0.raw vm-104-disk-0.qcow2

甚至有人提出了更黑科技的原地自转 qrow2 方法,而不用通过 raw 格式中转。这种方法就没有尝试过了。

qcow2 出现问题后的解决方法是有的,但由于它能膨胀超过原定的指定大小直至占满硬盘,这就是“计划外”的运维问题了,这一点很坑。

在这里插入图片描述
一旦出现这种情况,就需要立马给 qcow2 瘦身。否则虚拟机连交互都做不了。

VMDK格式

VMDK = vmware disk。
VMWare 是一个很老牌的虚拟机厂家(windows的同学很熟悉),他定的这种格式性能、稳定性应该是相当好的。不过 linux 很多虚拟化方式并不支持。
但 qemu-img 工具是支持对它的转换的,以此可以进行两边不同虚拟机的迁移。

qemu-img convert -f vmdk -O qcow2 image-from-vmware.vmdk image-for-kvm-qcow2.img
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐