Wir betreiben viele Dienste – teilweise mit rootful – Podman in unprivilegierten LXC-Containern unter Proxmox. Über Wochen tauchte immer wieder derselbe Fehler auf: Nach einem podman stop oder einem Neuerstellen per Ansible war der Dienst plötzlich nicht mehr erreichbar – „No route to host“, sogar lokal.
Das Symptom
podman stop meldete open container netns … No such file or directory. Der Container startete danach mit einer neuen IP, aber netavark ließ die alte Portweiterleitung (DNAT-Regel) stehen. Weil die alte Regel zuerst greift, landete der Verkehr bei einer IP, die es nicht mehr gab.
Die Ursache
Rootful Podman legt die Netzwerk-Namespaces unter /run/user/0/netns ab. Bei der ersten SSH-Anmeldung als root hängt systemd-logind aber ein frisches tmpfs über /run/user/0 – und hängt es bei der letzten Abmeldung samt Inhalt wieder aus.
- Namespaces aus dem Boot liegen unter dem tmpfs und sind in jeder SSH-Sitzung unsichtbar.
- Namespaces, die in einer SSH-Sitzung entstehen, sind nach dem Abmelden ganz weg.
In beiden Fällen findet der nächste podman stop seinen Namespace nicht, räumt das Netz nicht ab, und netavark hinterlässt eine verwaiste Regel. Ansible und CI-Runner melden sich per SSH an – genau deshalb trat der Fehler vor allem bei automatisierten Abläufen auf.
Nachweisen lässt es sich unschädlich mit einem Bind-Mount, der unter das tmpfs schaut:
d=$(mktemp -d); mount --bind /run $d; ls $d/user/0/netns; umount $d
Die Lösung
loginctl enable-linger root
Damit läuft user-runtime-dir@0 ab dem Boot dauerhaft und /run/user/0 wird nie mehr aus- und eingehängt. Zusätzlich ein Drop-in für podman-restart.service mit Wants= und After=user-runtime-dir@0.service, damit die Container beim Booten erst danach starten. Danach den LXC einmal neu starten.
Wir haben das als Ansible-Task ausgerollt und auf jedem Gast getestet: Stop/Start per SSH, neue IP, genau eine DNAT-Regel, Dienst intern und extern erreichbar.
Was wir außerdem gelernt haben
podman-compose downlöscht und erzeugt das Netz neu und ist besonders anfällig. Zum Neuerstellen lieber nur den Container entfernen undpodman-compose up -dausführen.podman-compose up --no-depslegt in Version 1.3 trotzdem alle Container des Stacks an und bricht bei laufenden Nachbarn ab. Statt des Exit-Codes prüfen wir, ob die Container wirklich laufen.- Nach jedem Neuerstellen eines Containers mit Port von außen: Erreichbarkeit prüfen, nicht nur den Status.
