我正在尝试使用 dd conv=sparse 来减小图像尺寸,但无论我做什么,图像尺寸仍然很大。
我有一个 CentOS 镜像,大约 136GB。它这么大的主要原因是它有一个 128GB 的交换空间。
当我运行 du -sh 时,这是输出
# du -sh centos_raw.img
2.0G centos_raw.img
因此,我尝试使用 virt-sparsify 来减少它。结果如下:
# virt-sparsify centos_raw.img centos_raw_sparse.img
[ 0.2] Create overlay file in /tmp to protect source disk
[ 0.2] Examine source disk
- 25% [###############################################----------------------------------------------------------------------------------------------------------------------------------------------] --:--
100% [#############################################################################################################################################################################################] 00:00
[ 32.1] Fill free space in /dev/sda2 with zero
100% [#############################################################################################################################################################################################] 00:00
[ 43.5] Clearing Linux swap on /dev/sda3
100% [#############################################################################################################################################################################################] 00:00
[ 955.3] Fill free space in /dev/sda4 with zero
100% [#############################################################################################################################################################################################] 00:00
[1054.3] Copy to destination and make sparse
[1068.3] Sparsify operation completed with no errors.
virt-sparsify: Before deleting the old disk, carefully check that the
target disk boots and works correctly.
不过容量还是一样,还是136GB。
当我再次运行 du -sh 时,尺寸确实缩小了。
# du -sh centos_raw_sparse.img
1.3G centos_raw_sparse.img
我打算用这个镜像作为 openstack baremetal 镜像,这个镜像太大了,无法通过网络传输
答案1
你说这个镜像大约有 136GB。du
2.0G centos_raw.img
表示磁盘上的大小为 2G。您可以在输出中看到这两个数字
ls -hls centos_raw.img
稀疏性就是这样运作的:文件看起来很大,但占用的磁盘空间却很少。看起来原始图像本来就是稀疏的。
virt-sparsify
成功创建了一个更稀疏的文件,磁盘上的新大小仅为1.3G
。新文件仍报告 136GB,这是预期的。如果文件被截断,它很可能会损坏;它必须保持其原有的大小。
我认为一切都按预期进行。新文件确实很少。
图片太大了,无法通过网络传输
这是你真正的问题,但一般来说,它并不直接取决于稀疏性。零块可以有所帮助。稀疏性的意义在于有效地“压缩”这些块,因此它们实际上不占用磁盘空间。你的文件非常稀疏,所以如果你读取它们,就会出现大量的零序列。如果你知道如何做到这一点,那么具有明确零块(确实占用磁盘空间)的非稀疏文件也可以有效地通过网络传输。这就是为什么我说“它并不直接取决于稀疏性”。如果你用“错误”的方法传输文件,零块(稀疏或不稀疏)可能对你没有帮助。
一些“正确”的方法:
- 使用透明压缩数据的协议(例如 SSH使用适当的设置)。这不依赖于源文件是否稀疏。请注意,您很可能需要额外的步骤(可能在运行中)来使生成的文件稀疏。
压缩文件(可能在运行中)并在另一端解压(可能在运行中)。这也不依赖于源文件的稀疏性;需要额外的步骤来使生成的文件稀疏。示例(作为
dd conv=sparse
附加步骤):到达目的地:
nc -l … | gzip -dc | dd bs=512 conv=sparse of=centos_raw_sparse.img
(
bs=512
因为这)。来源:
<centos_raw_sparse.img gzip -c | nc …
将文件存档(可能即时存档)
tar -S
并在另一端解档。-S
选项做依赖于源文件的稀疏性。这是极少数情况下使用 tar 打包文件的情况之一。单身的文件是有意义的。优点是您不需要额外的步骤。如果支持,tar
默认情况下将使文件在目标处稀疏,您需要的只是-S
在源处。在我的工作流程中,我无论如何都会使用 SSH。这似乎是合理的:
tar -cS centos_raw_sparse.img | ssh destination 'cd /dest/dir && tar -x'
答案2
无需 virt-sparsify 的手动且可靠的方法(通过 libguestfs 的 guestfs-tools)
加载 nbd 驱动程序:
sudo modprobe nbd
将 qcow2 映像绑定到 /dev/nbd0:
sudo qemu-nbd --connect=/dev/nbd0 tosparsify.qcow2
缩小分区:
sudo gparted /dev/nbd0 (resize to 4GB - apply)
从/dev/nbd0解除绑定:
sudo qemu-nbd --disconnect /dev/nbd0
调整 qcow2 文件的大小:
sudo qemu-img resize --shrink tosparsify.qcow2 4.5G
最后 gpt 分区备份丢失,在 gdisks 扩展操作中将备份重新分配到磁盘末尾:
sudo qemu-nbd --connect=/dev/nbd0 tosparsify.qcow2
sudo gdisk tosparsify.qcow2
按 x 按 e (确认重新定位) 按 w (确认写入)
sudo qemu-nbd --disconnect /dev/nbd0
现在你可以压缩它:
qemu-img convert -c -p -f qcow2 -O qcow2 tosparsify.qcow2 compressed_sparsified.qcow2
结果是,通过压缩文件,文件大小从 138 GB 减少到了 0.9 GB
这些都是我凭记忆写的,可能有些瑕疵,但总体思路是这样的。在 qcow2 测试磁盘上测试之前不要使用。