Wenn plötzlich die wichtigste VM aus geht
„Ich geh nach Haus, das Licht bleibt aus…“
So ungefähr fühlte es sich an, als plötzlich meine wichtigste VM – ioBroker – verschwunden war. Keine Fehlermeldung im Webinterface, kein Absturzdialog, kein dramatischer Kernel-Panic-Screen. Die VM war einfach weg.
Der Übeltäter: der Linux OOM-Killer.
OOM steht für Out Of Memory. Wenn dem System der Arbeitsspeicher ausgeht, greift Linux zu einer letzten Notmaßnahme: Ein Prozess wird beendet, damit wieder Speicher frei wird.
Blöd nur, wenn das ausgerechnet die wichtigste VM ist.
In meinem Fall also: Licht aus.
Schnellnavigation
- Was ist der OOM-Killer?
- Wie erkennt man, dass der OOM-Killer zugeschlagen hat?
- Wie prüft man den verfügbaren RAM?
- Welche Hardware steckt eigentlich im Proxmox-Host?
- ZFS und ARC – der heimliche RAM-Verbraucher
- Mehr RAM – der einfachste Fix
- Wichtige VMs vor dem OOM-Killer schützen
- Copy & Paste: VM-Forensik-Skript für Proxmox
- Fazit
Was ist der OOM-Killer?
Linux versucht normalerweise alles, um ohne Totalausfall auszukommen. Wenn der RAM knapp wird, passiert zunächst Folgendes:
- Speicher wird freigeräumt
- Cache wird reduziert
- Swap wird verwendet
Erst wenn all das nicht mehr reicht, greift der Kernel zum letzten Mittel: Der OOM-Killer beendet Prozesse. Wer das nerdiger nachlesen will, findet in der offiziellen Linux-Dokumentation Details zum Verhalten des Speichermanagements und des OOM-Killers unter docs.kernel.org.
Der Kernel entscheidet dabei anhand verschiedener Kriterien, welcher Prozess „am ehesten entbehrlich“ ist. Leider bedeutet das oft ziemlich unromantisch:
Der Prozess mit dem größten Speicherverbrauch fliegt zuerst.
Auf einem Proxmox-Host sind das häufig die KVM-Prozesse, also laufende virtuelle Maschinen. Proxmox selbst dokumentiert die QEMU/KVM-Architektur und das Verhalten virtueller Maschinen in der offiziellen Doku unter pve.proxmox.com.
Wie erkennt man, dass der OOM-Killer zugeschlagen hat?
Der erste Hinweis findet sich im Systemlog. Auf einem Proxmox-Host kannst du einfach danach suchen:
dmesg | grep -i "out of memory"
Oder etwas ausführlicher:
journalctl -k | grep -i oom
Ein typischer Eintrag sieht zum Beispiel so aus:
Out of memory: Killed process 5003 (kvm) total-vm:11083204kB
Das bedeutet:
- Ein Prozess (
kvm) wurde beendet - Der Kernel hat ihn ausgewählt, um Speicher freizugeben
Wenn zusätzlich so etwas auftaucht:
task_memcg=/qemu.slice/111.scope
Dann weißt du sogar welche VM betroffen war.
In meinem Fall: VM 111 – ioBroker.
Praktisch ist dabei: Die Kernel-Dokumentation beschreibt auch, dass OOM-Ereignisse im Zusammenhang mit Speicherdruck und Auswahlkriterien protokolliert werden können. Wer tiefer graben will, kann zusätzlich in die Sysctl-Doku zu /proc/sys/vm schauen: Kernel-Dokumentation zu /proc/sys/vm.
Wie prüft man den verfügbaren RAM?
Der schnellste Überblick geht mit:
free -h
Beispielausgabe:
Mem: 8Gi total, 8Gi used, 0Gi free
Swap: 7.6G, 4.7G used
Hier siehst du sofort:
- Gesamter RAM
- Aktuelle Nutzung
- Swap-Verbrauch
Wenn Swap bereits stark benutzt wird, ist das ein Hinweis darauf, dass das System dauerhaft unter Speicherdruck steht. Für solche Fälle lohnt sich oft nicht erst akademisches Herumgeeier, sondern ein echter Blick auf die RAM-Ausstattung. Falls dein Host noch mit eher knappen 8 GB oder 16 GB unterwegs ist, kann ein Upgrade auf 32 GB DDR4-Arbeitsspeicher (bezahlter Link) oder bei passenden Plattformen auf ECC-RAM für Server und NAS-Systeme (bezahlter Link) oft mehr bewirken als jede noch so heldenhafte Shell-Magie.
Welche Hardware steckt eigentlich im Proxmox-Host?
Bevor man über Upgrades nachdenkt, sollte man prüfen, was tatsächlich verbaut ist. Das geht direkt über die Konsole.
Mainboard anzeigen:
dmidecode -t baseboard
Speicher anzeigen:
dmidecode -t memory
Oder kompakt:
dmidecode -t memory | grep -E "Size:|Speed:"
Damit sieht man sofort:
- Wie viele RAM-Module verbaut sind
- Welche Geschwindigkeit sie haben
- Welche Slots frei sind
Gerade bei gebrauchten Office-PCs, Mini-Servern oder alten Workstations ist das Gold wert. Sonst bestellt man im schlimmsten Fall motiviert irgendwelche Module, und das Board schaut einen anschließend an wie ein Beamter kurz vor Feierabend.
ZFS und ARC – der heimliche RAM-Verbraucher
Viele Proxmox-Installationen nutzen ZFS als Storage. Das ist extrem robust, bietet Prüfsummen, Snapshots und viele Dinge, wegen denen man sich ein bisschen fühlt, als hätte man plötzlich Enterprise-Spielzeug im Keller stehen.
Der Haken: ZFS nutzt RAM sehr aggressiv.
Der sogenannte ARC (Adaptive Replacement Cache) ist ein intelligenter Cache im Arbeitsspeicher. Je mehr RAM verfügbar ist, desto größer wird dieser Cache. Das ist grundsätzlich kein Bug, sondern genau so vorgesehen. OpenZFS dokumentiert ARC und die zugehörigen Parameter offiziell in der eigenen Doku, zum Beispiel über arcstat und die ZFS-Modulparameter.
Die aktuelle ARC-Größe lässt sich so anzeigen:
cat /proc/spl/kstat/zfs/arcstats | grep size
Bei wenig RAM kann ARC ein zusätzlicher Faktor sein, der den Speicherverbrauch erhöht. Das heißt nicht automatisch, dass ZFS „schuld“ ist – aber in kleinen Hosts mit mehreren VMs spielt es definitiv mit in derselben Speicher-Drama-AG.
Falls du ZFS produktiv im Homelab betreibst, kann auch ein Blick auf passende NVMe-SSDs für Storage und Cache-Aufgaben (bezahlter Link) sinnvoll sein. Mehr Performance ersetzt zwar keinen fehlenden RAM, aber in einem sauber geplanten Setup gehören Storage und Arbeitsspeicher nun mal zusammen wie Proxmox und „ich baue nur mal eben schnell noch eine VM“.
Mehr RAM – der einfachste Fix
In meinem Setup lief der Proxmox-Host ursprünglich mit 8 GB RAM.
Für:
- Proxmox selbst
- mehrere VMs
- ZFS
- Backups
ist das schlicht zu wenig.
Nach einem Upgrade auf 32 GB RAM sah die Lage plötzlich ganz anders aus. Genau deshalb ist zusätzlicher Arbeitsspeicher für viele Homelab-Systeme keine Luxus-Aufrüstung, sondern schlicht die vernünftigste Lösung. Wenn du gerade ohnehin nachrüstest, findest du passende Module zum Beispiel über 32-GB-DDR4-Kits (bezahlter Link) oder – falls dein System das unterstützt – über ECC-UDIMM-Module für zuverlässigere Server-Setups (bezahlter Link).
free -h
Mem: 31Gi total, 11Gi used, 18Gi free
Swap: 7.6Gi total, 0B used
Swap wird nicht mehr benutzt und der Host hat wieder ausreichend Reserven.
Und ja: Manchmal ist die beste Tuning-Methode eben nicht irgendein finsteres Kernel-Voodoo, sondern schlicht mehr RAM. Sehr unsexy. Sehr effektiv.
Wichtige VMs vor dem OOM-Killer schützen
Nicht jede VM in einem Proxmox-Homelab ist gleich wichtig. Wenn ein Testsystem abstürzt, ist das meist verschmerzbar. Wenn dagegen die zentrale Smart-Home-Instanz oder der ioBroker plötzlich verschwindet, sieht die Sache anders aus.
Linux besitzt dafür einen Mechanismus, mit dem Prozesse unterschiedlich priorisiert werden können: oom_score_adj. Dieser Wert beeinflusst, wie attraktiv ein Prozess für den OOM-Killer ist. Der Wertebereich liegt zwischen:
- -1000 → möglichst niemals beenden
- 0 → normale Priorität
- +1000 → möglichst zuerst beenden
Warum systemctl set-property hier nicht funktioniert
Ein naheliegender Versuch ist, die Priorität direkt über systemd zu setzen:
systemctl set-property 111.scope OOMScoreAdjust=-900
In der Praxis funktioniert das jedoch nicht zuverlässig, weil OOMScoreAdjust keine Runtime-Property ist, die sich hier einfach so setzen lässt. Proxmox beziehungsweise systemd quittiert das dann gern mit:
Unknown assignment: OOMScoreAdjust=-900
Wichtige VM direkt schützen
Stattdessen kann der Wert direkt am laufenden QEMU-Prozess der VM gesetzt werden:
PID="$(pgrep -f 'kvm.*-id 111' | head -n1)"
echo -900 > /proc/$PID/oom_score_adj
cat /proc/$PID/oom_score_adj
Damit wird der OOM-Score der VM deutlich reduziert und der Kernel wird versuchen, andere Prozesse zuerst zu beenden.
Opfer-VMs definieren
Der umgekehrte Ansatz ist ebenfalls möglich: weniger wichtige Systeme bekommen bewusst einen höheren Wert, damit sie im Ernstfall zuerst beendet werden.
PID="$(pgrep -f 'kvm.*-id 200' | head -n1)"
echo 500 > /proc/$PID/oom_score_adj
cat /proc/$PID/oom_score_adj
Man könnte es auch so formulieren:
Wenn jemand gehen muss, dann bitte zuerst die Testmaschine.
Wichtiger Hinweis und Hookscripts
Der manuelle Weg funktioniert zwar sofort, hat aber einen Haken: Nach jedem Neustart der VM bekommt der QEMU-Prozess eine neue PID und der Wert muss erneut gesetzt werden. In Proxmox lässt sich das eleganter lösen, indem man ein sogenanntes Hookscript verwendet. Hookscripts werden in bestimmten Lebenszyklus-Phasen einer VM ausgeführt, zum Beispiel direkt nach dem Start. In der post-start-Phase könnte ein kleines Skript automatisch die PID des QEMU-Prozesses ermitteln und den gewünschten oom_score_adj-Wert setzen. Damit wird der OOM-Schutz bei jedem VM-Start automatisch wieder aktiviert. Die Hookscript-Funktion dokumentiert Proxmox offiziell sowohl im qm-Handbuch als auch im Bereich QEMU/KVM Virtual Machines.
Für den Alltag heißt das: Manuell testen ist okay. Dauerhaft sauber wird es erst mit Automatisierung. Alles andere ist technisch gesehen nur glorifiziertes „Denk dran, das nach jedem Start wieder zu machen“ – also exakt die Sorte Plan, die in Homelabs irgendwann nachts um 23:47 Uhr implodiert.
Copy & Paste: VM-Forensik-Skript für Proxmox
Wenn eine VM plötzlich ausgeht und du nicht weißt, ob jemand sie heruntergefahren hat oder ob der Proxmox OOM-Killer zugeschlagen hat, hilft ein kleines Bash-Skript. Es sammelt automatisch die wichtigsten Logs und Statusinformationen.
Das Skript
#!/usr/bin/env bash
set -euo pipefail
VMID=111
SINCE="${1:-3 days ago}"
echo "== Proxmox VM-Forensik: VMID=$VMID | since: $SINCE =="
echo
echo "## 1) Status & Konfig (onboot/startup, etc.)"
qm status "$VMID" || true
echo
qm config "$VMID" | egrep -i '^(name:|onboot:|startup:|boot:|memory:|balloon:|cores:|sockets:|scsi|sata|virtio|net|agent:|machine:|bios:|ostype:|tags:)' || true
echo
echo "## 2) QEMU-Log der VM (letzte 250 Zeilen)"
QLOG="/var/log/pve/qemu-server/${VMID}.log"
if [[ -f "$QLOG" ]]; then
ls -lh "$QLOG"
echo
tail -n 250 "$QLOG"
else
echo "Kein Log gefunden: $QLOG"
fi
echo
echo "## 3) Proxmox Task-Index: Stop/Shutdown/Reset/Start"
if [[ -f /var/log/pve/tasks/index ]]; then
egrep -i "($VMID).*(qm (stop|shutdown|reset|start)|stop|shutdown|reset|start)" /var/log/pve/tasks/index | tail -n 300 || true
else
echo "Kein Task-Index gefunden: /var/log/pve/tasks/index"
fi
echo
echo "## 4) journalctl: qemu/vm/shutdown/stop/reset/watchdog/oom"
journalctl --since "$SINCE" --no-pager \
| egrep -i "(qemu|kvm|pvedaemon|pveproxy|vm|${VMID}|shutdown|poweroff|stop|reset|watchdog|oom|out of memory|killed process)" \
| tail -n 400 || true
echo
echo "## 5) Kernel-Log: OOM-Killer / I/O Errors / watchdog"
journalctl -k --since "$SINCE" --no-pager \
| egrep -i "(oom|out of memory|killed process|qemu|${VMID}|i/o error|blk|ext4|xfs|zfs|nvme|ata|watchdog|reset)" \
| tail -n 400 || true
echo
echo "## 6) Reboots des Hosts"
last -x | head -n 30 || true
echo
echo "== Ende =="
Was macht das Skript?
Ein paar interessante Bestandteile:
set -euo pipefail sorgt dafür, dass das Skript sauber arbeitet:
-ebeendet das Skript bei Fehlern-uverhindert die Nutzung nicht gesetzter Variablenpipefailsorgt dafür, dass Fehler in Pipes erkannt werden
VMID=111 definiert die VM, die untersucht werden soll. In meinem Fall war das die ioBroker-VM.
SINCE="${1:-3 days ago}" erlaubt optional einen Zeitraum beim Start des Skripts. Ohne Parameter werden automatisch die letzten drei Tage durchsucht.
Die einzelnen Blöcke sammeln dann gezielt Informationen:
- VM-Status und Konfiguration über
qm statusundqm config - QEMU-Logdatei der VM
- Proxmox Task-Historie, um manuelle Stop/Start-Aktionen zu erkennen
- System-Journal, um Ereignisse rund um qemu, shutdown oder OOM zu finden
- Kernel-Logs, in denen der OOM-Killer normalerweise sehr deutlich auftaucht
- Host-Reboots, die ebenfalls erklären können, warum eine VM plötzlich weg ist
Damit bekommt man eine kompakte Forensik-Ausgabe, ohne sich durch mehrere Logdateien kämpfen zu müssen. Falls du dir für solche Wartungsarbeiten ohnehin noch ein bisschen Infrastruktur gönnen willst, sind USB-Sticks für Boot- oder Rettungsmedien (bezahlter Link) oder zusätzliche SSDs für Backups und Migrationen (bezahlter Link) im Homelab oft sinnvoller als der zehnte spontane Adapterkauf aus einer nächtlichen „das könnte man bestimmt mal brauchen“-Laune.
Fazit
Der OOM-Killer ist kein Fehler, sondern eine Schutzfunktion des Linux-Kernels.
Er sorgt dafür, dass ein System unter extremem Speicherdruck nicht komplett abstürzt.
Problematisch wird es erst, wenn er die falschen Prozesse erwischt.
Mit ein paar einfachen Schritten lässt sich das Verhalten deutlich verbessern:
- Logs prüfen
- RAM-Auslastung analysieren
- wichtige VMs priorisieren
- bei Bedarf Hookscripts nutzen
- und im Zweifel schlicht aufrüsten
Und manchmal ist die simpelste Lösung tatsächlich die beste:
Mehr RAM.
Seit dem Upgrade auf 32 GB bleibt bei mir jedenfalls das Licht an.
Weitere Artikel rund um Proxmox und Homelab
Wenn du dich generell mit Proxmox im Homelab beschäftigst, könnten auch einige meiner anderen Beiträge interessant für dich sein. In meiner Proxmox Anleitung zeige ich die grundlegenden Schritte für Installation und erste Einrichtung eines eigenen Virtualisierungshosts. Wenn du Storage mit ZFS nutzt, lohnt sich außerdem ein Blick in den Artikel über das Verschieben von Proxmox-VMs und Containern auf ein ZFS-Mirror-Storage, in dem ich erkläre, wie man laufende Systeme sauber auf neuen Speicher umzieht.
Auch das Thema Backup spielt im Homelab eine große Rolle. In meinem Beitrag über den Proxmox Backup Server im Homelab beschreibe ich, wie ich mein Setup endlich vernünftig abgesichert habe und welche Vorteile ein dedizierter Backup-Server bringt. Falls du eher nach praktischen Anwendungsbeispielen suchst, findest du im Artikel zur Installation eines Teamspeak-Servers unter Proxmox eine komplette Schritt-für-Schritt-Anleitung für eine typische VM im Homelab.
Alle diese Artikel zeigen unterschiedliche Aspekte eines eigenen Virtualisierungsservers – von Storage über Backups bis zu praktischen Diensten, die auf einem Proxmox-Host laufen können.
* Affiliate-Link: Wenn du über so einen Link etwas kaufst, erhalte ich unter Umständen eine kleine Provision. Für dich ändert sich am Preis nichts.
GrayTheZebra ist Entwickler und Betreiber von prokrastinerd.de mit Fokus auf Smart Home ohne Cloud, ESP32 und MQTT-basierte Systeme. Alle Projekte basieren auf praktischer Umsetzung und eigener Hardwareentwicklung.
Autorprofil und Hintergrund:
Über GrayTheZebra

