Warum Thin Provisioning
Wer mit dem “Virtual Machine Manager” eine neue VM anlegt, erhält in der Standardeinstellung eine 20GB große Datei mit der Endung .qcow2
Die Dateigröße entspricht der Gesamtgröße der virtuellen Festplatte für diese VM, egal wie viel tatsächliche genutzt wird.
Bei Thinprovisioning wird nur der tatsächlich verwendete Speicherplatz im Hostsystem verwendet. D.h. wenn die VM-Festplatte mit 20GB konfiguriert wird, aktuell aber nur 5GB benutzt werden, so wird im Hostsystem auch nur eine ca. 5GB große Datei angelegt. Bei mehreren Systemen kann das ganz schön viel Speicherplatz sparen.
Nachteil: wächst der tatsächliche Speicherbedarf in den Virtuellen-Maschinen, wird ev. der zur Verfügung stehende Speicherplatz “gesprengt” und legt ev. das ganze Hostsystem incl. aller VMs lam …
Thin Provisioning QCOW2 Datei erzeugen
Um die nach der Default Installation erzeugte QCOW2 Datei zu verkleinern sind folgende Schritte notwendig:
- Die VM herunterfahren
- Die QCOW2 Datei umbenennen (bei mir befinden diese sich am Hostsystem unter /var/lib/libvirt/images), also wenn die VM den Namen server1 hat:
mv server1.qcow2 server1.qcow2_old
- Die Datei verkleinern
qemu-img convert -O qcow2 server1.qcow2_old server1.qcow2
- Zusätzlich kann man die Datei auch gleich komprimieren (Option -c), dass verlängert zwar die Zugriffszeiten etwas, spart aber noch mehr Platz. Allerdings werden später neu geschriebene Daten nicht automatisch komprimiert und der Vorgang muss gegebenenfalls (z.B. nach einem großen Update) wiederholt werden.
qemu-img convert -O qcow2 -c server1.qcow2_old server1.qcow2
- Mit kann man sich die Dateigrößen nun anzeigen lassen, wenn die VM nun gestartet wird und ohne Probleme läuft, kann man die Datei mit der Endung .qcow2_old löschen
ls -alh
Der hier beschrieben Weg führt aber nicht dauerhaft zu kleinen Dateien. Im Laufe der Zeit wächst mit jeden Schreibvorgang die QCOW2-Datei, bis sie die bei der Erstellung angegebenen Größe erreicht hat.
Dauerhaftes Thin Provisioning
Hier wird ein kleiner Trick verwendet, die eigentlich für SSDs benötigte TRIM-Funktion. Über TRIM teilt das Betriebssystem der Festplatte mit, dass es einen Block nicht mehr benötigt. SSDs können den Block dann speziell löschen um ihn später wieder beschreiben zu können.
Der QEMU-Treiber verwendet diese Funktion nun um den Bereich in der QCOW2-Datei mit neuen Daten beschreiben zu können, da er ja derzeit vom Betriebssystem nicht mehr verwendet wird.
Leider funktioniert das mit dem Standard-VirtIO Treiber von QEMU nicht, sondern man muss das System auf SCSI umstellen.
- Sicherstellen, dass in der VM das Festplatten-Device nicht direkt angesprochen wird, sondern über UUIDs (also z.B. nicht /dev/vda sondern UUID=ba207599-8491-4b7f-8594-6603c2f9d1cb) und zwar z.B. an folgenden Stellen (je nach Installation) – fstab – Grub – LVM
- VM herunterfahren
- Im Virt-Manager den/die Datenträger unter “Erweiterte Optionen”-> Festplattenbus von “VirtIO” auf “SCSI” umstellen.
- dadurch sollte gegebenenfalls ein neuer Eintrag “Steuerung SCSI” auftauchen, dort auf “VirtIO SCSI” umstellen
- am Hostsystem muss in der Config-Datei noch manuell folgender Eintrag hinzugefügt werden discard=‘unmap’ (ist derzeit leider nicht über den Virt-Manager möglich)
virsh edit server1
...
<devices>
<emulator>/usr/bin/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' discard='unmap'/>
<source file='/var/lib/libvirt/images/plutos.qcow2'/>
<target dev='sda' bus='scsi'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
...
Anmerkung zu vi-Editor: Einfügen mit Einfg, dann ESC und mit :qw! speichern.
- Jetzt kann die VM wieder gestartet werden und mit kann geprüft werden, ob TRIM jetzt verwendet werden kann (hier sollte nicht 0 Byte aufscheinen)
lsblk -o MOUNTPOINT,DISC-MAX,FSTYPE
- mit kann TRIM einmal manuell aufgerufen werden. Nun kann man (falls noch nicht erfolgt) Thin Provisioning QCOW2 Datei erzeugen durchführen.
fstrim -av
- um TRIM automatisch im Betriebssystem zu aktivieren sind unter Debian oder Ubuntu folgende Schritte nötig
cp /usr/share/doc/util-linux/examples/fstrim.service /etc/systemd/system cp /usr/share/doc/util-linux/examples/fstrim.timer /etc/systemd/system systemctl enable fstrim.timer