Creating a compressed and minimal KVM template
Tags: kvm, linux, qemu, guide
Published: 2021-07-18 09:18:37

Note:exclamation:: This is purely for self-learning, so that I can learn how to automate my Virtual Machines using Libvirt

### Goal

<!-- An innocent comment to force Markdown out of list parsing mode. See also http://meta.stackoverflow.com/a/99637 -->
```shell
                  virt-sysprep        virt-sysprep
                    (reset)      (add user, keys, logos)
                        |                   |
                dd      v          dd       v
original guest ----> template ---------> copied ------> custom
                                          template         guest 
```
To start this you first need to install a virtual machine in KVM, either by using virt-install or virt-manager. Automating this is possible via kickstart or by downloading a cloud image, I did it manually.

This was the base image after installation and it was around 2.1 GB on disk and 10GB virtually.

<!-- An innocent comment to force Markdown out of list parsing mode. See also http://meta.stackoverflow.com/a/99637 -->

    qemu-img info "rocky-linux.qcow2"
    file format: qcow2
    virtual size: 10 GiB (10737418240 bytes)
    disk size: 2.25 GiB

I've used virt-sparsify instead of dd with compress which made the image size 1GB on disk and took around 5 minutes for it to complete

<!-- An innocent comment to force Markdown out of list parsing mode. See also http://meta.stackoverflow.com/a/99637 -->

    sudo virt-sparsify --tmp=./ --compress rocky-linux.qcow2 rocky-linux-template.qcow2

Final file “rocky-linux-template.qcow2” which is 1GB :fire:.

<!-- An innocent comment to force Markdown out of list parsing mode. See also http://meta.stackoverflow.com/a/99637 -->
    sudo qemu-img info rocky-linux-template.qcow2
      virtual size: 10 GiB (10737418240 bytes)
      disk size: 0.993 GiB
    

Now let’s virt-sysprep it

<!-- An innocent comment to force Markdown out of list parsing mode. See also http://meta.stackoverflow.com/a/99637 -->

    sudo virt-sysprep -a rocky-linux-template.qcow2

Time to virt-sparsify it again

<!-- An innocent comment to force Markdown out of list parsing mode. See also http://meta.stackoverflow.com/a/99637 -->

    sudo virt-sparsify --tmp=./ --compress rocky-linux-template.qcow2 rocky-linux-g1.qcow2

Time to add the ssh keys and relabel the system

<!-- An innocent comment to force Markdown out of list parsing mode. See also http://meta.stackoverflow.com/a/99637 -->

    sudo virt-sysprep --format=qcow2 -a rocky-linux-g1.qcow2 \
    --ssh-inject root:file:.ssh/id_rsa.pub \
    --selinux-relabel --hostname rk-g1-minimal

Creating a guest out of this

<!-- An innocent comment to force Markdown out of list parsing mode. See also http://meta.stackoverflow.com/a/99637 -->

      virt-install --connect qemu:///system \
          --name "${VM_NAME}" \
          --disk "${VM_DISK_PATH}",target.bus=virtio \
          --boot hd \
          --memory=1048 \
          --noautoconsole \
          --graphics none \
          --os-variant "${VM_OS_VARIANT}" \
          --vcpus 2 \
          --cpu host \
          --os-type linux \
          --network network=br0,model=virtio \
          --console pty,target_type=serial

And it’s done :v: