QCOW 3 Ways

How to mount QCOW images as Linux block devices

  • guestmount (requires libguestfs-tools) sudo guestmount -d <vm-name> --ro -i <mountpoint>
  • qemu-nbd (requires the nbd driver)
    • Load the kernel module modprobe nbd max_part=8
    • Bind the device to the image qemu-nbd --connect=/dev/nbd0 <vmdiskimage.qcow>
    • Assuming partition #1 is the target mount /dev/ndb0p1 /a
  • loopback mount. Requires converting qcow to raw
    • Convert qcow to raw qemu-img convert vmdisk.qcow2 -f qcow2 -O raw vmdisk.raw
    • Create a loopback device losetup -f -P vmdisk.raw
    • Locate name of loopback device losetup -l | grep vmdisk.raw
    • Mount (assuming partition #1 on loopback device 99 mount /dev/mapper/loop99p1 /a
Continue reading

Create a Linux VM with KVM in 6 easy steps

Step 1. Install KVM

“KVM” Is shorthand for several technologies primarily KVM itself, QEMU and Livbirt. Like all tasks, life is considerably easier with the right tools. I suggest installing the following.

sudo apt install -y qemu qemu-kvm libvirt-daemon libvirt-clients bridge-utils virt-manager cloud-image-utils libguestfs-tools

Though not strictly necessary – rebooting after installing the above might save you some headaches

sudo reboot

Step 2. Download a base image

Download a bootable image to create a VM clone from. I prefer ubuntu cloud images for this task. Choose your favorite flavor of a released build from the ubuntu cloud image released builds page. You will probably want the an amd64 build to download.

wget https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.img

Step 3. Set a password for the new VM

The cloud-images come pre loaded with a user named ubuntu however there is no password set for that user so it is impossible to login. To overcome this, you will need to create a text file which contains your own password – convert that to a magical image file and then pass in that image file as part of the VM creation. Don’t worry it’s easier than it sounds.

cat >user-data.txt <<EOF
password: secretpassword
chpasswd: { expire: False }
ssh_pwauth: True

Then create the image file. We will use the user-data.img file in the virt-install step.

cloud-localds user-data.img user-data.txt

Step 4. Create a writable clone of the boot drive

So far we have a bootable, but read-only image file of our chosen Linux OS and a custom override file that will set a password for the ubuntu user. Next we need to create a “disk” for our VM to boot from which is writable. We also probably want our root disk to be larger than 2GB. We can do both of those things using qemu-img. In the example below is the file ubuntu-vm-disk.qcow2 that will become our boot disk. It will be 20G in size.

qemu-img create -b ubuntu-18.04-server-cloudimg-amd64.img -F qcow2 -f qcow2 ubuntu-vm-disk.qcow2 20G

Step 5. Create a running VM

Now we need to turn that disk image into a running VM. To do that we use virt-install. As part of the virt-install command line we pass in the customization disk user-data.img which contains details of the customizations we want (namely to set a password). Other things like the VM name, memory and number of CPU are set here too. As part of this command the VM will boot and present a console. You can login from here.

virt-install --name ubuntu-vm \
  --virt-type kvm --memory 2048 --vcpus 2 \
  --boot hd,menu=on \
  --disk path=ubuntu-vm-disk.qcow2,device=disk \
  --disk path=user-data.img,format=raw \
  --graphics none \
  --os-type Linux --os-variant ubuntu18.04 

Step 6. Enjoy your virtual machine

You are now the proud owner of a virtual machine. As long as the VM is running you can connect to it using the command $ virsh-console ubuntu-vm. The username is ubuntu and the password is secretpassword unless you changed the text in user-data.txt


gary@dellboy:~$ mkdir vmtmp

gary@dellboy:~$ cd vmtmp

gary@dellboy:~/vmtmp$ wget https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.img
--2022-09-10 19:45:42--  https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.img
Resolving cloud-images.ubuntu.com (cloud-images.ubuntu.com)...,, 2620:2d:4000:1::1a, ...
Connecting to cloud-images.ubuntu.com (cloud-images.ubuntu.com)||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 389349376 (371M) [application/octet-stream]
Saving to: ‘ubuntu-18.04-server-cloudimg-amd64.img’

ubuntu-18.04-server-cloudim 100%[========================================>] 371.31M  15.9MB/s    in 24s

2022-09-10 19:46:06 (15.7 MB/s) - ‘ubuntu-18.04-server-cloudimg-amd64.img’ saved [389349376/389349376]

gary@dellboy:~/vmtmp$ cat >user-data.txt <<EOF
password: secretpassword
chpasswd: { expire: False }
ssh_pwauth: True

gary@dellboy:~/vmtmp$ cloud-localds user-data.img user-data.txt

gary@dellboy:~/vmtmp$ qemu-img create -b ubuntu-18.04-server-cloudimg-amd64.img -F qcow2 -f qcow2 ubuntu-vm-disk.qcow2 20G
Formatting 'ubuntu-vm-disk.qcow2', fmt=qcow2 size=21474836480 backing_file=ubuntu-18.04-server-cloudimg-amd64.img backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16

gary@dellboy:~/vmtmp$ virt-install --name ubuntu-vm \
  --virt-type kvm --memory 2048 --vcpus 2 \
  --boot hd,menu=on \
  --disk path=ubuntu-vm-disk.qcow2,device=disk \
  --disk path=user-data.img,format=raw \
  --graphics none \
  --os-type Linux --os-variant ubuntu18.04 

...VM boots....

[   13.327063] cloud-init[1160]: Cloud-init v. 22.2-0ubuntu1~18.04.3 running 'modules:final' at Sat, 10 Sep 2022 23:51:04 +0000. Up 13.18 seconds.
[   13.328572] cloud-init[1160]: Cloud-init v. 22.2-0ubuntu1~18.04.3 finished at Sat, 10 Sep 2022 23:51:05 +0000. Datasource DataSourceNoCloud [seed=/dev/vdb][dsmode=net].  Up 13.32 seconds
[  OK  ] Started Execute cloud user/final scripts.
[  OK  ] Reached target Cloud-init target.

Ubuntu 18.04.6 LTS ubuntu ttyS0

ubuntu login: ubuntu. <---- enter ubuntu as username
Password:  secretpassword <------ enter secretpassword as password
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 4.15.0-192-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sat Sep 10 23:51:55 UTC 2022

  System load:  0.45              Processes:             104
  Usage of /:   5.7% of 19.20GB   Users logged in:       0
  Memory usage: 6%                IP address for enp1s0:
  Swap usage:   0%

0 updates can be applied immediately.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.