⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Builds multi-plateformes

Un build multi-plateforme fait référence à une seule invocation de build qui cible plusieurs combinaisons de systèmes d'exploitation ou d'architectures de processeur différentes. Lors de la construction d'images, cela vous permet de créer une seule image qui peut s'exécuter sur plusieurs plateformes, telles que linux/amd64, linux/arm64 et windows/amd64.

Pourquoi des builds multi-plateformes ?

Docker résout le problème "ça marche sur ma machine" en empaquetant les applications et leurs dépendances dans des conteneurs. Cela facilite l'exécution de la même application sur différents environnements, tels que le développement, les tests et la production.

Mais la conteneurisation en elle-même ne résout qu'une partie du problème. Les conteneurs partagent le noyau de l'hôte, ce qui signifie que le code qui s'exécute à l'intérieur du conteneur doit être compatible avec l'architecture de l'hôte. C'est pourquoi vous ne pouvez pas exécuter un conteneur linux/amd64 sur un hôte arm64 (sans utiliser l'émulation), ou un conteneur Windows sur un hôte Linux.

Les builds multi-plateformes résolvent ce problème en empaquetant plusieurs variantes de la même application dans une seule image. Cela vous permet d'exécuter la même image sur différents types de matériel, tels que des machines de développement exécutant x86-64 ou des instances Amazon EC2 basées sur ARM dans le cloud, sans avoir besoin d'émulation.

Différence entre les images mono-plateforme et multi-plateformes

Les images multi-plateformes ont une structure différente des images mono-plateforme. Les images mono-plateforme contiennent un seul manifeste qui pointe vers une seule configuration et un seul ensemble de couches. Les images multi-plateformes contiennent une liste de manifestes, pointant vers plusieurs manifestes, chacun pointant vers une configuration et un ensemble de couches différents.

Structure d'image multi-plateforme

Lorsque vous poussez une image multi-plateforme vers un registre, le registre stocke la liste de manifestes et tous les manifestes individuels. Lorsque vous tirez l'image, le registre renvoie la liste de manifestes, et Docker sélectionne automatiquement la variante correcte en fonction de l'architecture de l'hôte. Par exemple, si vous exécutez une image multi-plateforme sur un Raspberry Pi basé sur ARM, Docker sélectionne la variante linux/arm64. Si vous exécutez la même image sur un ordinateur portable x86-64, Docker sélectionne la variante linux/amd64 (si vous utilisez des conteneurs Linux).

Prérequis

Pour créer des images multi-plateformes, vous devez d'abord vous assurer que votre environnement Docker est configuré pour le prendre en charge. Il y a deux façons de le faire :

  • Vous pouvez passer du magasin d'images "classique" au magasin d'images containerd.
  • Vous pouvez créer et utiliser un builder personnalisé.

Le magasin d'images "classique" de Docker Engine ne prend pas en charge les images multi-plateformes. Le passage au magasin d'images containerd garantit que votre Docker Engine peut pousser, tirer et créer des images multi-plateformes.

La création d'un builder personnalisé qui utilise un pilote avec prise en charge multi-plateforme, tel que le pilote docker-container, vous permettra de créer des images multi-plateformes sans passer à un autre magasin d'images. Cependant, vous ne pourrez toujours pas charger les images multi-plateformes que vous créez dans votre magasin d'images Docker Engine. Mais vous pouvez les pousser directement vers un registre de conteneurs avec docker build --push.

Les étapes pour activer le magasin d'images containerd dépendent si vous utilisez Docker Desktop ou Docker Engine de manière autonome :

Pour créer un builder personnalisé, utilisez la commande docker buildx create pour créer un builder qui utilise le pilote docker-container.

$ docker buildx create \
  --name container-builder \
  --driver docker-container \
  --bootstrap --use
Note

Les builds avec le pilote docker-container ne sont pas automatiquement chargés dans votre magasin d'images Docker Engine. Pour plus d'informations, consultez Pilotes de build.

