如何导出最优大小的qcow2镜像文件
在之前的几篇文章中介绍过如何制作OpenStack虚拟机镜像,在导出镜像文件的时候都是直接用qemu-img命令将raw格式或者qcow2格式的磁盘文件压缩后导出,相关命令如下:
1 | # 将raw格式的磁盘,简单压缩并转换成qcow2格式 |
不过,以上方式在不同情况下,其压缩效果差距较为明显:
情况一
- 假如虚拟机磁盘大小为20G,刚安装好操作系统后占用1.6G,此时通过以上方式压缩导出的镜像大小可能只占1G左右甚至更小。因为磁盘的大量剩余空间还没有被使用到(大量block块都是空白的,未写入过数据),所以在导出过程中,空白的block块就会被压缩甚至忽略掉,这样导出的镜像文件的压缩效果就很不错。
情况二
- 假如虚拟机磁盘大小为20G,在安装好操作系统后占用1.6G,然后往虚拟机里上传一个4.71G的ISO文件配置本地YUM源安装必备的一些软件,安装完成后将ISO文件删除,虚拟机内的磁盘空间显示空间已经释放出来了,磁盘占用空间变成跟操作系统刚装好时一样只有1.6G。但此时再使用以上方式压缩并导出镜像文件,会发现导出的镜像文件比之前多出了4.71G的大小。这是因为操作系统删除文件,实际只是在分区表中把文件的索引给删除了,其4.71G的物理数据还是依然占用着磁盘上的block块,这部分空间在导出过程中是无法被压缩或者忽略的(使用
qemu-img info命令可以看到该磁盘文件的物理占用空间比之前变大了4.71G左右)。
针对第二种情况,我们需要在导出镜像文件前对所有未存储有效数据的block块(包括已删除文件的block块)进行置零填充,然后再进行镜像文件压缩导出。
精简导出
虚拟机内部置零填充
在虚拟机内通过dd命令创建一个全0文件,将虚拟机内的剩余可用空间全部置零,然后再将这个全0文件删除。
说明
- 置零操作可能需要话费大量的时间,取决于剩余可用空间的大小
- 如果虚拟机除了根分区,还将其他的如/home、/opt单独划分,记得每个分区都要执行置零操作,修改全0文件的生成路径即可
1 | # 执行置零操作,直到提示空间不足自动退出为止 |
导出镜像文件
说明
执行导出操作前,虚拟机必须处于关机状态
针对raw格式的虚拟机磁盘文件
1 | # --sparse=always稀疏拷贝,忽略全0数据 |
针对qcow2格式的虚拟机磁盘文件
1 | qemu-img convert -c -f qcow2 ${filename}.raw -O qcow2 ${filename}.qcow2 |
实测导出镜像大小对比
- raw文件实际大小(disk size):5.8G
- 直接导出qcow2镜像大小:4.9G
- 置零填充后导出qcow2镜像大小:636M