Images Docker Multi-Architecture : Guide Complet ARM64 et AMD64
Introduction
Avez-vous déjà construit une image Docker sur votre MacBook et déployé en production, pour rencontrer une erreur cryptique comme no matching manifest for linux/amd64 ? Vous n'êtes pas seul. Avec la transition d'Apple vers les puces ARM M1 et M2, l'écart entre environnements de développement et de production s'est creusé, créant de nouveaux défis pour la conteneurisation.
Dans ce guide complet, nous explorerons pourquoi les images Docker ne sont pas toujours portables entre différentes architectures CPU, comment Docker Desktop gère cette complexité, et surtout, comment construire des images multi-architecture universelles qui fonctionnent de manière transparente sur toutes les plateformes.
Comprendre les Architectures CPU : ARM64 vs AMD64
Les ordinateurs modernes utilisent différentes architectures de jeu d'instructions (ISA) qui définissent comment le CPU traite les instructions. Les deux architectures dominantes dans le paysage informatique actuel sont :
AMD64 (x86_64)
- Utilisé par : Processeurs Intel et AMD
- Courant dans : Ordinateurs portables traditionnels, ordinateurs de bureau, et la plupart des serveurs cloud (AWS EC2, Google Cloud, Azure)
- Caractéristiques : Architecture CISC (Complex Instruction Set Computing)
- Également connu sous : x86_64, x64
ARM64 (aarch64)
- Utilisé par : Apple Silicon (M1/M2/M3), AWS Graviton, Raspberry Pi 4+, nombreux appareils mobiles
- Courant dans : MacBooks modernes, tablettes, smartphones, edge computing
- Caractéristiques : Architecture RISC (Reduced Instruction Set Computing)
- Également connu sous : aarch64, ARMv8
Pourquoi est-ce important ? Le code compilé pour une architecture ne peut pas s'exécuter nativement sur une autre. Une image Docker construite pour ARM64 ne fonctionnera pas sur un processeur AMD64 sans émulation, et vice versa.
Comment Docker Fonctionne sur macOS et Windows
Une idée fausse courante est que Docker s'exécute nativement sur macOS et Windows. En réalité, Docker est fondamentalement une technologie Linux qui nécessite un noyau Linux pour fonctionner.
La Couche de Machine Virtuelle
Docker Desktop crée une machine virtuelle Linux légère en arrière-plan :
| Système d'Exploitation Hôte | Technologie de Virtualisation | Architecture de la VM Linux |
|---|---|---|
| macOS (Intel) | HyperKit / Virtualization.framework | AMD64 (x86_64) |
| macOS (Apple Silicon) | Virtualization.framework | ARM64 (aarch64) |
| Windows (Intel/AMD) | WSL 2 (Windows Subsystem for Linux) | AMD64 (x86_64) |
| Windows (ARM) | WSL 2 | ARM64 (aarch64) |
Insight critique : L'architecture de la VM Linux correspond à l'architecture de votre CPU hôte. Cela signifie : - Mac M1/M2 → VM Linux ARM64 → Les images Docker sont construites pour ARM64 - Mac Intel → VM Linux AMD64 → Les images Docker sont construites pour AMD64
Même si c'est "juste Linux" en dessous, la différence d'architecture compte.
Le Problème du Déploiement en Production
Considérez ce scénario courant :
- Développement : Vous construisez et testez votre application sur un MacBook M1 (ARM64)
- Construction du conteneur :
docker build -t myapp:latest .crée une image ARM64 - Push vers le registre :
docker push myapp:latesttélécharge l'image ARM64 sur Docker Hub - Déploiement en production : Votre serveur cloud (AWS EC2 t3.medium sur Intel Xeon) tente de pull l'image
Résultat :
Error response from daemon: no matching manifest for linux/amd64 in the manifest list entries
Votre serveur de production ne peut pas exécuter une image ARM64 car il utilise un processeur AMD64.
Impact Réel : Quand les Architectures Entrent en Collision
Étude de Cas : L'Échec de Déploiement Silencieux
Une équipe de développement a rencontré des échecs de déploiement intermittents dans leur pipeline CI/CD. Certains développeurs pouvaient pousser des images qui se déployaient avec succès, tandis que d'autres images échouaient systématiquement en production.
Cause racine : La moitié de l'équipe utilisait des MacBooks Intel (AMD64), tandis que l'autre moitié avait migré vers des MacBooks M1 (ARM64). Les images construites sur les machines M1 n'étaient pas compatibles avec leur infrastructure de production AMD64.
Coût : 12 heures d'interruption de service, développeurs frustrés, et retard dans la sortie de fonctionnalités.
La Solution : Images Multi-Architecture
Les images multi-architecture (multi-arch) résolvent ce problème en empaquetant plusieurs variantes d'image sous un seul tag. Lorsque vous faites docker pull d'une image multi-arch, Docker sélectionne automatiquement la variante correspondant à votre plateforme.
Comment Fonctionnent les Images Multi-Arch
Les images multi-arch utilisent une liste de manifestes (également appelée "fat manifest") qui référence plusieurs images spécifiques à la plateforme :
myapp:latest (liste de manifestes)
├── linux/amd64 → sha256:abc123...
└── linux/arm64 → sha256:def456...
Quand un utilisateur exécute docker pull myapp:latest :
1. Docker vérifie la liste de manifestes
2. Identifie l'architecture hôte (amd64 ou arm64)
3. Pull uniquement la variante d'image correspondante
Résultat : Un seul tag d'image fonctionne partout.
Construire des Images Multi-Architecture avec Docker Buildx
Docker Buildx est le système de build étendu de Docker qui supporte les builds multi-plateforme. Il est inclus avec Docker Desktop par défaut.
Étape 1 : Créer une Instance de Builder
Buildx utilise des instances de builder pour effectuer des builds cross-platform :
# Créer une nouvelle instance de builder
docker buildx create --name multiplatform --driver docker-container --use
# Vérifier le builder
docker buildx inspect --bootstrap
Ce que cela fait : Crée un environnement de build conteneurisé capable de construire pour plusieurs architectures simultanément.
Étape 2 : Construire pour Plusieurs Plateformes
La magie opère avec le flag --platform :
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag username/myapp:latest \
--push \
.
Explication des flags :
- --platform linux/amd64,linux/arm64 : Construire pour les deux architectures
- --tag username/myapp:latest : Nom et tag de l'image
- --push : Push vers le registre (requis pour les images multi-arch)
- . : Contexte de build (répertoire courant)
Pourquoi --push est-il requis ?
Les images multi-architecture créent une liste de manifestes qui référence plusieurs couches d'image à travers différentes architectures. Ce manifeste ne peut pas être stocké dans votre daemon Docker local—il doit être publié dans un registre de conteneurs.
Si vous devez tester localement sans push, vous pouvez construire pour votre plateforme actuelle uniquement :
docker buildx build --platform linux/arm64 --load -t myapp:latest .
Le flag --load charge l'image dans votre daemon Docker local, mais ne fonctionne que pour les builds mono-plateforme.
Étape 3 : Vérifier l'Image Multi-Arch
Inspectez le manifeste pour confirmer que les deux architectures sont présentes :
docker manifest inspect username/myapp:latest
Sortie attendue (abrégée) :
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:1234567890abcdef...",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:fedcba0987654321...",
"platform": {
"architecture": "arm64",
"os": "linux"
}
}
]
}
✅ Les deux manifestes amd64 et arm64 sont présents.
Avancé : Optimisation du Build Cross-Platform
Construire pour plusieurs architectures peut prendre du temps. Voici des stratégies d'optimisation :
1. Utiliser le Cache de Build
Buildx supporte le cache distribué avec le cache GitHub Actions ou le cache de registre :
docker buildx build \
--platform linux/amd64,linux/arm64 \
--cache-from type=registry,ref=username/myapp:buildcache \
--cache-to type=registry,ref=username/myapp:buildcache,mode=max \
--tag username/myapp:latest \
--push \
.
2. Builds Multi-Étapes
Optimisez le Dockerfile avec des builds multi-étapes pour réduire la taille de l'image :
# Étape de build
FROM --platform=$BUILDPLATFORM golang:1.21 AS builder
ARG TARGETARCH
WORKDIR /build
COPY . .
RUN GOARCH=$TARGETARCH go build -o app
# Étape d'exécution
FROM alpine:latest
COPY --from=builder /build/app /usr/local/bin/app
CMD ["app"]
Variables de plateforme :
- $BUILDPLATFORM : Architecture de l'hôte de build
- $TARGETPLATFORM : Architecture ciblée pour le build
- $TARGETARCH : Architecture cible (amd64, arm64, etc.)
3. Dépendances Conditionnelles
Certaines dépendances sont spécifiques à l'architecture :
FROM node:18
# Installer des outils spécifiques à l'architecture
RUN if [ "$(uname -m)" = "x86_64" ]; then \
apt-get install -y specific-amd64-package; \
else \
apt-get install -y specific-arm64-package; \
fi
Résolution des Problèmes Courants
Problème 1 : Échec d'Authentification
ERROR: failed to push: requested access to the resource is denied
Solution : Connectez-vous à votre registre de conteneurs :
docker login
# Entrez nom d'utilisateur et mot de passe quand demandé
Problème 2 : Émulation de Plateforme Lente
Construire pour une architecture non native utilise l'émulation QEMU, qui peut être significativement plus lente.
Solution : Utilisez des builders natifs ou des services de build cloud (GitHub Actions avec plusieurs runners, Docker Hub Automated Builds).
Problème 3 : Impossible de Charger l'Image Multi-Arch Localement
ERROR: multi-platform images cannot be loaded directly
Solution : Soit :
- Push vers le registre et pull en retour : docker push puis docker pull
- Construire pour la plateforme locale uniquement : docker buildx build --platform linux/arm64 --load -t myapp .
Problème 4 : Taille de l'Image Doublée
Q : "Est-ce que multi-arch double la taille de mon image ?"
R : - Dans le registre : Oui, les deux variantes d'image sont stockées - Lors du pull : Non, seule l'architecture correspondante est téléchargée - Impact coût : Minimal pour la plupart des cas d'usage, mais considérez les limites de stockage du registre privé
Bonnes Pratiques pour la Production
1. Toujours Construire en Multi-Arch dans CI/CD
Assurez-vous que votre pipeline CI/CD construit pour toutes les plateformes cibles :
# Exemple GitHub Actions
- name: Build and push multi-arch image
uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
push: true
tags: username/myapp:latest
2. Utiliser des Images de Base Spécifiques
Certaines images de base ne supportent pas toutes les architectures. Vérifiez le support :
docker manifest inspect alpine:latest | jq '.manifests[].platform'
3. Taguer avec Suffixe d'Architecture pour les Tests
Pendant le développement, taguez les builds spécifiques à l'architecture :
docker buildx build --platform linux/amd64 -t myapp:latest-amd64 --push .
docker buildx build --platform linux/arm64 -t myapp:latest-arm64 --push .
4. Documenter les Exigences d'Architecture
Dans votre README :
## Architectures Supportées
Cette image supporte les architectures suivantes :
- `linux/amd64` - Intel/AMD 64-bit
- `linux/arm64` - ARM 64-bit (Apple Silicon, AWS Graviton)
Considérations de Performance
Performance Native vs Émulée
| Scénario | Temps de Build | Performance d'Exécution |
|---|---|---|
| Build natif (ARM64 sur M1) | Baseline | 100% |
| Build natif (AMD64 sur Intel) | Baseline | 100% |
| Build émulé (AMD64 sur M1) | 3-10x plus lent | N/A (s'exécute en production) |
| Exécution émulée (ARM64 sur serveur AMD64) | N/A | 5-20x plus lent |
À retenir : Déployez toujours des images correspondant à votre architecture de production. L'émulation est acceptable pour le développement local, inacceptable pour la production.
L'Avenir : ARM dans le Cloud
L'adoption d'ARM s'accélère dans l'infrastructure cloud :
- AWS Graviton3 : 25% de meilleures performances prix-performance que x86
- Google Tau T2A : VMs basées sur ARM dans Google Cloud
- Azure Cobalt : Instances cloud basées sur ARM de Microsoft
- Hetzner : Serveurs dédiés basés sur ARM
Le support multi-architecture n'est pas juste un correctif de compatibilité—c'est la préparation de votre infrastructure pour un avenir dominé par ARM.
Conclusion
La promesse de Docker "build once, run anywhere" nécessite un effort conscient dans un monde multi-architecture. En adoptant Docker Buildx et les images multi-architecture, vous assurez que vos applications fonctionnent de manière transparente sur les ordinateurs portables de développement, les runners CI/CD, et les serveurs de production—quelle que soit l'architecture CPU sous-jacente.
Points clés à retenir : 1. L'architecture de Docker Desktop correspond à votre CPU, pas seulement "Linux" 2. Les images multi-arch utilisent des listes de manifestes pour supporter plusieurs plateformes 3. Docker Buildx rend les builds cross-platform simples 4. Construisez toujours pour votre architecture de production, pas seulement votre machine de développement 5. L'adoption d'ARM est en croissance—le support multi-arch prépare vos conteneurs pour l'avenir
Ressources Additionnelles
- Documentation Docker Buildx
- Spécification des images multi-plateforme
- Référence de la commande Docker manifest
- Émulation utilisateur QEMU
Des questions sur les images Docker multi-architecture ? Ce guide vous a été utile ? Partagez votre expérience dans les commentaires ci-dessous.