30 April 2023

How to Use an Ubuntu or Debian Cloud Image

Topics: Linux, Debian and Ubuntu
Tags: kvm
Canonical and Debian provide images for cloud deployments, but you can use them instead of ISOs to speed up new VM creation in smaller environments without having to create the preseed ISOs or an OpenStack environment.

You can find the current cloud images at: https://cloud-images.ubuntu.com and https://cloud.debian.org/images/cloud/. They’re built daily so that when you launch a host from a recent one there are no updates needed. There are images for many architectures and virtualization hosts KVM, Azure, LXD, VMware, VirtualBox, and Vagrant, there are also minimal builds. Once you’ve downloaded your image, use qemu-img to inspect it, possibly convert or rename it to qcow2. The images use the .img extension but internally are usually qcow2. Finally the images are very small, you’ll want to use qemu-img resize to specify the desired size when making a copy to use.

The official procedure involves creating a small ISO image (preseed) with information for the host you’re deploying, that will do things like set the password and networking configuration. For just bringing a simple vm in a simple environment it can be done more simply.

Before attempting to start the vm, you’ll need to create a root password, and you can set the hostname

virt-customize -a myhost.qcow2 \
   --root-password password:ubuntu \   --hostname myhost

The utility can be used to install software and copy files, even run commands, into the vm at creation, set the timezone and add ssh keys.

When the machine first boots networking will be disabled and the host ssh keys won’t have been created. The command ssh-keygen -A run in /etc/ssh will generate the keys. You could also do this with guestmount or virt-customize –run-command ‘cd /etc/ssh; ssh-keygen -A’ before starting the vm.

Because this is a headless machine you want to be able to attach the terminal at the command line and have to ensure that the serial console is working. I’ve never been able to get an ubuntu or debian vm to work with the serial console if it had been created with a graphical console, the cloud images are set up to work with the serial console, the grub parameters have already been added.

# Example virt-install commandvirt-install \--name myhost \--ram 1024 \--disk /var/lib/libvirt/images/myhost.qcow2,bus=sata \--import \--vcpus 1 \--os-type linux \--os-variant ubuntu20.04 \--network bridge=br0,mac=54:54:54:54:54:54 \--graphics none \--console pty,target_type=serial \--debug

If you omit ,mac=…. virt-install will generate a random mac. If you’re not using bridged networking, see the virt-install docs for specifying other network setups.

Once you login to the machine use lshw to find the generated name for the network interface and configure it. With Ubuntu cloud Jammy you have a lot of choices on how, You can use systemd-networkd or NetworkManager, or NetPlan or even go back to legacy interfaces. I recommend systemd-networkd over NetworkManager and NetPlan.

If you’re building multiple vms, once you know the interface name to use you can use guest-umount or guest-fish (virt-edit can’t create a file) or have virt-customize copy a file into the image before starting it.

# /etc/systemd/network/20-wired.network# enp1s0 is a common assignment on KVM[Match]Name=enp1s0[Network]DHCP=yes

You’ll be able to connect from the command line with the virsh console.

Another issue to deal with is that while you resized the image externally, the filesystems won’t have been resized. On first login you’ll want to expand it with growpart /dev/sda 1, which will  allocate all the new space to that partition. Growpart is in cloud-guest-utils and should already be installed. You may also have to resize the file system, for any of the ext variants use resize2fs, for brfs and xfs the utilities are btrfs filesystem resize and xfs_growfs

Steps to use the Image

  • Download
  • Make a copy for your VM
  • Resize the Image (qemu-img resize xxG)
  • Set the hostname and root password (virt-customize)
  • Create the ssh host key (virt-customize)
  • Optional use guestmount to install ssh keys, and enable networking before first boot.
  • Create the VM with virt-install.
  • Immediately after booting resize the filesystem with growpart to fill the expanded image.
  • Expand the filesystem with resize2fs or xfs_growfs.
  • Enable networking if you haven’t.