- Shell 43.5%
- Python 32.8%
- HTML 23.7%
| kimchiflask | Fix arguments | |
| .gitignore | Simple dashboard giving basic infos about host and domains | |
| app.py | Simple dashboard giving basic infos about host and domains | |
| README.md | Add license | |
| requirements.txt | Simple dashboard giving basic infos about host and domains | |
kimchi
Shell scripts and flask web interface to create and maintain virtual machines on a server with the help of libvirt and KVM.
Setup
This setup has been tested on Debian 12 with virsh 9.0.0 and virt-install 4.1.0.
Requirements
Make sure you're running all of this on a machine supporting virtualization. You might need to check your BIOS settings.
Installation
# Install tools
apt install qemu-utils libvirt-daemon-service libvirt-clients virtinst bridge-utils
# Create "tank" folder in root which contains default cloud images and the custom virtual disk images of each running VM
mkdir /tank
cd /tank
mkdir vm img
# Make sure your user has write access to these folders
Networking
To allow communication between VMs and other processes on the same LAN we're establishing a bridge interface on the host ("bridge mode"). All VMs will use this "external" bridge interface. From here they receive their IP-Addresses from the LAN router via DHCP or static assignment.
Make sure that no other networking managers are running which might interfere with our manual configuration. Also remove all currently assigned IP addresses if there are any on the ethernet interface.
For an setup which will persist after reboot we make use of the brctl tool which was installed as part of the bridge-utils package:
# Create bridge interface on host
brctl addbr br0
# Bind ethernet device to bridge
brctl addif br0 <eth_dev>
Open /etc/network/interfaces in an editor and adjust it to a) assign an static IP address to the bridge b) route the bridge to the right gateway c) make sure that the ethernet interface is not automatically changed by other processes:
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# Set up interfaces manually, we don't want them to use dhcp or be managed by external processes
iface <eth_dev> inet manual
# Assign a static IPv4 and IPv6 address and correct gateway to bridge
auto br0
iface br0 inet static
bridge_ports <eth_dev>
address 192.168.1.115
broadcast 192.168.1.255
netmask 255.255.255.0
gateway 192.168.1.1
iface br0 inet6 static
address 2001:db8::1
netmask 64
gateway fe80::11
autoconf 0
The bridge utility hooked itself into the network setup and will make sure that these settings are respected after next reboot.
Finally, reset potentially existing ip addresses for your ethernet interface and bring everything up again:
ip address flush <eth_dev> scope global
ifup br0
Allow non-root user
To be able to create VMs via the flask web interface, we need to allow non-root users.
# Check if libvirt group exists
sudo getent group | grep libvirt
# Add user to group
sudo usermod -a -G libvirt $(whoami)
newgrp libvirt
Edit the libvirtd configuration at /etc/libvirt/libvirtd.conf and change the following lines:
unix_sock_group = "libvirt"
unix_sock_rw_perms = "0770"
Edit or create a file in /etc/qemu/bridge.conf to allow bridge access to all users:
allow br0
Adjust the permissions to avoid "Permission denied" error when creating vm with network bridge as regular user:
chown root:root /etc/qemu/bridge.conf
chmod 0640 /etc/qemu/bridge.conf
chmod u+s /usr/lib/qemu/qemu-bridge-helper
Restart the daemon after making the changes:
systemctl restart libvirtd.service
Server
Install the dependencies to run the Python Flask web server. It is recommended to use a virtual environment and reverse proxy with http basic authentication.
# Install dependencies required to build libvirt-python
apt install libvirt-dev pkg-config
# Install python dependencies
pip install -r requirements.txt
Usage
Download cloud images
# Check which os variants are supported by libvirt (folder name should match)
virt-install --osinfo list
# Create folder with libvirt's os variant name from list
mkdir /tank/img/<os_variant>
# Download cloud image into this folder
wget <url> -O /tank/img/<os_variant>/root.img.qcow2
Maintain virtual machines
You find all scripts in the kimchiflask/scripts folder.
# Create a new VM
./create.sh <domain_name> <os_variant> <vcpu> <mem> <storage> <pubkeys>
# Example: Launch an Ubuntu 22.04 VM with 1 VCPU, 512 MB RAM and 16GB virtual disk
./create.sh test-vm-1 ubuntu22.04 1 512 16 "$(cat ~/.ssh/id_ed25519.pub)"
# List all currently running VMs
virsh list --all
# Enter VM via console, leave it again via CTRL + ]
virsh console <domain_name>
# Delete VM (this will remove everything!)
./destroy.sh <domain_name>
Start web server
# Visit web interface at localhost:5000
flask run --host 0.0.0.0
License
UNIVERSAL PUBLIC DOMAIN LICENSE
This software and everything else in the universe is in the public domain. Ideas are not property.