ZVOL in Promox verkleinern – Was es zu beachten gibt

Hier ein paar kurze Eckpunkte, was es zu beachten gibt, wenn man ein ZVOL in Proxmox verkleinern will (in meinem Fall eine Windows-Partition):

  • NTFS verkleinern -> am besten mit EaseUS Partition Master Free
  • Alle Partitionen verschieben, sodass der freie Platz ganz hinten ist.
  • zfs set volsize=200G rpool/vm-100-disk-0 (ACHTUNG, 3x kontrollieren ob das auch stimmt!)(Kann sehr lange dauern)

In Proxmox zu rpool eine weitere SSD/HDD hinzufügen

Neulich kam ich in die Situation, dass ich bei einer älteren Proxmox-Installation auf nur eine SSD als Boot-Drive traf. Das ist natürlich sehr schlecht, zumal auf der SSD auch noch VMs und LXCs rannten, die im Falle eines Hardware-Defekts dann kaputt gewesen wären. Mit ZFS ist es jedoch relativ einfach möglich, hier eine weitere SSD hinzuzufügen, damit dann in Zukunft von einem ZFS-mirror gebootet werden kann. Leider ist der genaue Ablauf aber nicht gut dokumentiert seitens Proxmox, deshalb dieser Artikel.

Zu Beginn machen wir am System einmal zpool status -v:

  pool: rpool
 state: ONLINE
status: Some supported features are not enabled on the pool. The pool can
        still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
        the pool may no longer be accessible by software that does not support
        the features. See zpool-features(5) for details.
  scan: none requested
config:

        NAME                                                 STATE     READ WRITE CKSUM
        rpool                                                ONLINE       0     0     0
          mirror-0                                           ONLINE       0     0     0
            sda3                                             ONLINE       0     0     0

Was in diesem Fall zusätzlich schlecht ist: Sollte das System auf die Idee kommen, die Festplatte nicht mehr auf sde3 zu legen, kann es sein, dass sich der Pool nicht mehr findet. Das wollen wir natürlich nicht, aber eines nach dem anderen.

Zunächst müssen wir eine weitere SSD, im Idealfall mit gleicher Größe einbauen. Dann können wir uns mit dem Befehl hwinfo --disk oder mit fdisk -l oder mit lsblk die neue Platte suchen. Auch in der Proxmox-GUI können wir unter Disks die neue Platte sehen. Sollten wir nur die /dev/sdx-Identifikation wissen, dann einfach mit hwinfo --disk | grep /dev/sda nachsehen, wie der by-id Pfad der Festplatte heißt. Ob man hier die ata-... Bezeichung oder die wnn-... verwendet, bleibt jedem selbst überlassen, ich verwende für meinen rpool die ata- Schreibweise.

