FreeBSD avec kvm et virtio

Si vous avez besoin de bidouiller ou tester des choses sur FreeBSD et que vous n’avez pas assez de machines physiques, vous vous tournez naturellement vers la visualisation. Seulement la visualisation c’est bien souvent lent en raison des I/O réseau et disque qui font pleins d’aller-retour entre le kernel et l’userland. Pour ça il y a des drivers spéciaux appelés virtio qui permettent d’accélérer les accès disque et réseau. Récemment (fin 2011) des drivers virtio sont enfin disponibles pour votre OS préféré, voilà un petit how-to pour les utiliser avec kvm sous Debian whezzy (testing). Pour mes machines sous kvm, j’utilise le script kvmctl, en lisant ce script vous pourrez facilement déduire les bonnes options pour kvm.

On commence par l’installation du script:

# On installe tout ce qu'il faut
$ sudo apt-get install kvm uml-utilities
# On dl la dernière release
$ wget 'http://www.linux-kvm.org/wiki/images/6/6e/HowToConfigScript%24kvmctl-2.0.4.jpg' -O - | tar xvjf -
kvmctl-2.0.4/interfaces
kvmctl-2.0.4/kvmctl
kvmctl-2.0.4/kvm-ifup
kvmctl-2.0.4/kvm-init
kvmctl-2.0.4/README.txt
kvmctl-2.0.4/template.kvm

# on installe tout ça
$ sudo install kvmctl-2.0.4/kvmctl /usr/local/bin/kvmctl
$ sudo mkdir -p /etc/kvm/auto

# Ma config réseau (à adapter à vos besoins)
$ cat /etc/network/interfaces
# The loopback network interface
auto lo
iface lo inet loopback

auto kvmbr0
iface kvmbr0 inet dhcp
	bridge_ports eth0
	bridge_fd 0
	bridge_hello 2
	bridge_maxage 12
	bridge_stp off

$ cat /etc/kvm/kvm-ifup
#!/bin/sh

/usr/sbin/tunctl -u 0 -t $1 >/dev/null 2>&1
ip link set $1 up
sleep 0.5s
brctl addif kvmbr0 $1 >/dev/null 2>&1
sleep 2 # Temps nécessaire au démarrage de l'interface
exit 0

Personnellement j’ai modifié le script /usr/local/bin/kvmctl pour avoir un clavier fr dans vnc et pour limiter la mémoire maximum des vm de 4G à 6G et aussi un fix pour créer /var/run/kvm s’il n’existe pas.

--- kvmctl-2.0.4/kvmctl 2009-10-07 21:34:21.000000000 +0200
+++ /usr/local/bin/kvmctl   2012-05-21 13:23:35.801551991 +0200
@@ -49,7 +49,7 @@
# Adjust these as needed.  These are the min and max amount
# of RAM to assign to a VM, in MB
minmem="128"
-maxmem="4096"
+maxmem="6144"
# How long to sleep at certain points in the script
sleeptime="3"
@@ -437,12 +437,14 @@
fi
# Start the VM
+   mkdir -p ${piddir} >/dev/null 2>&1
echo "Attempting to start VM for ${1} ..."
${kvm} \
-name ${host} \
-smp ${confcpus} \
-m ${confmem} \
-vnc :${id} \
+       -k fr \
-daemonize \
-localtime \
-usb \

On va commencer par installer FreeBSD sans virtio (à ce jour ne j’ai pas trouvé de kernel FreeBSD officiel avec virtio). Notre machine va s’appeler ftest.

# On crée un volume lvm dédié de 5G (hey ho, c'est juste un test)
$ sudo lvcreate -L 5G -n ftest rootvg
# On download l'iso de FreeBSD 9.0
$ wget ftp://ftp.fr.freebsd.org/pub/FreeBSD/releases/ISO-IMAGES/9.0/FreeBSD-9.0-RELEASE-amd64-disc1.iso
# On fait un fichier de config pour kvmctl (2G de RAM, 4 core)
# Pour certaines VM que j'utilise tous les jours en prod je fais un layout disques plus optimisé:
# - Un lvm sur un ssd pour l'OS en disk0
# - Un lvm sur un disque normal pour les datas en disk1
$ cat /etc/kvm/ftest.kvm
host="ftest"
id="1"
mem="2048"
cpus="4"
mouse="tablet"
nic="e1000"
boot="d"
disktype0="ide"
media0="disk"
disk0="/dev/rootvg/${host}"
disktype1=""
media1=""
disk1=""
disktype2="ide"
media2="cdrom"
disk2="/home/phil/FreeBSD-9.0-RELEASE-amd64-disc1.iso"
#disk2=""

