Hier soll eine Sammlung entstehen, wie KVM und deren Gäste optimiert werden können.
Host:
Um VT-d zu nutzen, braucht Grub einen zusätzlichen Eintrag, in der Zeile:
GRUB_CMDLINE_LINUX_DEFAULT=
das anfügen:
intel_iommu=on
und Grub updaten:
sudo update-grub
Es sollte auf dem Host kontrolliert werden ob es Prozesse gibt, die mehrere CPU Kerne in Anspruch nehmen. Z.B. Squid in Kombination mit Spuidguard startet mehrere Instanzen. Das kann zu Latenz Probleme im Guest führen. Auch Apache macht das.
low-latency Kernel kann helfen die VMs performanter zu machen, bzw. die Reaktionszeiten zu verkürzten. Besonders bei Anwendungen die geringe Latenz brauchen, wie Audio/Video Applikationen, ist das von Vorteil. Dadurch wird die Kernel Timer Frequency auf 1000 Hz erhöht und es werden Preemptible Funktionen aktiviert.
Auf Seiten des Host kann die Priorität einer VM, mit Bordmitteln, verändert werden. Ein Script als Cronjob (z.B. alle 10 Minuten) kann hier Abhilfe schaffen:
#!/bin/bash
# Name der zu priorisierenden VM
vmName="$VMName"
# PID, nice Priorität und IO State ermitteln
vmPID="$( ps ax | awk '/qemu-system-x86_64/ && /'"$vmName"'/ && !/awk/{ print $1 }' )"
if [[ -n "$vmPID" ]]; then
nID="$( ps -o nice -p $vmPID | awk '/[0-9]+/{ p=$NF } END{ print p }' )"
ioStat="$( ionice -p $vmPID | awk '/none/{ print }' )"
fi
ffPID="$( ps ax | awk '/ffmpeg -nostats -v info -hide_banner -re/ && !/awk/{ print $1 }' )"
if [[ -n "$ffPID" ]]; then
ffID="$( ps -o nice -p $ffPID | awk '/[0-9]+/{ p=$NF } END{ print p }' )"
ffioStat="$( ionice -p $ffPID | awk '/none/{ print }' )"
fi
# Priosisierungswerte
vmPrio="-10"
vmIOCl="2"
vmIOPr="0"
# Wenn nice nicht den gewünschten Wert hat, wird dieser gesetzt
if [[ -n "$nID" ]] && (( $nID >= 0 )); then
renice -n $vmPrio -p $vmPID >/dev/null 2>&1
fi
if [[ -n "$ffID" ]] && (( $ffID >= 0 )); then
renice -n $vmPrio -p $ffPID >/dev/null 2>&1
fi
# Wenn IO Class 'none' ist, wird diese erhöht
if [[ -n "$ioStat" ]]; then
ionice -c $vmIOCl -n $vmIOPr -p $vmPID -t >/dev/null 2>&1
fi
if [[ -n "$ffioStat" ]]; then
ionice -c $vmIOCl -n $vmIOPr -p $ffPID -t >/dev/null 2>&1
fi
exit 0
Disk Performance:
driver name='qemu' type='raw' cache='none' io='native'
Cache none ist das beste, funktioniert aber nicht wenn das VM Image auf einem ZFS Dateisystem liegt. Hier kann auch writeback genommen werden, muss aber mit Vorsicht geschehen. Bei writeback gibt es keine Sicherheit und es kann schnell zu Datenverlust kommen.
Als Image Format ist raw zu bevorzugen. Noch besser ist es eine Festplatte komplett durch zu reichen.
Für VM Images, besonders in Kombination mit Linux bringt das „Deadline“ Scheduling etwas mehr an Festplattenperformance. Muss im Host und im Guest eingestellt werden.
Windows in VM:
Unbedingt virtio Treiber verwende! Schon beim Einrichten der virtueller Hardware virtio wählen.
Für Netzwerkdienste Checksum Offload im Netzwerk Interface deaktivieren (Geräte Manager). Zum testen ob die Checksum korrekt ist, kann ein IP Stream gestartet werden, z.B. mit udp (ffmpeg), auf dem Host kann dann mit tcpdump der Stream geprüft werden:
tcpdump -i ethX -n dst port 1234 -s0 -vv
Taucht bad udp cksum […] auf, muss Checksum Offload deaktiviert werden, in dem Fall für UDP.
KVM beherrscht HyperV Funktionen, diese sollen zusätzlich etwas Leistung bei Windows VMs bringen:
virt-xml $VMNAME --edit --features hyperv_relaxed=on,hyperv_vapic=on,hyperv_spinlocks=on,hyperv_spinlocks_retries=8191
Guest Allgemein:
CPU Pinning kann sinnvoll sein. Wird vor allem bei mehr Prozessor Systemen empfohlen, um zu vermeiden, dass ein Thread auf den Speicher des anderen Prozessors zugreifen muss.
OVMF Bios sollte man im Auge behalten und gegebenenfalls installieren und beim Einrichten der VM auswählen. Für Windows 10 ist es z.B. empfehlenswert ein UEFI Bios zu nutzen, das geht nur mit OVMF
IOthreads zu aktivieren kann bei mehreren HDs Sinn machen. Muss über virsh edit VMName gemacht werden.
Weitere CPU Tuning Optionen sind möglich, z.B. vCPU Scheduling, einfach mal getesten.