Les conteneurs qui s’arrêtent immédiatement avec exec format error invitent au mauvais réflexe: ajouter une capacité, monter un périphérique, modifier la configuration du tunnel. Aucune de ces pistes n’atteint le problème. Le noyau n’a pas pu exécuter le binaire du tout, ce qui, dans un conteneur, signifie presque toujours que l’image cible une architecture de processeur différente de celle de l’hôte. Tout ce que vous pourriez changer au routage, aux identifiants ou aux privilèges se produit après le démarrage d’un programme, et aucun programme n’a démarré.

Le message de démarrage qui ressemble à une erreur de configuration

Un échec de format exec vient du chargeur, avant que l’application ne lise le moindre réglage. C’est pourquoi il ne produit aucun avertissement de configuration ni journal de tunnel, car aucun processus vivant n’est là pour les écrire. L’échec est aussi remarquablement rapide, souvent avant même qu’une ligne n’apparaisse dans le journal du conteneur. Le même court message apparaît que le binaire soit destiné à une autre architecture, à un autre système d’exploitation ou qu’il soit endommagé.

Notez l’environnement d’exécution et l’architecture à côté de la référence exacte de l’image, puis vérifiez ce que cette référence propose réellement. Sur Docker Desktop, la plateforme du conteneur appartient à la machine virtuelle Linux et non au portable, si bien que l’architecture de l’hôte seule peut induire en erreur. Lisez la liste des entrées d’index de cette référence plutôt que le texte marketing de sa page d’étiquette.

Lisez l’index de l’image avant la commande d’exécution

Lorsqu’un registre publie une référence multiplateforme, l’étiquette pointe vers un index, et chaque entrée nomme une plateforme avec son propre digest. Inspectez la référence à l’étude plutôt qu’une étiquette voisine, et lisez l’index au lieu de supposer ce qu’il contient.

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

La première commande liste les plateformes que la référence publie. La seconde indique la plateforme de l’image déjà présente localement, et c’est celle que le runtime exécutera. Une référence avec une seule entrée signifie que chaque hôte reçoit le même binaire, et l’étiquette ne peut pas aider une machine pour laquelle elle n’a jamais été construite.

Les étiquettes sélectionnent une variante; elles n’en créent pas

Un index multiplateforme permet au runtime de choisir une entrée correspondante, ce qui est vraiment pratique et souvent confondu avec la portabilité. La sélection est une recherche, pas une traduction: si la variante est absente, il n’y a rien à sélectionner. La même étiquette sur deux hôtes peut donc se résoudre en deux binaires différents, et sur un hôte elle ne se résout en rien d’utilisable.

L’épinglage par digest lève l’ambiguïté et rend aussi possible une revue ultérieure, car le digest identifie exactement les octets testés. Conservez ce digest avec l’enregistrement de déploiement au lieu de vous fier à l’étiquette qui se trouvait être à jour.

L’émulation est un arrangement, pas une couche de traduction

L’émulation via un runtime pris en charge peut exécuter certaines charges de travail non natives en espace utilisateur, donc l’affirmation absolue qu’une architecture ne pourra jamais exécuter l’image d’une autre est fausse. Ce n’est pas non plus une solution générale. L’exécution émulée a des caractéristiques de performance différentes, et un processus trivial qui démarre ne vous dit rien sur le comportement acceptable d’une charge de tunnel.

Le guide multiplateforme de Docker traite les builds natifs, la compilation croisée et l’émulation comme des stratégies distinctes, et c’est la bonne façon de lire les options. Choisissez-en une délibérément et qualifiez la charge VPN en dessous plutôt que de supposer une équivalence.

Les permissions résolvent un autre problème

Accorder une capacité d’administration réseau ou faire passer un périphérique TUN ne peut pas faire fonctionner un exécutable incompatible. Ce sont des permissions d’exécution qu’utilise un processus en cours; elles sont invisibles pour un chargeur qui a déjà refusé le fichier.

L’inverse est tout aussi vrai. Un binaire natif ne prouve rien sur les privilèges, l’accès aux périphériques, l’intégration du résolveur ou la politique de redémarrage dont un tunnel a besoin, donc un conteneur qui démarre n’est pas encore un conteneur qui fonctionne. Établissez d’abord le contrat de plateforme, puis passez au contrat d’exécution avec ses options documentées.

Gardez le digest de l’image, la cible prise en charge et la configuration ensemble dans le même enregistrement. Une mise à jour d’étiquette qui change silencieusement l’architecture est plus facile à détecter lorsque le digest précédent est consigné que lorsque le seul symptôme est une erreur familière et un nouvel après-midi de débogage.

Articles similaires