Bevor wir uns jedoch nun ins Vergnügen stürzen, müssen wir uns noch die Boot-Sektoren und EFI-Disk kopieren. Das geht mit folgender Befehlsreihe (hier kann man auch die /dev/sdx Bezeichner verwenden, weil man das ohnehin nur einmal macht. In diesem Fall ist /dev/sda die bestehende SSD und /dev/sdb die Neue:

WARNUNG: Das sind gefährliche Befehle. Bitte kontrolliert 3x, am besten im 4-Augen-Prinzip, ob die Platten auch wirklich die richtigen sind. Sollte hier etwas schief gehen, habt ihr euch das Proxmox-System richtig zerfetzt.

sgdisk --replicate=/dev/sdb /dev/sda
sgdisk --randomize-guids /dev/sdb
grub-install /dev/sdb

Was hier passiert ist folgendes:
Im ersten Befehl wird das Partitionsschema auf die neue SSD repliziert.
Im zweiten Schritt wird die GUID mit einem Zufallswert neu gesetzt, damit es hier zu keinem Blödsinn kommt.
Im dritten Schritt installieren wir GRUB2, den Bootloader von Debian bzw. Proxmox, auf die neue Platte in die zuvor kopierten Partitionen.

ANMERKUNG!

Wie hier zu sehen, kann es auch sein, dass man anstatt grub-install oder zuätzlich das Tool pve-efiboot-tool verwenden kann/muss/soll? Das muss ich erst evaluieren, eventuell hängt das mit BIOS vs. UEFI-Boot zusammen. Sobald dies getestet ist, werde ich den Artikel dementsprechend anpassen! Das wären die folgenden 2 Befehle:

pve-efiboot-tool format /dev/sdb2 --force
pve-efiboot-tool init /dev/sdb2

Die offizielle Empfehlung von Proxmox ist anscheinend, grub-install, aber das kann natürlich auch veraltet sein (siehe hier).

ANMERKUNG ENDE!

Nachdem die Platte nun bootfähig ist, können wir die dritte Partition, auf der nun ZFS die Daten speichern soll, in den ZFS-Pool rpool hängen. Hier verwenden wir nun die vorher erklärten ata-... Identifier. Wichtig ist hier zu beachten, der Befehl sowohl den Namen des aktuellen Pools haben möchte (hier rpool), als auch die aktuelle SSD, auf der der Pool gespeichert ist (in diesem Fall sda3). Der Identifier der bestehenden Disk kann hier jedoch nicht irgendwie verwendet werden (also nicht ata-Schreibweisen, wnn-Schreibweise etc.), sondern muss exakt mit der Schreibweise ident sein, die bei zpool status -v gezeigt wird. In meinem Fall (siehe oben) ist das nur sda3, ohne /dev oder ähnlichem davor. Die Platte, die wir hinzufügen wollen, benennen wir aber sehr wohl nach dem by-id Schema, damit wir die oben beschriebene Problematik, dass das System die Platte nicht mehr auf /dev/sda legen könnte, nicht haben. Hier ist auch zu beachten, dass die ZFS-Partition nun die Partition 3 ist, weil auf Part1 die Boot-Partition liegt und auf Part2 die EFI-Disk. Das sieht dann in meinem Fall so aus (mit Zensur des Herstellers und der Seriennummer):

zpool attach rpool sda3 /dev/disk/by-id/ata-Herstellergedöns-part3

Mit dem Befehl zpool status -v 5 könnt ihr nun zusehen, wie das System resilvered (Die 5 gibt dabei die Aktualisierungsrate in Sekunden an).

Bevor das System nicht resilvered ist, solltet ihr es nicht rebooten, sonst könnte es zu Problemen kommen.

Um einen misslungenen Identiefier auszubessern, eignet sich diese Anleitung.

Links und Credit

https://forum.proxmox.com/threads/different-size-disks-for-zfs-raidz-1-root-file-system.22774/post-208998
https://pve.proxmox.com/wiki/ZFS:_Tips_and_Tricks
https://pve.proxmox.com/pve-docs/pve-admin-guide.html#sysboot
https://forum.proxmox.com/threads/proxmox-zfs-mirror-install-with-one-disk-initially.53601/
https://briankoopman.com/moving/
https://askubuntu.com/questions/27997/which-hard-disk-drive-is-which
https://forum.proxmox.com/threads/zfs-attach-on-boot-drive-is-there-a-right-way.61761/
https://pve.proxmox.com/wiki/ZFS:_Tips_and_Tricks#Replacing_a_failed_disk_in_the_root_pool
https://plantroon.com/changing-disk-identifiers-in-zpool/

Proxmox-Container (LXC) lässt sich nach Proxmox-Upgrade nicht mehr starten

Nach dem Proxmox-Upgrade wollte bei mir ein Proxmox-Container nicht mehr booten, die Fehlermeldung war leider nicht sehr aussagekräftig.

Nach kurzem googlen dann die Lösung: das ZFS-Subvol wollte sich nicht mounten lassen, weil das Verzeichnis nicht leer war. Hier war ein leeres dev/ Verzeichnis Schuld an dem Unglück. Nach dem Löschen des dev/ Verzeichnisses kann man das Image selbst mit zfs mount einbinden.

Kurzes Beispiel:

Euer Container mit der ID 100 wurde auf ein ZFS-Storage installiert. Nehmen wir an, das war direkt auf dem lokalen ZFS-Pool von Proxmox, dem rpool/data/. Nun wollt ihr den Container starten, doch das funktioniert nicht. Also macht ihr ls -alh /rpool/data/subvol-100-disk1/ und seht dort ein Verzeichnis dev/, das leer ist.

Wenn ansonsten nichts zu sehen ist außer dieses leere dev/ Verzeichnis, dann könnt ihr mit rm -r /rpool/data/subvol-100-disk1/dev dieses löschen. Anschließend macht ihr zfs mount rpool/data/subvol-100-disk1, und wenn das ohne Probleme und Fehlermeldung funktioniert, sollte der Container wieder starten.

Ich habe heute das Problem nicht wegbekommen, und nach einem Neustart war es immer und immer wieder soweit, dass die Container nicht starten wollten. Dabei war die Lösung doch recht einfach: Anstatt nur den dev-Ordner zu löschen, müssen alle Datasets des betroffenen Pools unmountet werden, um danach den Ordner auf root-Ebene, also zB rm -rf /data_redundant, zu löschen. Danach einfach mittels Befehl systemctl restart zfs-mount.service den Dienst neu starten. Gelingt das ohne Fehlermeldung, sollte auch nach einem Reboot alles in Ordnung sein.

Was außerdem noch seitens Proxmox empfohlen wird, ist das Cachefile des zpools neu zu setzen. Ich hab das Anfangs ohne Erfolg versucht, aber vielleicht hilft es ja, solchen neuen Fehlern vorzubeugen, ich hatte nämlich seither keine Probleme mehr. Nachdems nicht geschadet hat, einfach mal zustätzlich ins Terminal reinklopfen:

zpool set cachefile=/etc/zfs/zpool.cache POOLNAME
update-initramfs -u -k all
Links und Credit

https://forum.proxmox.com/threads/lxc-container-cant-start.53431/
https://forum.proxmox.com/threads/update-broke-lxc.59776/#post-277303
https://forum.proxmox.com/threads/update-broke-lxc.59776/post-329812
https://forum.proxmox.com/threads/lxc-not-starting-after-v5-to-v6-upgrade-using-zfs-for-storage.57698/post-269706
https://proxmox-openvz.blogspot.com/2019/05/debugging-proxmox-lxc-container-that.html

Große VMs/LXCs migrieren mit minimaler Downtime – Proxmox

Ich hatte testweise 2 Proxmox-Hosts als Cluster im Betrieb, und wollte nun alle meine VMs und LXCs, die sich im Laufe der Zeit auf den 2 Hosts gebildet haben, auf einen Host migrieren. Leider funktioniert die Proxmox-GUI-Migration nur, wenn beide Hosts einen gleichen Speicher haben, zB local-lvm. Da aber ein Host bei mir ZFS Mirror als Base-System hat, und der andere LVM, funktioniert diese Methode nicht. Bei kleinen VMs und Containern, bei denen eine Downtime von 10 Minuten keine Tragik darstellt, lässt sich das ganze mit der Backup & Restore – Methodik bewerkstelligen. Dabei wird einfach die Instanz online genommen, mittels GUI eine Archiv der VM oder des Containers erstellt, diese wird dann im Terminal vom Pfad /var/lib/vz/dump/vzdump... auf den anderen Host mittels SCP kopiert und dort unter dem local-Datenspeicher ausgewählt und wieder eingespielt.

Was aber tun, wenn die VM oder der Container zB mehrere Tibibyte groß ist, wie es bei einer Nextcloud-Instanz schnell der Fall sein kann? In diesem Fall würde die Backup & Restore – Methode aus 2 Gründen nicht gut funktionieren:

  • Der lokale Speicher, wo das Betriebssystem installiert ist, hat meistens nicht mehrere Terabyte für ein Backup frei
  • Vor allem bei LXCs muss für ein Backup der Container zeitweise offline genommen werden, diese Downtime ist in den allermeisten Fällen nicht vertretbar

Nun gibt es mehrere Möglichkeiten, wie dieses Problem gelöst werden kann:

  1. Man fügt beiden Hosts einen Shared-Storage hinzu:
    • Dazu benötigt man jedoch einen dritten Host mit viel freiem Speicher, oder freie Anschlüssen an einem Proxmox-Host
    • Meistens hat man nicht mehrere Tibibyte an Festplatten zuhause liegen, die frei zur Verfügung sind
  2. Man macht es manuell über die Command-Line

Da ich keine Festplatten rumliegen habe, dich ich einfach so einbauen kann, kam für mich nur die 2. Möglichkeit in Frage, ich hatte nämlich in beiden Host Festplatten, die groß genug sind, die allerdings nicht leer sind. Da ich nicht mit Shared-Storage herumpfuschen wollte, den ich dann bei nur einem Host gar nicht brauchen kann und nur hinderlich ist, habe ich den Weg der direkten Migration über die Command-Line gewählt.

Mein Vorteil ist, dass beide Festplattenspeicher in meinen Hosts ZFS-Pools sind. Die genaue Konstellation ist dabei gar nicht wichtig, ob das jetzt ein ZFS-Mirror ist oder ein RAIDZ1, spielt keine Rolle. Wichtig ist nur, das genug Platz auf den Pools ist. In meinem Fall war die Nextcloud-Instanz schon auf dem ZFS-Pool installiert, sollte das nicht der Fall sein, kann aber die VM oder der Container über die GUI verschoben werden, sofern sich der Speicher im gleichen Host befindet.

Wenn nun auf einem Host die Instanz als Block-Storage auf ZFS vorhanden ist, können wir nun mit der manuellen Migration beginnen, die sich wie folgt darstellt:

  1. Einen ZFS-Snapshot der Instanz erstellen
  2. Diesen ZFS-Snapshot auf den 2. Host übertragen
  3. Gegebenfalls einen weiteren Zwischensnapshot machen und übertragen, falls die Nextcloud-Instanz regen Datenverkehr gesehen hat.
  4. Die Instanz herunterfahren
  5. Einen neuen ZFS-Snapshot auf dem 1. Host anfertigen
  6. Die Änderungen der Snapshots übertragen
  7. Die Config verschieben
  8. Die Config bearbeiten
  9. Die Instanz am anderen Host wieder booten

Im Falle von ZFS sieht das nun wie folgt aus:

  1. Der Snapshot kann über die GUI gemacht werden oder über die Command Line, das liegt jedem frei, mein Snapshot heißt „migration_state“
  2. Die Übertragung des ersten Snapshots erfolgt nun mittels ZFS send/receive vom ersten Host:
    zfs send --replicate --large-block --compressed --verbose zfspool1/subvol-161-disk-0@migration_state | ssh root@10.10.0.150 zfs recv -v zfspool2/subvol-161-disk-0
    Dies kann nun einige Zeit dauern, das lässt man am besten in Ruhe in einem tmux-Fenster werken und detached sich derweilen.
  3. Habe ich ausgelassen, weil ich meine Instanz ruhig für eine viertel Stunde offline nehmen kann, ohne das es jemanden stört. Falls es sich um eine viel-besuchte Instanz handelt, hier die Schritte Punkt 5 und 6 benutzen.
  4. Jetzt die Instanz herunterfahren, damit wir einen konsistenten Stand übertragen können.
  5. Nun fertigen wir erneut einen Snapshot wie in Punkt 1 an, meiner heißt final_state
  6. Nun übertragen wir die Änderungen des „migration_state“ und des neuen final_state Snapshots mittels diesem Befehl:
    zfs send --large-block --compressed --verbose -i migration_state zfspool1/subvol-161-disk-0@final_state | ssh root@10.10.0.150 zfs recv -v -F zfspool2/subvol-161-disk-0
    WICHTIG: Der bei -i angeführte Snapshot ist der letzte, der auf dem Host 2 vorhanden ist, der nach dem @ bei send ist der aktuellste, den wir übertragen wollen. Der Parameter -F bei recv ist dafür zuständig, das wir eventuelle Änderungen am Host 2 überschreiben. Das macht uns nichts aus, weil die Instanz ja noch nicht von dort läuft.
  7. Nun können wir die Config-File verschieben. Dies wird automatisch über das Proxmox-Cluster mit dem 2. Host synchronisiert. (In meinem Fall handelt es sich um einen LXC, bei VMs liegt die Config im Ordner qemu-server)
    mv /etc/pve/nodes/host1/lxc/161.conf /etc/pve/nodes/host2/lxc/
  8. Nun muss die Datei 161.conf bearbeitet werden, um jede Referenz auf das Dataset zu ändern:
    nano /etc/pve/nodes/host2/lxc/161.conf
    In unserem Fall wird
    zfspool1/subvol-161-disk-0
    zu
    zfspool2/subvol-161-disk-0
    ausgebessert. Je mehr Snapshots von dieser VM vorhanden sind, umso mehr Zeilen müssen ausgebessert werden.
  9. Nun können wir die Instanz am neuen Host wieder booten. Alle Daten und Einstellungen sind übernommen, und die Instanz funktioniert wie sie soll.

Wenn das Prinzip einmal verstanden ist, kann das auch mit anderen Konstellationen funktionieren. Wichtig ist dabei immer, nicht zu voreilig zu handeln, und die Befehle bei Unsicherheit in einer Test-VM zu probieren, um keine bösen Überraschungen fürchten zu müssen.

Links und Credit

https://pve.proxmox.com/wiki/Backup_and_Restore
https://forum.proxmox.com/threads/migrating-vms-to-different-storage.49467/
https://docs.oracle.com/cd/E19253-01/820-2313/gbchx/index.html

ZFS Datasets – Snapshots und Offsite-Backup leicht gemacht – Sanoid

UPDATE vom UPDATE (19.12.2019): Der Fix unten hilft nur bedingt. Ich empfehle, bei cron mit dem Eintrag MAILTO="" die E-Mail-Benachrichtigung zu deaktvieren, damit ihr nicht genervt werden. Ich habe das Issue bei sanoid auf Github im Auge und werde den Artikel aktualiseren, sobald ich mehr weiß.

UPDATE/INFO (18.12.2019): Aktuell gibt es einen Bug, bei dem Sanoid ständig errors von sich gibt, die einem das ganze E-Mail-Postfach füllen (bei Proxmox zumindest). Um dieses Problem zu „lösen“ (quick and dirty fix), einfach den cron-Befehl

* 1 * * rm -r /var/run/sanoid_cacheupdate.lock

hinzufügen.

Heute bin ich auf ein kleines, aber feines Tool gestoßen: Sanoid. Dieses macht es einem einfach, automatische Snapshots eines ZFS-Datasets (zB eine Proxmox-VM auf einem ZFS-Pool) zu erstellen und diese dann auch gleich auf einen Offsite-Server zu sichern.

Das Tool ist gut dokumentiert, allerdings gibt es nicht viele Beispiele, wie genau eine Config aussehen muss. Man findet aber eine beispielhafte sanoid.conf und eine sanoid.defaults.conf, in denen viel erklärt wird.

Die Installation unter Proxmox ist sehr einfach (debian-based), einfach die Anleitung unter INSTALL.md auf GitHub befolgen, in 5 Minuten ist der Fall erledigt. Wichtig ist zu beachten, das sanoid auf dem Hypervisor direkt laufen muss, weil logischerweise ansonsten keine Möglichkeit besteht, die VMs wegzusichern.

Nachdem das ganze installiert ist, kann man unter

/etc/sanoid/sanoid.conf

einfach eine Konfiguration eintragen, in meinem Falle möchte ich zB einen Nextcloud-LXC sichern:

[data0/subvol-100-disk-0]
        use_template = prod


[template_prod]
        frequently = 0
        hourly = 1
        daily = 30
        monthly = 6
        yearly = 7
        autosnap = yes
        autoprune = yes

Hier beispielhaft ein stündlicher Snapshot (falls mir zufällig was blödes passiert während der Wartung, bei Dateischäden hat Nextcloud selbst außerdem eine eigene Versionierung), 30 tägliche Snapshots, 6 monatliche und 7 jährliche. Außerdem soll das ganze automatisch sowohl gesnapshottet werden, als auch gepruned (das heißt, das wenn zB ein neuer stündlicher Snapshot erstellt wird, der letzte gelöscht wird, weil wir ja nur einen stündlichen aufheben wollen).

Nun wird das ganze als Cronjob ausgeführt (in meinem Fall als root, man wird natürlich auch einen eigenen Benutzer machen können). Sanoid muss natürlich dort ausgeführt werden, wo ihr die git-repo hingeforkt habt.

* * * * * TZ=UTC /root/sanoid/sanoid --cron

Eine Minute warten, und siehe da, es funktioniert:

root@host:~# zfs list -rt snap
NAME                                                           USED  AVAIL  REFER  MOUNTPOINT
data0/subvol-100-disk-0@autosnap_2019-05-25_13:54:40_yearly      0B      -  30.1G  -
data0/subvol-100-disk-0@autosnap_2019-05-25_13:54:40_monthly     0B      -  30.1G  -
data0/subvol-100-disk-0@autosnap_2019-05-25_13:54:40_daily       0B      -  30.1G  -
data0/subvol-100-disk-0@autosnap_2019-05-25_12:04:01_hourly   4.19M      -  30.1G  -

Nun können wir mit dem 2. Tool namens syncoid das ganze auch offsite sichern. Dazu brauchen wir auf dem 2. Rechner nur einen ZFS-Pool, und ein paar Tools, die sich ganz einfach (in meinem Fall unter Debian) installieren lassen:

apt install pv mbuffer lzop

Ob die Tools wirklich notwendig sind weiß ich nicht auswendig, aber so funktioniert es bei mir auf jeden Fall.

Syncoid funktioniert über SSH, also am besten einfach eine public-authentication auf den Rechnern einrichten und SSH des Offsite-Rechners auf einen nicht-standardisierten Port legen.

Dann kann das ganze auch schon beginnen, mit einem Befehl:

syncoid data0/subvol-100-disk-0 root@offsite:zpool/dataset --sshport=12345 --source-bwlimit=400k

Man beachte: das Dataset wird von syncoid auf dem Offsite-Rechner angelegt, wenn man das selber macht, kommt eine Fehlermeldung bei syncoid. Mittels –help kann man noch weitere Optionen sehen, die nützlich sein können (je nach Szenario). Ich habe zum Beispiel noch die Bandbreite limitiert, um die A1-Leitung nicht komplett in Anspruch zu nehmen.

Nun wird das ganze einmal eine Weile in Anspruch nehmen. Aber keine Sorge, sollte das ganze länger dauern als das Cron-Interval, das ihr nun festlegt, wird das 2. mal einfach abgebrochen, solange hier noch übertragen wird. Da im Anschluss nur mehr Änderungen übertragen werden, solltet ihr in Zukunft auch kein Problem haben, das ihr den ganzen Tag die Internetleitung in Anspruch nehmt.

Jetzt noch das ganze als Cronjob anlegen (hier: jeden Tag um 2 in der Früh):

0 2 * * * /root/sanoid/syncoid data0/subvol-100-disk-0 root@offsite:zpool/dataset --sshport=12345 --source-bwlimit=400k

WICHTIG: Bei cronjobs immer den absoluten Pfad zum Programm angeben!

Um zu überprüfen, ob der Bandwidth-Limit funktioniert, empfehle ich euch „nload“, einfach über apt installiert, seht ihr genau, welche Bandbreite über eure Netzwerk-Interfaces benutzt werden.

syncoid übertragt alle Snapshot-Zwischenschritte, die ihr am System habt. Das heißt, das ihr auch die stündlichen, täglichen, usw. am anderen System habt. Sollte das nicht erwünscht sein, gibt es dafür eine entsprechende Option (–no-stream)

Ihr könnt auch als Beispiel im Falle von Proxmox einen Hot-Spare auf einem anderen Ort laufen haben, wo ihr immer diese Snapshots hinkopiert. Sollte euch der Standort abbrennen oder einfach der Server sterben, könnt ihr den anderen nehmen, hinstellen und (sofern ihr auch die Proxmox-notwendigen Konfigurationen etc. über zB ssh-copy übertragen habt) einfach weitermachen, womit ein schnelles weiterarbeiten gewährleistet ist.