Si vous utilisez Docker Engine de manière autonome et que vous devez créer des images multi-plateformes à l'aide de l'émulation, vous devez également installer QEMU, voir Installer QEMU manuellement.

Créer des images multi-plateformes

Lors du déclenchement d'un build, utilisez l'indicateur --platform pour définir les plateformes cibles pour la sortie du build, telles que linux/amd64 et linux/arm64 :

$ docker buildx build --platform linux/amd64,linux/arm64 .

Stratégies

Vous pouvez créer des images multi-plateformes en utilisant trois stratégies différentes, en fonction de votre cas d'utilisation :

  1. En utilisant l'émulation, via QEMU
  2. Utiliser un builder avec plusieurs nœuds natifs
  3. Utiliser la compilation croisée avec des builds multi-étapes

QEMU

La création d'images multi-plateformes sous émulation avec QEMU est le moyen le plus simple de démarrer si votre builder le prend déjà en charge. L'utilisation de l'émulation ne nécessite aucune modification de votre Dockerfile, et BuildKit détecte automatiquement les architectures disponibles pour l'émulation.

Note

L'émulation avec QEMU peut être beaucoup plus lente que les builds natifs, en particulier pour les tâches gourmandes en calcul comme la compilation et la compression ou la décompression.

Utilisez plusieurs nœuds natifs ou la compilation croisée à la place, si possible.

Docker Desktop prend en charge l'exécution et la création d'images multi-plateformes sous émulation par défaut. Aucune configuration n'est nécessaire car le builder utilise le QEMU fourni dans la VM Docker Desktop.

Installer QEMU manuellement

Si vous utilisez un builder en dehors de Docker Desktop, par exemple si vous utilisez Docker Engine sur Linux, ou un builder distant personnalisé, vous devez installer QEMU et enregistrer les types d'exécutables sur le système d'exploitation hôte. Les prérequis pour l'installation de QEMU sont :

  • Version du noyau Linux 4.8 ou ultérieure
  • Version de binfmt-support 2.1.7 ou ultérieure
  • Les binaires QEMU doivent être compilés statiquement et enregistrés avec l'indicateur fix_binary

Utilisez l'image tonistiigi/binfmt pour installer QEMU et enregistrer les types d'exécutables sur l'hôte avec une seule commande :

$ docker run --privileged --rm tonistiigi/binfmt --install all

Cela installe les binaires QEMU et les enregistre auprès de binfmt_misc, permettant à QEMU d'exécuter des formats de fichiers non natifs pour l'émulation.

Une fois QEMU installé et les types d'exécutables enregistrés sur le système d'exploitation hôte, ils fonctionnent de manière transparente à l'intérieur des conteneurs. Vous pouvez vérifier votre enregistrement en vérifiant si F fait partie des indicateurs dans /proc/sys/fs/binfmt_misc/qemu-*.

Plusieurs nœuds natifs

L'utilisation de plusieurs nœuds natifs offre une meilleure prise en charge des cas plus compliqués que QEMU ne peut pas gérer, et offre également de meilleures performances.

Vous pouvez ajouter des nœuds supplémentaires à un builder à l'aide de l'indicateur --append.

La commande suivante crée un builder multi-nœuds à partir de contextes Docker nommés node-amd64 et node-arm64. Cet exemple suppose que vous avez déjà ajouté ces contextes.

$ docker buildx create --use --name mybuild node-amd64
mybuild
$ docker buildx create --append --name mybuild node-arm64
$ docker buildx build --platform linux/amd64,linux/arm64 .

Bien que cette approche présente des avantages par rapport à l'émulation, la gestion des builders multi-nœuds introduit une certaine surcharge de configuration et de gestion des clusters de builders. Alternativement, vous pouvez utiliser Docker Build Cloud, un service qui fournit des builders multi-nœuds gérés sur l'infrastructure de Docker. Avec Docker Build Cloud, vous obtenez des builders multi-plateformes ARM et X86 natifs sans le fardeau de les maintenir. L'utilisation de builders cloud offre également des avantages supplémentaires, tels que