Creating a Linux Virtual Machine with KVM
What is KVM?
Kernel-Based Virtual Machine (KVM) is a virtualization infrastructure developed for the Linux kernel, transforming it into a hypervisor. KVM requires a processor with hardware virtualization capabilities to be available.
KVM is a part of Linux. If you have Linux Kernel 2.6.20 or newer, you have KVM. KVM was first announced in 2006 and merged with the mainline Linux kernel a year later. Since KVM is part of the existing Linux code, it immediately benefits from every new Linux feature, fix, and enhancement without additional engineering.
What is Virtualization?
Virtualization allows hardware components such as processors, memory, and storage on a computer to be divided into multiple virtual machines (VMs). Each virtual machine runs its own operating system (OS) and behaves like an independent computer, even though it operates on only a portion of the underlying physical computer hardware.
Virtualization technology forms the foundation of modern cloud computing.
Virtualization provides various advantages to data center operators and service providers, including:
- Efficient resource utilization
- Easier management
- Minimum downtime
What is a Hypervisor?
A hypervisor is a software layer that coordinates virtual machines. It acts as an interface between the virtual machine and the underlying physical hardware, ensuring that each has access to the physical resources it needs to execute. Additionally, it ensures that virtual machines do not interfere with each other by affecting each other’s memory areas or computation cycles.
There are two types of hypervisors:
Type 1 Hypervisor
Type 1 or “bare metal” hypervisor interacts directly with the underlying physical resources, completely replacing the traditional operating system. They are most commonly seen in virtual server scenarios.
Type 2 Hypervisor
Type 2 hypervisor runs as an application on an existing operating system. They are most commonly used on endpoint devices to run alternative operating systems and carry a performance overhead since they need to use the main operating system to access and coordinate the underlying hardware resources.
How Does KVM Work?
KVM turns Linux into a type 1 (bare metal) hypervisor. All hypervisors require some OS-level components such as a memory manager, process scheduler, I/O stack, device drivers, security manager, and network stack to run virtual machines. Since KVM is part of the Linux kernel, it has all these components. Each virtual machine is implemented as a regular Linux process, scheduled by the standard Linux scheduler, with dedicated virtual hardware such as a network card, graphics adapter, CPU(s), memory, and disks.
What are the Advantages of Using KVM Hypervisor?
The biggest advantage of the KVM hypervisor is its native availability in Linux. Since KVM is part of Linux, it comes natively with the Linux kernel. It provides a simple user experience and seamless integration. However, KVM offers more benefits compared to other virtualization technologies. These include:
- Performance - One of the main drawbacks of traditional virtualization technologies is the performance lag of virtual machines compared to physical machines. As a type-1 hypervisor, KVM performs better than all type-2 hypervisors, delivering near-physical machine performance. With the KVM hypervisor, virtual machines boot quickly and achieve desired performance results.
- Scalability - As a Linux kernel module, the KVM hypervisor automatically scales to respond to heavy loads when the number of virtual machines increases. The KVM hypervisor allows clustering for thousands of nodes, laying the foundation for cloud infrastructure applications.
- Security - Since KVM is part of the Linux kernel source code, it benefits from the largest open-source community collaboration in the world, rigorous development and testing processes, and continuous security patches.
- Maturity - KVM was established in 2006 and has been actively developed since. Over its 15-year history, more than 1,000 developers worldwide have contributed to KVM’s code.
- Cost Efficiency - Cost is a significant factor for many organizations. Since KVM is open-source and available as a Linux kernel module, it comes at zero cost. Businesses can optionally subscribe to various commercial programs like “Ubuntu Pro” to get enterprise support for their KVM-based virtualizations or cloud infrastructures.
Creating a Linux Virtual Machine with KVM
Requirements
- Linux Machine (I will use Ubuntu 20.04)
- Internet Connection
- A system adequate for the operations you will perform on your virtual machines.
Download KVM
Let’s download KVM
sudo apt install -y qemu qemu-kvm libvirt-daemon libvirt-clients bridge-utils virt-manager cloud-image-utils libguestfs-tools
After that restart your machine
sudo reboot
Download Image
Let’s download a virtual machine image to create a VM.
wget https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-20.04-server-cloudimg-amd64.img
Create a password for the new machine
The downloaded image comes preloaded with a user named ubuntu, but there is no password set for this user, making it impossible to log in. To overcome this, we need to create a text file containing our own password.
cat >user-data.txt <<EOF
#cloud-config
password: secretpassword
chpasswd: { expire: False }
ssh_pwauth: True
EOF
Create the image file.
cloud-localds user-data.img user-data.txt
Create a writable copy of the boot disk.
So far, we have a bootable but read-only image of our chosen Linux operating system and a special file to set the password for the ubuntu user. We need to create a writable disk for our VM to boot from. We likely want our root disk to be larger than 2GB as well. We can do both using qemu-img. In the example below, ubuntu-vm-disk.qcow2 will be our boot disk.
qemu-img create -b ubuntu-20.04-server-cloudimg-amd64.img -F qcow2 -f qcow2 ubuntu-vm-disk.qcow2 20G
Convert image to virtula machine
Now, we can convert the machine with the image into a virtual machine. We use virt-install to do this.
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 ubuntu20.04
Connect to the virtual machine
Connect to your running virtual machine. You can use the command virsh console ubuntu-vm for this. If you haven’t changed the information in user-data.txt, your login credentials will be; username ubuntu, and password secretpassword.
Example
tyfn@ubuntu:~$ mkdir vmtmp
tyfn@ubuntu:~$ cd vmtmp
tyfn@ubuntu:~/vmtmp$ wget https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-20.04-server-cloudimg-amd64.img
--2024-04-02 21:45:42-- https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-20.04-server-cloudimg-amd64.img
Resolving cloud-images.ubuntu.com (cloud-images.ubuntu.com)... 185.125.190.37, 185.125.190.40, 2620:2d:4000:1::1a, ...
Connecting to cloud-images.ubuntu.com (cloud-images.ubuntu.com)|185.125.190.37|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 389349376 (371M) [application/octet-stream]
Saving to: ‘ubuntu-20.04-server-cloudimg-amd64.img’
ubuntu-20.04-server-cloudim 100%[========================================>] 371.31M 15.9MB/s in 24s
2024-04-02 21:50:06 (15.7 MB/s) - ‘ubuntu-20.04-server-cloudimg-amd64.img’ saved [389349376/389349376]
tyfn@ubuntu:~/vmtmp$ cat >user-data.txt <<EOF
#cloud-config
password: secretpassword
chpasswd: { expire: False }
ssh_pwauth: True
EOF
tyfn@ubuntu:~/vmtmp$ cloud-localds user-data.img user-data.txt
tyfn@ubuntu:~/vmtmp$ qemu-img create -b ubuntu-20.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-20.04-server-cloudimg-amd64.img backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
tyfn@ubuntu:~/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 ubuntu20.04
...VM boots....
[ 13.327063] cloud-init[1160]: Cloud-init v. 22.2-0ubuntu1~20.04 running 'modules:final' at Tue, 2 Apr 2024 22:40:01 +0000. Up 13.18 seconds.
[ 13.328572] cloud-init[1160]: Cloud-init v. 22.2-0ubuntu1~20.04 finished at Tue, 2 Apr 2024 22:42:08 +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 20.04 LTS ubuntu ttyS0
ubuntu login: ubuntu. <---- enter ubuntu as username
Password: secretpassword <------ enter secretpassword as password
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-12.15-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue Apr 2 22:43:12 UTC 2024
System load: 0.45 Processes: 104
Usage of /: 5.7% of 19.20GB Users logged in: 0
Memory usage: 6% IP address for enp1s0: 192.168.122.188
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.
ubuntu@ubuntu:~$