Neuigkeiten von trion.
Immer gut informiert.

Docker Multi-Arch-Image

Docker

Docker-Images sind plattformabhängig: Während früher Docker ausschließlich unter Linux auf x86 Plattformen ein Thema war, kamen mit der ARM-Architektur und Windows-Containern zusätzliche Varianten hinzu. Die einzige Option, das jeweils richtige Image für die Plattform auszuwählen, war dann, mit Image Tags zu arbeiten, sofern von einem Projekt überhaupt mehrere Architekturen unterstützt wurden und nicht ein ganz anderes Repository genutzt werden musste. Tags sind eindimensional und es gibt ggf. weitere Image-Varianten zu berücksichtigen. Darum hat jedes Projekt eine eigene Namenskonvention erstellt, beispielsweise gibt es dann foo/mariadb:amd64, foo/mariadb:arm, foo/mariadb:alpine-amd64 und foo/mariadb:alpine-arm. Damit werden die zu verwendenen Image-Namen plattformabhängig und können nicht übergreifend verwendet werden, z.B. in Kubernetes-Deploymentmanifests.

Das Problem wurde erkannt und Docker hat in mehreren Schritten den "Multi-Architecture-Support" implementiert.

Kernstück ist dabei die Bereitstellung zusätzlicher Metainformationen zu einem Image in Form eines sogenannten Manifest. Das Manifest führt die plattformspezifischen Varianten des Image auf, sodass stets automatisch das richtige Image für eine Plattform ausgewählt werden kann. Man kann sich ein Multi-Arch-Image daher als ein virtuelles Image vorstellen, das es in der Form gar nicht direkt gibt.

Zu beachten ist, dass die Implementierung des jeweiligen Images durchaus sehr unterschiedlich sein kann. Beispielsweise sind unter Windows andere Werkzeuge und Verfahren zu finden als bei Linux. Semantisch darf ein Nutzer erwarten, dass die Images sich im Betrieb gleichartig verhalten.

Seit Ende 2017 werden entprechende Images auf Dockerhub bereitgestellt und können auch verwendet werden, um darauf aufbauend eigene Multi-Arch Images zu erzeugen. Ab Docker Version 18.02 ist der Umgang mit Manifesten mit dem Docker-Kommandozeilenwerkzeug (CLI) möglich, sodass die früher benötigten externen Werkzeuge entfallen können.

Docker Multi-Arch-Images erzeugen

Am Beispiel eines "Hello World"-Images für Windows und Linux wird das Vorgehen illustriert, um Docker-Images für mehrere Plattformen zu implementieren. Das Image gibt "Hello World" auf die Konsole aus.

Das Windows-Image verwendet als CMD einen echo Aufruf, um damit "Hello World" auszugeben und nutzt als Base-Image das nanoserver Docker-Image von Microsoft. Damit ist eine native Ausführung als Windows-Docker-Container möglich.

Windows Hello-World-Image
FROM microsoft/nanoserver:latest
CMD echo "Hello World from Windows"

Das Linux-Image verwendet ein schlankes Alpine-Linux-Basisimage und verwendet ebenfalls echo als CMD, um die Ausgabe "Hello World" zu erzielen.

Linux Hello-World-Image
FROM alpine:latest
CMD echo "Hello World from Linux"

Beide Images können nun gebaut, getaggt und gepusht werden. Die Ausgabe des jeweiligen Schritts wird am Linux-Image exemplarisch gezeigt.

Build des Linux-Docker-Image
$ docker build -t trion/hello-world:linux .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM alpine:latest
 ---> 11cd0b38bc3c
Step 2/2 : CMD echo "Hello World from Linux"
 ---> Running in 5da460015061
Removing intermediate container 5da460015061
 ---> ea5bf96e8c5e
Successfully built ea5bf96e8c5e
Successfully tagged trion/hello-world:linux

Die gebauten Images werden nun jeweils in die Registry gepusht.

