Stolperfalle: Proxmox VE und OCFS2 Shared Storage
Proxmox VE (Virtual Environment) erfreut sich, nicht zuletzt wegen des Broadcom-/VMware-Deals, regem Interesse. Für viele ist der Hypervisor eine willkommene Alternative zu vSphere ESXi - unterscheidet sich jedoch hinsichtlich des Storages. Hier hat man i.d.R. die Wahl zwischen:
- NFS/CIFS
- iSCSI
- Btrfs (technical preview)
- LVM
- ZFS
- CephFS/Ceph RBD
- Gluster
Snapshot-Funktionalität wird jedoch nicht bei allen Speichertypen unterstützt - hier sollte die Wahl idealerweise auf die folgenden fallen:
- NFS/CIFS (sofern qcow zum Einsatz kommt)
- ZFS (lokal/over iSCSI)
- LVM (thin-provisioned)
- Gluster (sofern qcow zum Einsatz kommt)
- CephFS/Ceph RBD
Mehr technische Details finden sich im Wiki des Herstellers.
Ceph ist vor allem bei HCI-Setups (hyper-converged infrastructure) mit lokalem Speicher interessant, während konventionelle Server im Rechenzentrum eher auf iSCSI oder Fibre-Channel-Storage setzen dürften. Leider wird genau letzteres nur mit LVM als Shared Storage unterstützt und bietet somit keinen Snapshot-Support.
Oracle Cluster Filesystem 2
Ein anderer Ansatz besteht darin, OCFS2 auf einer Shared Disk (z.B. über Multipath) einzusetzen und das Volume als lokales Verzeichnis einzuhängen.
OCFS2 ist ein Cluster-Dateisystem mit einem verteilten Lock-Manager, welcher den gleichzeitigen Zugriff auf den Speicher regelt. Seit Version 2.6.16 ist es offizieller Bestandteil des Linux-Kernels. Zur Kommunikation wird standardmäßig TCP-Port 7777 verwendet. Das Werkzeug o2cb
befüllt die Konfigurationdatei /etc/ocfs2/cluster.conf
.
Die hier gezeigte Vorgehensweise wird nicht offiziell von Proxmox unterstützt. Support-Anfragen werden nur nach best effort bearbeitet.
Implementation
Zunächst werden die OCFS2-Tools installiert und Verzeichnisse für den Lock Manager und den Mountpoint angelegt.
1# apt-get install ocfs2-tools
2# mkdir /dlm /mnt/ocfs
In der Konfigurationsdatei /etc/default/o2cb
müssen zwei Parameter geändert werden:
1O2CB_ENABLED=true
2O2CB_BOOTCLUSTER=MYPVE
Auf allen Clusterknoten müssen die folgenden Kommandos ausgeführt werden, um den Cluster anzulegen und zu initialisieren:
1# o2cb add-cluster MYPVE
2# o2cb add-node --ip <ip> MYPVE node01
3# o2cb add-node --ip <ip> MYPVE node02
4...
5# /etc/init.d/o2cb enable
Das Dateisystem wird anschließend auf einem Clusterknoten wie folgt erstellt:
1# mkfs.ocfs2 -J block64 -T vmstore -L mypve /dev/mapper/<name>
Damit das Volume beim Booten eingehängt wird, muss noch eine Zeile in die Datei /etc/fstab
eingefügt werden:
1LABEL=mypve /mnt/ocfs ocfs2 _netdev,defaults 0 0
Abschließend wird der neue Speicher eingehängt und ein neuer Proxmox-Speicher angelegt (/etc/pve/storage.cfg
):
1# mount -a
1dir: mypve
2 path /mnt/ocfs
3 content snippets,images,vztmpl,iso,rootdir
4 is_mountpoint /mnt/ocfs
5 shared 1
Weitere technische Details finden sich in folgender Präsentation von Heinlein Support.
Upgrade-Stolperfallen
Einen sehr beunruhigenden Fehler habe ich kürzlich bei einem Upgrade von Proxmox 8.0 auf 8.1 beobachtet. Hier hat sich die Version des Linux-Kernels von 6.2.16 auf 6.5.11 geändert - und dadurch auch die Version des ocfs2
-Moduls.
Üblicherweise ist das Vorgehen beim Patchen eines Clusters wie folgt:
- Evakuieren eines Knotens durch Verschieben der VMs auf einen anderen Knoten
- Patchen und Rebooten des Knoten
- Zurückverschieben der VMs
- Wiederholen der Schritte für den nächsten Knoten
Die letzten beiden Schritte funktionierten aber nicht. Zwar wurde das OCFS2-Volume wieder korrekt eingebunden und Dateien konnten auf dem frisch gepatchten Knoten eingesehen und auch beschrieben werden - der Betrieb von VMs war aber nicht möglich. VMs konnten zwar gestartet werden, waren aber nicht in der Lage auf den Speicher zu schreiben. Auffällig waren die Fehlermeldungen im Kernel-Log:
1(kvm,182849,0):ocfs2_dio_end_io:2423 ERROR: Direct IO failed, bytes = -5
2(kvm,182849,0):ocfs2_dio_end_io:2423 ERROR: Direct IO failed, bytes = -5
3(kvm,182849,7):ocfs2_dio_end_io:2423 ERROR: Direct IO failed, bytes = -5
4(kvm,182849,7):ocfs2_dio_end_io:2423 ERROR: Direct IO failed, bytes = -5
Ein erneutes Rebooten in den alten Kernel löste die Zugriffsprobleme. In diesem konkreten Fall ist ein Updaten des Clusters ohne Downtime somit unmöglich - was die Idee eines Clusters ad-absurdum führt.
Mir ist nicht ganz klar, ob OCFS2 generell nur dann funktioniert, wenn alle Clusterknoten die gleiche Modulversion haben - oder ob es bei diesem konkreten Versionssprung einfach breaking changes gab. Zwischen den beiden Kernel-Versionen habe ich die folgenden Änderungen an OCFS2 in den Changelogs festgestellt:
- ocfs2: fix data corruption after failed write (6.3)
- ocfs2: fix use-after-free when unmounting read-only filesystem (6.3.9 und 6.4)
- ocfs2: Switch to
security_inode_init_security()
(6.4)- neues Format von erweiterten Dateisystem-Attributen (
xattrs
) wird eingesetzt
- neues Format von erweiterten Dateisystem-Attributen (
- ocfs2: remove redundant assignment to variable bit_off (6.5)
Eine weitere Fehlermeldung im Kernel-Log scheint bei letzterem in die Richtung zu gehen:
1Jan 05 13:37:00 proxmox01 kernel: seq_file: buggy .next function ocfs2_dlm_seq_next [ocfs2] did not update position index
Unter diesen Umständen muss ich vom Einsatz von OCFS2 in Zusammenhang mit Proxmox eher abraten. 🫠
Ergänzung vom 27.03.2024: Zwischenzeitlich wurde im Proxmox-Forum ein Workaround aufgezeigt. Dieser besteht darin, den VM-Paramter aio
auf den Wert threads
zu setzen.