Ensuite on boot la vm avec sudo kvmctl start ftest et on se connecte en vnc sur la vm avec vncviewer localhost:5901. Pour ceux qui n’utilisent pas kvmctl voilà ce que ça donne dans mon ps:

/usr/bin/kvm -name ftest -smp 4 -m 2048 -vnc :1 -k fr -daemonize -localtime -usb -usbdevice tablet -net nic,macaddr=00:16:3e:00:00:1,model=e1000 -net tap,ifname=tap1 -pidfile /var/run/kvm/ftest.pid -boot d -no-reboot -drive index=0,media=disk,if=ide,file=/dev/rootvg/ftest -drive index=2,media=cdrom,if=ide,file=/home/phil/FreeBSD-9.0-RELEASE-amd64-disc1.iso

Ensuite on installe FreeBSD comme on veut, je suis adepte de zfs (c’est pour ça que j’ai passé memmax de 4G à 6G ^^), donc j’ai tout installé en shell en suivant cette méthode. Ne pas oublier le kbdcontrol -l fr.iso.acc pour les problèmes de clavier, et PermitRootLogin yes dans /etc/ssh/sshd_config pour pouvoir se logger ssh root.

Bon évidement, l’installation est très lente, c’est parce qu’on a pas encore virtio.

Ensuite on reboot sur le disque avec boot="c" dans /etc/kvm/ftest.kvm et on se logge en root sur la machine pour installer virtio:

# Voir sur http://people.freebsd.org/~kuriyama/virtio/ pour la dernière version
$ pkg_add http://people.freebsd.org/~kuriyama/virtio/9.0/virtio-kmod-0.234349.tbz
# Il faut faire ce qui est marqué à l'installation de virtio.
$ cat >> /boot/loader.conf << EOF
virtio_load="YES"
virtio_pci_load="YES"
virtio_blk_load="YES"
if_vtnet_load="YES"
virtio_balloon_load="YES"
EOF
$ sed -i.bak -Ee 's|/dev/ada?|/dev/vtbd|' /etc/fstab
$ echo 'ifconfig_vtnet0_name="em0"' >> /etc/rc.conf
$ shutdown -p now

Ensuite on stop le process kvm avec sudo kvmctl stop ftest et on modifie la conf kvmctl pour utiliser virtio:

$ cat /etc/kvm/ftest.kvm
host="ftest"
id="1"
mem="2048"
cpus="4"
mouse="tablet"
nic="virtio"
boot="c"
disktype0="virtio"
media0="disk"
disk0="/dev/rootvg/${host}"
disktype1=""
media1=""
disk1=""
disktype2="ide"
media2="cdrom"
disk2="/home/phil/Downloads/FreeBSD-9.0-RELEASE-amd64-disc1.iso"
#disk2=""

Et pour ceux qui n’utilisent pas kvmctl:

/usr/bin/kvm -name ftest -smp 4 -m 2048 -vnc :1 -k fr -daemonize -localtime -usb -usbdevice tablet -net nic,macaddr=00:16:3e:00:00:1,model=virtio -net tap,ifname=tap1 -pidfile /var/run/kvm/ftest.pid -boot c -drive index=0,media=disk,if=virtio,boot=on,file=/dev/rootvg/ftest -drive index=2,media=cdrom,if=ide,file=/home/phil/FreeBSD-9.0-RELEASE-amd64-disc1.iso

On peut maintenant booter la vm avec sudo kvmctl start ftest, et nous voilà avec une VM sous FreeBSD qui utilise les virtio. On peut snapshoter le lvm et cloner cette VM en pleins de petits FreeBSD pour tester des tas de choses intéressantes :)