Push des Linux-Docker-Image in Registry
$ docker push trion/hello-world:linux
The push refers to repository [trion/hello-world:linux]
73046094a9b8: Pushed
linux: digest: sha256:4455e74891682f001d567c37f822ea6d76b724f86f593afa169cd6062e3b390b size: 528

Ab jetzt sind die Images bereits unter dem plattformspezifischen Tag nutzbar, der jeweilige Konsument müsste jedoch den vollständigen Namen mit dem plattformspezifischen Tag angeben. Damit Docker nun automatisch das richtige Image auswählt, wird ein Manifest benötigt.

Docker Multi-Arch Manifest

In neueren Docker-Versionen kann das Manifest direkt mit dem Docker-Kommandozeilenwerkzeug erzeugt werden. Für ältere Versionen gibt es unterschiedliche separate Werkzeuge, mit denen sich ebenfalls die Manifest-Dateien erzeugen lassen.

Um den Manifest-Support von Docker zu nutzen, muss jedoch eine Einstellung in der Docker Clientkonfiguration vorgenommen werden, da sonst eine Fehlermeldung die Nutzung aller Manifest-Operationen blockiert.

Docker Manifest-Kommando liefert Warnung
$ docker manifest
docker manifest is only supported when experimental cli features are enabled

In der Datei ~/.docker/config.json werden die in der Fehlermeldung referenzierten experimentellen Features aktiviert. Ein Beispiel für die Konfiguration ist im Folgenden zu sehen.

Konfigurationsdatei ~/.docker/config.json mit experimentellen Features
{
   "experimental": "enabled"
}

Nachdem die experimentellen Features im Docker CLI aktiviert sind, können die Manifest-Operationen verweden werden und damit auch ein Manifest erzeugt werden. Ein Manifest ist hierarchisch aufgebaut und startet mit dem virtuellen Image, das von den konkreten Plattformen abstrahiert.

Im Beispiel sieht die Struktur daher wie folgt aus:

  • trion/hello-world:latest

    • trion/hello-world:linux

    • trion/hello-world:windows

Analog zu dieser Struktur wird nun das Manifest durch docker manifest create erzeugt:

Erzeugung des Docker-Image Manifests mit Images für Linux und Windows
$ docker manifest create
    trion/hello-world:latest
    trion/hello-world:linux
    trion/hello-world:windows
Created manifest list trion/hello-world:latest

Anschließend kann das Manifest in die Registry gepusht werden.

Push des Manifest in die Docker Registry
$ docker manifest push trion/hello-world:latest
sha256:39a26c2f97deb5242aa8bbc7b13454e7c57ee1a29b3feec71111c407ec56892c

Ab jetzt kann Docker automatisch das richtige Image für die jeweilige Plattform auflösen.

Note

Wer mit einer lokalen Registry arbeitet oder aus anderen Gründen keine TLS Absicherung der Registry konfiguriert hat, muss bei allen docker manifest-Anweisungen den Schalter --insecure mit angeben. Andernfalls kommt lediglich die Fehlermeldung no such manifest: localhost:5000/…​.

Es gilt zu beachten, dass das Manifest für alle Tags erzeugt und gepusht werden muss, für die die Multi-Arch-Funktionalität zur Verfügung stehen soll.

In diesem Artikel wird beschrieben, wie auf Docker Hub automatisiert Multi-Arch Docker Images gebaut werden können: DockerHub Multi-Arch Image als Autobuild.




Zu den Themen Kubernetes, Docker und Cloud Architektur bieten wir sowohl Beratung, Entwicklungsunterstützung als auch passende Schulungen an:

Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.

Feedback oder Fragen zu einem Artikel - per Twitter @triondevelop oder E-Mail freuen wir uns auf eine Kontaktaufnahme!

Los geht's!

Bitte teilen Sie uns mit, wie wir Sie am besten erreichen können.