Howto: Shrink VMWare VMDK Files

Virtual machine images tend to grow over time, causing exported machine images to be unnecessarily large. Here’s how to remove the excess baggage.

Step 1. Delete temporary files and unneeded log files

The following commands will remove temporary files and cached packages from various package managers. There is certainly more that can be done, but these are a few steps.

Another easy location is the system log files. Manually review /var/log and remove unneeded files.

find /tmp /var/tmp -mindepth 1 -maxdepth 1 -exec rm -rf \{\} \;

# Red Hat, CentOS
sudo yum clean all

# Debian, Ubuntu
sudo apt-get clean
sudo apt-get autoclean

# Arch 
sudo pacman -c

Step 2. Boot VM with Parted Magic ISO

  1. Download Parted Magic Live ISO.
  2. Connect the VM CD/DVD drive to Parted Magic ISO, and select the connect at power on box.
  3. Configure the VM to boot from CD

Step 3. Zero unused disk blocks

In Parted Magic, Open a terminal instance

# if using LVM, activate devices
vgchange -a y

# for each partition containing an ext* filesystem, run zerofree:
fdisk -l | grep dev

zerofree -v /dev/sda1
zerofree -v /dev/sdb1
zerofree -v /dev/sdc1
zerofree -v /dev/sdd1
zerofree -v /dev/mapper/VolGroup00-LogVol00

# for swap partitions, zero then recreate swap
dd if=/dev/zero of=/dev/<swap device> bs=1M
mkswap /dev/<swap device>

#NOTE: This will create a new UUID.  If your /etc/fstab file uses UUID rather than device paths, you will need to update the swap entry in /etc/fstab with the new UUID.
mount /dev/<Root Device> /mnt
vi /mnt/etc/fstab

Shut down the VM

Step 4. Shrink VMDKs

SSH to your vSphere/ESXi server. If you don’t have SSH enabled, look here: How to enable SSH on vSphere

# change directory to your VM.  Replace <VM> with the name of your VM.
cd /vmfs/volumes/datastore1/<VM>

ls -lah *.vmdk
-rw-------    1 root     root       80.0G Sep 11 18:53 vm-flat.vmdk
-rw-------    1 root     root         506 Sep 11 18:32 vm.vmdk
-rw-------    1 root     root       40.0G Sep 11 18:53 vm_1-flat.vmdk
-rw-------    1 root     root         506 Sep 11 18:53 vm_1.vmdk
-rw-------    1 root     root       10.0G Sep 11 18:53 vm_2-flat.vmdk
-rw-------    1 root     root         506 Sep 11 18:53 vm_2.vmdk
-rw-------    1 root     root       20.0G Sep 11 18:54 vm_3-flat.vmdk
-rw-------    1 root     root         506 Sep 11 18:53 vm_3.vmdk

#for each vmdk, skipping the "-flat" files
vmkfstools --punchzero vm.vmdk
vmkfstools --punchzero vm_1.vmdk
vmkfstools --punchzero vm_2.vmdk
vmkfstools --punchzero vm_3.vmdk

Step 5. Optional: Export VM

Your VM should now be thin provisioned, using the minimum space in your datastore. You can now export using vSphere Client or ovftool

ovftool vi://<esx_ip>/<vm_display_name> <file.ovf>
# Note: If <vm_display_name> is left off, the server will return a list of options