Virtual Machines from the command line with QEMU
I recently went through the Arch Linux Wiki page about QEMU and realized it is quite easy to work with virtual machines from the command line. Not only that: for the simple scenarios I usually need, the command line is even simpler than using a GUI application.
Here are the steps!
Create a disk image
Create a disk image in QCOW2 format (qcow2
is slower than the raw
format, but uses less disk space).
qemu-img create -f qcow2 ubuntu.cow 20G
The Arch Wiki explains how to add an overlay image, if you want to take snapshots.
Install the OS
qemu-system-x86_64 -m 4G -enable-kvm \ -cdrom ~/Downloads/ubuntu-21.10-desktop-amd64.iso \ -drive file=ubuntu.cow,format=qcow2 \ -boot order=d
where:
-enable-kvm
increases performances dramatically but it requires the host to load some modules. See the Arch page for more details.-m 4G
allocates 4G of RAM, in place of the 128M otherwise available
You can skip this passage and download prebuilt images, such as, for instance:
- Arch Linux boxes, from: https://gitlab.archlinux.org/archlinux/arch-boxes/
- Guix boxes, from: https://guix.gnu.org/en/download/
I did not look into it, but the option -bios /usr/share/qemu/bios.bin
-boot menu=on
might be necessary for booting certain OSs, such as Arch Linux.
Run the machine
qemu-system-x86_64 -m 4G -smp 2 -enable-kvm \ -nic user,hostfwd=tcp::60022-:22 \ ubuntu.cow
qemu-system-x86_64 -m 4G -smp 2 -enable-kvm \ -display none \ -nic user,hostfwd=tcp::60022-:22 \ ubuntu.cow
where:
-display none
hides the graphical display-smp 2
tellsqemu
to use 2 CPUs-nic user,...
makes port60022
on the host point to port22
(ssh) on the guest. This allows to ssh on the machine withssh localhost -p 60022
, issshd
is running on the guest.
Share Files
Mount a guest directory on the host (assuming sshd
is running on the
guest):
sshfs remote_user@localhost:/home/remote_user ./tmp/ -C -p 60022
Serve Web pages
Similar to the previous example, we also forward port 80
to 8080
on the host:
qemu-system-x86_64 -m 4G -smp 2 -enable-kvm ubuntu.cow \ -display none \ -nic user,hostfwd=tcp::60022-:22,hostfwd=tcp::8080-:80
We assume, of course, a web server runs on the guest.