VPN-Container bricht mit 'exec format error' ab: falsche Plattform
'exec format error' bedeutet, dass die Binärdatei für eine andere CPU gebaut wurde, nicht dass NET_ADMIN fehlt. Lesen Sie den Image-Index, bevor Sie Routen oder Zugangsdaten ändern.
Container, die sofort mit exec format error beenden, laden zu falschen Reflexen ein: eine Capability hinzufügen, ein Gerät einbinden, die Tunnelkonfiguration bearbeiten. Nichts davon trifft das Problem. Der Kernel konnte die Binärdatei überhaupt nicht ausführen, was in einem Container fast immer bedeutet, dass das Image auf eine andere CPU-Architektur als die des Hosts abzielt. Alles, was Sie an Routing, Zugangsdaten oder Rechten ändern könnten, geschieht, nachdem ein Programm gestartet wurde, und kein Programm wurde gestartet.
Die Startmeldung, die nach einem Konfigurationsfehler aussieht
Ein exec-Formatfehler kommt vom Loader, bevor die Anwendung auch nur eine Einstellung liest. Deshalb erzeugt er keine Konfigurationswarnungen und kein Tunnel-Log, weil kein lebender Prozess sie schreiben kann. Der Fehler ist außerdem bemerkenswert schnell, oft bevor überhaupt eine Zeile im Container-Log erscheint. Dieselbe kurze Meldung erscheint, ob die Binärdatei für eine andere Architektur, für ein anderes Betriebssystem oder beschädigt ist.
Halten Sie Laufzeitumgebung und Architektur zusammen mit der genauen Image-Referenz fest und prüfen Sie dann, was diese Referenz tatsächlich bietet. Bei Docker Desktop gehört die Containerplattform zur virtuellen Linux-Maschine und nicht zum Laptop, daher kann die Hostarchitektur allein irreführen. Lesen Sie die Indexeinträge für diese Referenz, statt den Marketingtext auf ihrer Tag-Seite.
Lesen Sie den Image-Index vor dem Startbefehl
Wenn eine Registry eine Multiplattform-Referenz veröffentlicht, zeigt der Tag auf einen Index, und jeder Eintrag nennt eine Plattform mit eigenem Digest. Untersuchen Sie die betreffende Referenz und nicht einen benachbarten Tag, und lesen Sie den Index, statt anzunehmen, was er enthält.
docker buildx imagetools inspect ghcr.io/example/vpn:1.4
docker image inspect --format '{{.Os}}/{{.Architecture}}' ghcr.io/example/vpn:1.4
Der erste Befehl listet die Plattformen auf, die die Referenz veröffentlicht. Der zweite meldet die Plattform des bereits lokal vorhandenen Images, und genau dieses wird die Laufzeit ausführen. Eine Referenz mit nur einem Eintrag bedeutet, dass jeder Host dieselbe Binärdatei erhält, und der Tag kann einer Maschine nicht helfen, für die er nie gebaut wurde.
Tags wählen eine Variante; sie erzeugen keine
Ein Multiplattform-Index lässt die Laufzeit einen passenden Eintrag wählen, was wirklich praktisch ist und oft mit Portabilität verwechselt wird. Die Auswahl ist ein Nachschlagen, keine Übersetzung: fehlt die Variante, gibt es nichts auszuwählen. Derselbe Tag kann auf zwei Hosts daher zu zwei verschiedenen Binärdateien führen, und auf einem Host führt er zu nichts Brauchbarem.
Das Anheften per Digest beseitigt die Unklarheit und ermöglicht auch eine spätere Prüfung, weil der Digest genau die getesteten Bytes identifiziert. Bewahren Sie diesen Digest zusammen mit dem Bereitstellungsdatensatz auf, statt sich auf den Tag zu verlassen, der zufällig aktuell war.
Emulation ist eine Vereinbarung, keine Übersetzungsschicht
Emulation über eine unterstützte Laufzeit kann einige nicht-native User-Space-Workloads ausführen, sodass die absolute Behauptung, eine Architektur könne nie das Image einer anderen ausführen, falsch ist. Sie ist auch keine allgemeine Lösung. Emulierte Ausführung hat andere Leistungsmerkmale, und ein trivialer Prozess, der startet, sagt nichts darüber aus, ob sich ein Tunnel-Workload akzeptabel verhält.
Dockers Multiplattform-Leitfaden behandelt native Builds, Cross-Kompilierung und Emulation als getrennte Strategien, und so liest man die Optionen richtig. Wählen Sie eine bewusst und qualifizieren Sie den VPN-Workload darunter, statt Äquivalenz anzunehmen.
Berechtigungen lösen ein anderes Problem
Eine Netzwerkverwaltungs-Capability zu erteilen oder ein TUN-Gerät durchzureichen kann eine inkompatible ausführbare Datei nicht zum Laufen bringen. Das sind Laufzeitberechtigungen, die ein laufender Prozess nutzt; für einen Loader, der die Datei bereits abgelehnt hat, sind sie unsichtbar.
Das Umgekehrte gilt ebenso. Eine native Binärdatei beweist nichts über Privilegien, Gerätezugriff, Resolver-Integration oder die Neustartrichtlinie, die ein Tunnel braucht, daher ist ein Container, der startet, noch kein Container, der funktioniert. Legen Sie zuerst den Plattformvertrag fest und gehen Sie dann zum Laufzeitvertrag mit seinen dokumentierten Optionen über.
Bewahren Sie Image-Digest, unterstütztes Ziel und Konfiguration gemeinsam in demselben Datensatz auf. Eine Tag-Aktualisierung, die still die Architektur ändert, lässt sich leichter erkennen, wenn der vorherige Digest niedergeschrieben ist, als wenn das einzige Symptom ein vertrauter Fehler und ein frischer Nachmittag Fehlersuche ist.