Prerequisites
First thing to do when preparing to install KVM on a new machine is to make sure that the machine supports virtualization. This is typically controlled from BIOS. For instance with my Intel NUC, the following settings need to be turned on or maximized:
Performance >> Processor >> Hyper-Threading: enabled
Performance >> Processor >> Intel Turbo Boost Technology: enabled
Performance >> Processor >> Active Processor Cores: all
Security >> Intel Virtualization Technology: enabled
Security >> Intel VT for Directed I/O (VT-d): enabled
Installation
Fist install QEmu+kvm, which is the emulation for the KVM supervisor.
Run the following bash command to install the command line KVM:
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst
$virsh Welcome to virsh, the virtualization interactive terminal. Type: 'help' for help with commands 'quit' to quit virsh #
Creating a VM
My goal is to show how to create a VM from scratch from command line scripts. I am going to use the Ubuntu cloud image "Focal Fossa" from the official site: https://cloud-images.ubuntu.com
A cloud image requires preparation in order to be used. Why? Because it typically requires some networking setup, along with provisioning users at the very minimum. Typically the cloud image does not have GUI and once installed on a VM, the only way to work with the VM is by ssh or, if the user is so provisioned, by typing the user name and password.
Ubuntu cloud images are made so that they can be configured using cloud init. For reference the cloud init documentation can be found here.
For the purpose of this demo, let us use the following user date template, which is a yaml file that cloud init understands. We are provisioning a user with an ssh key
#cloud-config hostname: [your-machine-name-here] users: - default - name: [user-name-goes-here] sudo: "ALL=(ALL) NOPASSWD:ALL" shell: "/bin/bash" ssh-authorized-keys: - "your public ssh key goes here"
There is a lot more that can be configured with cloud init, not only users. For instance, one can specify how to partition the disk where the OS will run, or to mount some NFS volume, or to execute some commands at boot. Please check the documentation for more information.
By default, if no network config is provided, the VM starts with DHCP enabled and will get an IP address automatically from the local DHCP server. Let us provide a network config template so that we assign a static IP address to this VM.
version: 2 ethernets: enp1s0: dhcp4: false dhcp6: false addresses: - [your-static-ip-here]/24 gateway4: 192.168.1.1 nameservers: addresses: - 8.8.8.8 - 8.8.4.4
The above configuration files cannot be used directly with the vm creation command. They need to be added to a disk so that cloud-init finds when when booting the VM. For this, we are going to use the cloud-localds command:
cloud-localds -v --network-config=$NET_CONFIG_FILE $USER_DATA_FILE
The above command creates an iso9660 filesystem with the configuration files. Let us call this the "config disk".
A new VM is created by running the command virt-install. This is a somewhat low level command requiring some fine tuning via command line arguments.
Here is an example that deploys a VM:
virt-install \ --name $VM_NAME \ --memory $VM_MEMORY \ --vcpus $VM_VCPUS \ --disk $DISK_IMAGE,device=disk,bus=virtio \ --disk $CONFIG_DISK,device=cdrom \ --boot hd \ --os-type linux \ --os-variant ubuntu20.04 \ --virt-type kvm \ --graphics none \ --noautoconsole \ --network bridge=br0
Configuring the cloud image with cloud init can be challenging. Small errors in the config can cause the VM to boot with default config, leaving us puzzled as to why the configuration was not applied. I spent many hours debugging broken configs. How to check if the created VM has the expected config? On real machines, when they boot, one can see on the screen prints from the OS as it boots, followed by the login prompt. Turns out, we can do something like that here as well. All we really need is to remove the argument --noautoconsole from virt-install command.
Comments
Post a Comment