Making half-sparse VM images



Normally with sparse images, especially on disk-backed storage, you inherit a lot of bad performance issues, hammering your disks with useless IOs. OS installs take a lot longer during the formatting phase and initial install. Patching takes longer. Everything takes longer, and it gets worse with each byte added by any VM in the datastore.

But if you alternatively use full disks, you will waste incredible amounts of disk space.



Let's not pick a poison any more.

Combine the advantages!


Make the fully allocated base image


We're creating a 4GB image using dd.

4GB is vast for stripped down installs. I use Alpine Linux and CentOS, those come at about 200MB - 500MB. Use more space, i.e. 20GB for a "heavier" OS or a workstation.


This part will be exactly as fast as any "normal" thickly / fully provisioned image. And this is what is written to at start, meaning your OS and the "standard" binaries can go there. I use a second disk for the application data or custom applications.



# dd if=/dev/zero of=4g.img bs=1024k count=4096
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB) copied, 17.1713 s, 250 MB/s
# du -sh 4g.img  ; ls -lh 4g.img 
4.0G	4g.img
-rw-r--r-- 1 root root 4.0G Oct 30 12:11 4g.img


Extend it to a half-sparse image

# dd if=/dev/zero of=4g.img ibs=1M count=1 seek=10240 obs=1M oflag=append conv=sparse
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.00498379 s, 210 MB/s
# du -sh 4g.img  ; ls -lh 4g.img 
4.0G	4g.img
-rw-r--r-- 1 root root 11G Oct 30 12:17 4g.img

As you can see it's now a 11GB Image using 4GB.

This area is the "overflow", sparsely allocated and it'll only be used in exceptional cases.


Now you can do your OS installs and basic patching etc. at the full speed.

Formatting anything beyond the 4G boundary will be slow. In practice, only the filesystem structures will allocate some space there. Also, remember it will still be *less* slow than it would be if all your VMs had been fully sparsified and installing at the same time, multiplying fragmentation by the number of writers (==running vms)


I hope you like this, and I hope it also serves as a little insight why sometimes "crafting your own" can give you interesting options.


Do you know if there's a simple (1-2 lines of shell) way of converting this to a vmdk or qcow2 file?

How about doing the same on the ESXi shell? (i'm aware vmfs is less shitty with this in general)