Containers die direct stoppen met exec format error nodigen uit tot het verkeerde instinct: een capability toevoegen, een apparaat koppelen, de tunnelconfiguratie aanpassen. Niets daarvan raakt het probleem. De kernel kon de binary helemaal niet uitvoeren, wat in een container bijna altijd betekent dat de image op een andere CPU-architectuur dan die van de host is gericht. Alles wat je aan routing, inloggegevens of rechten zou kunnen wijzigen, gebeurt nadat een programma is gestart, en er is geen programma gestart.

De opstartmelding die op een configuratiefout lijkt

Een exec-formaatfout komt van de loader, voordat de toepassing ook maar één instelling leest. Daarom levert die geen configuratiewaarschuwingen en geen tunnellog op, omdat er geen levend proces is om ze te schrijven. De fout is ook opmerkelijk snel, vaak voordat er überhaupt een regel in het containerlog verschijnt. Dezelfde korte melding verschijnt of de binary voor een andere architectuur, voor een ander besturingssysteem of beschadigd is.

Leg de runtime-omgeving en architectuur vast samen met de exacte image-referentie en controleer vervolgens wat die referentie werkelijk biedt. Op Docker Desktop hoort het containerplatform bij de virtuele Linux-machine en niet bij de laptop, dus de hostarchitectuur alleen kan misleiden. Lees de indexvermeldingen voor deze referentie in plaats van de marketingtekst op de tagpagina.

Lees de image-index vóór het uitvoercommando

Wanneer een registry een multiplatform-referentie publiceert, wijst de tag naar een index en elke vermelding noemt een platform met zijn eigen digest. Onderzoek de referentie die wordt beoordeeld, niet een naburige tag, en lees de index in plaats van aan te nemen wat erin staat.

docker buildx imagetools inspect ghcr.io/example/vpn:1.4
docker image inspect --format '{{.Os}}/{{.Architecture}}' ghcr.io/example/vpn:1.4

Het eerste commando somt de platforms op die de referentie publiceert. Het tweede meldt het platform van de image die al lokaal aanwezig is, en dat is degene die de runtime uitvoert. Een referentie met slechts één vermelding betekent dat elke host dezelfde binary ontvangt, en de tag kan een machine niet helpen waarvoor hij nooit is gebouwd.

Tags selecteren een variant; ze maken er geen

Een multiplatform-index laat de runtime een overeenkomende vermelding kiezen, wat echt handig is en vaak met overdraagbaarheid wordt verward. De selectie is een opzoeking, geen vertaling: als de variant ontbreekt, valt er niets te selecteren. Dezelfde tag kan op twee hosts dus tot twee verschillende binaries leiden, en op één host leidt hij tot niets bruikbaars.

Vastzetten op digest neemt de dubbelzinnigheid weg en maakt ook een latere beoordeling mogelijk, omdat de digest precies de geteste bytes identificeert. Bewaar die digest bij het uitrolrecord in plaats van te vertrouwen op de tag die toevallig actueel was.

Emulatie is een regeling, geen vertaallaag

Emulatie via een ondersteunde runtime kan sommige niet-native userspace-workloads draaien, dus de absolute bewering dat de ene architectuur nooit de image van de andere kan draaien, is onjuist. Het is ook geen algemene oplossing. Geëmuleerde uitvoering heeft andere prestatiekenmerken, en een triviaal proces dat start zegt niets over de vraag of een tunnelworkload zich acceptabel gedraagt.

Dockers multiplatform-gids behandelt native builds, cross-compilatie en emulatie als afzonderlijke strategieën, en dat is de juiste manier om de opties te lezen. Kies er één bewust en kwalificeer de VPN-workload eronder in plaats van equivalentie aan te nemen.

Rechten lossen een ander probleem op

Een netwerkbeheercapability geven of een TUN-apparaat doorgeven kan een incompatibel uitvoerbaar bestand niet laten draaien. Dit zijn runtimerechten die een lopend proces gebruikt; ze zijn onzichtbaar voor een loader die het bestand al heeft geweigerd.

Het omgekeerde is even waar. Een native binary bewijst niets over rechten, apparaattoegang, resolver-integratie of het herstartbeleid dat een tunnel nodig heeft, dus een container die start is nog geen container die werkt. Leg eerst het platformcontract vast en ga daarna over naar het runtimecontract met zijn gedocumenteerde opties.

Bewaar de image-digest, het ondersteunde doel en de configuratie samen in hetzelfde record. Een tag-update die stil de architectuur verandert, is gemakkelijker te betrappen wanneer de vorige digest is opgeschreven dan wanneer het enige symptoom een bekende fout en een nieuwe middag debuggen is.

Gerelateerde artikelen