Container-Image-Formate im Detail
Agata Krajewska
18. November 2020
0 Min. LesezeitIn den letzten Jahren sind Container nach der Veröffentlichung von Docker immer mehr zum Standard für die Bereitstellung von Software geworden.
Wir beobachten eine zunehmende Zahl containerbasierter Lösungen. Innovationen in diesem Bereich sind natürlich willkommen, zugleich müssen jedoch bestimmte Standards für Format und Laufzeit festgelegt werden.
Durch das rasante Wachstum des Docker-Projekts wurden Docker-Images für viele Zwecke zum Standard. Gleichzeitig besteht großes Interesse an einer einheitlichen, offenen Container-Spezifikation, die:
nicht an übergeordnete Konstrukte wie einen bestimmten Client oder Orchestrierungs-Stack gebunden ist,
nicht eng mit einem bestimmten kommerziellen Anbieter oder Projekt verbunden ist,
auf einer Vielzahl von Betriebssystemen, Hardware, CPU-Architekturen, Public Clouds usw. portierbar ist.
OCI (Open Container Initiative) ist ein Projekt der Linux Foundation zur Entwicklung offener Standards für die Virtualisierung auf Betriebssystemebene, insbesondere für Linux-Container.
Verschiedene Open-Source-Build-Tools unterstützen inzwischen das OCI-Image-Format, darunter:
BuildKit: eine optimierte Neuentwicklung der Docker-Build-Engine
Podman: eine alternative Implementierung des Docker-Kommandozeilen-Tools
Buildah: eine Kommandozeilen-Alternative zum Schreiben von Dockerfiles
Snyk unterstützt alle gängigen Container-Image-Formate. Dadurch können wir Integrationen mit einer Vielzahl von Tools aus dem gesamten Ökosystem anbieten. In diesem Blogbeitrag sehen wir uns einige davon an und zeigen, wie Snyk mit ihnen funktioniert.
Docker-Archiv
Sehen wir uns zunächst das Docker-Archivformat an. Es gehört zur veralteten v1 der Docker-Image-Spezifikation. Die vollständige Spezifikation finden Sie hier. Wenn Sie docker save ausführen, gibt der Docker-Client standardmäßig dieses Format aus, das aus Gründen der Abwärtskompatibilität mit anderen Tools verwendet wird. Container-Registries verwenden zum Speichern der Images ein neueres Format.
Wenn Sie Docker lokal ausführen und die Snyk CLI oder eine unserer Container-Integrationen verwenden, nutzen wir Ihre lokale Docker-Instanz, um das Image abzurufen, im Dateisystem zu speichern und die Analyse zu starten.
Sehen wir uns an, wie dieses Archiv aussieht und welche Inhalte für Snyk interessant sind.
In diesem Beitrag verwende ich das Image ubuntu:bionic. Speichern wir zunächst das Archiv in Ihrem lokalen Dateisystem:
docker save --output ubuntu-docker.tar ubuntu:bionic
Die Distribution bionic umfasst drei Image-Layer, die wir uns genauer ansehen.
Nachdem wir das tar-Archiv entpackt haben, können wir den Inhalt untersuchen:
Sehen wir uns manifest.json an:
Die Datei verweist auf die Container-Konfiguration, in der wir nützliche Informationen wie Architektur, Konfiguration und Root-Dateisystem-Layer finden. Besonders interessant für Snyk ist die Eigenschaft Layers: Sie verweist auf die eigentlichen Image-Layer, also Verzeichnisse im Archiv. Wechseln wir in eines dieser Verzeichnisse, sehen wir, was es enthält:
Sehen wir uns den Inhalt genauer an und entpacken das layer.tar-Archiv:
Wie Sie oben sehen, enthält das layer.tar-Archiv lediglich die Änderungen am Dateisystem des Image-Layers sowie – je nach Image-Inhalt – alle Abhängigkeiten und sonstigen Binärdateien. Nachdem wir den Inhalt extrahiert und analysiert haben,
können wir Ihnen die Liste der anfälligen Pfade anzeigen.
Testen wir nun das gespeicherte Docker-Archiv-Image mit snyk test. Ein lokales Archiv können wir testen, indem wir das Präfix docker-archive: angeben:
snyk container test docker-archive:ubuntu-docker.tar oder scannen Sie das Image aus Ihrem lokalen Docker-Repository:
snyk container test ubuntu:bionic
Beide Befehle liefern genau dieselbe Ausgabe:
OCI-Image
In den letzten Monaten haben wir das Scannen von OCI-Archiven als Funktion in die Snyk CLI aufgenommen.
Sehen wir uns nun die Spezifikation und den Inhalt des Archivs an. Auch in diesem Abschnitt verwende ich ubuntu:bionic.
Wenn Sie selbst ein OCI-Archiv-Tarball untersuchen möchten, können Sie folgenden Befehl ausführen:
skopeo copy --override-os linux docker://ubuntu:bionic oci-archive:ubuntu.tar
Zum Speichern des Images verwende ich hier Skopeo. Das cli-Dienstprogramm erleichtert verschiedene Vorgänge mit Images erheblich.
Um ein ubuntu-Image im OCI-Format zu speichern, müssen wir lediglich das Präfix oci-archive: für die tar-Ausgabe angeben.
Beachten Sie, dass ich außerdem das Flag --override-os verwende: Ich arbeite mit macOS, und offizielle Docker Hub ubuntu images sind nur für Linux verfügbar. Auf Images mit mehreren Architekturen gehen wir weiter unten ebenfalls ein.
Sobald wir das tar-Archiv entpackt haben, können wir den Inhalt untersuchen:
Im Stammverzeichnis befindet sich eine interessante Datei namens index.json. Sehen wir uns ihren Inhalt an:
Dies ist unser optionales Manifest der höheren Ebene. Es verweist auf bestimmte Image-Manifeste und enthält Informationen zu einer Gruppe von Images, die verschiedene Architekturen und Betriebssysteme umfassen können. Weitere Informationen finden Sie in der vollständigen Spezifikation.
Sehen wir uns nun das spezifische Image-Manifest an, auf das index.json im Verzeichnis blobs/sha256 verweist:
Hier finden wir interessante Inhalte wie die Container-Konfiguration mit vielen nützlichen Informationen zur Image-Architektur, den Basis-Image-Layern, der Konfiguration usw. Außerdem erhalten wir Informationen zu den Image-Layern, die in unserem Image ubuntu:bionic vorhanden sind.
Wie unten zu sehen ist, entspricht der Inhalt des ersten Layers genau dem des Docker-Archivs oben.
Sie können Ihr lokales OCI-Archiv mit folgendem Befehl scannen:
snyk container test oci-archive:ubuntu.tar
Verschiedene Plattformen und Architekturen
Bei der Untersuchung der Docker-Archiv- und OCI-Image-Manifeste ist uns aufgefallen, dass beide Informationen zur Architektur enthalten. Werfen wir noch einmal einen Blick auf den Inhalt des Container-Konfigurationsmanifests im Verzeichnis ubuntu-docker, in dem wir unser docker archive gespeichert haben:
Neben anderen Angaben sehen wir Architektur und Betriebssystem. In meinem Fall sind das amd64 und linux. Was aber, wenn unser Image auf arm64 basiert oder wir mit der Plattform windows arbeiten?
Zum Glück unterstützt Snyk auch andere Plattformen. Dazu übergeben Sie der Snyk CLI das Flag -—platform.
Wir haben uns das Archivformat von docker save angesehen. Werfen wir nun einen Blick auf das Format, in dem Images in Docker Hub gespeichert werden: das v2-Schema, das unter der Oberfläche sehr interessant ist. Diese zweite Version des v2-Schemas wurde für zwei Hauptziele entwickelt. Laut der Docker-Dokumentation:
Erstens sollen Multi-Architektur-Images ermöglicht werden: Ein „Fat Manifest“ verweist dazu auf Image-Manifeste für plattformspezifische Versionen eines Images. Zweitens soll die Docker-Engine auf inhaltsadressierbare Images umgestellt werden. Dazu wird ein Image-Modell unterstützt, bei dem sich die Konfiguration eines Images hashen lässt, um eine ID für das Image zu erzeugen.
Mit unserem lokalen Docker können wir zunächst das „Fat Manifest“ des gewünschten Images untersuchen und prüfen, welche Plattformvarianten verfügbar sind. Wie oben erklärt, kann ein einzelnes Repository mehrere Images für unterschiedliche Architekturen enthalten.
docker manifest inspect ubuntu:bionic
Das Ergebnis ist ein Array mit Manifesten:
Nachdem wir nun wissen, dass das Image ubuntu für verschiedene Plattformen verfügbar ist, sehen wir uns an, wie Sie ein ubuntu-Image für die Plattformarchitektur arm64 scannen.
Achten Sie darauf, dass experimentelle Funktionen in Docker auf Ihrem Host aktiviert sind. Dann können Sie folgenden Befehl ausführen:
snyk container test --platform=linux/arm64 ubuntu:bionic
Sehen wir uns die Ausgabe an:
Wir sehen alle entdeckten anfälligen Pfade sowie Angaben zur „Platform“ in der Scan-Ausgabe.
In diesem Blogbeitrag haben wir die beiden wichtigsten Container-Image-Formate von Docker und OCI untersucht und gezeigt, wie Snyk mit beiden Formaten und sogar mit mehreren Architekturen funktioniert.
Zum Abschluss finden Sie hier weitere Informationen zu bewährten Sicherheitspraktiken für die Erstellung optimaler Docker-Images für Node.js- und Java-Anwendungen:
10 Best Practices für Docker-Sicherheit — beschreibt Sicherheitspraktiken, die Sie beim Erstellen und Abrufen von Docker-Basis-Images beachten sollten, und führt außerdem in Docker Content Trust ein.
Entwickeln Sie mit Java? Diese Ressource ist für Sie interessant: Docker für Java-Entwickler: 5 Dinge, die Sie für Ihre Sicherheit wissen müssen
10 Best Practices für das Containerisieren von Node.js-Webanwendungen mit Docker – Wenn Sie mit Node.js entwickeln, wird Ihnen diese Schritt-für-Schritt-Anleitung gefallen. Sie zeigt, wie Sie sichere und leistungsfähige Docker-Basis-Images für Ihre Node.js-Anwendungen erstellen.
All diese Funktionen stehen Ihnen in Snyk kostenlos zur Verfügung — registrieren Sie sich für ein Konto.
Starten Sie mit Capture the Flag
Erfahren Sie in unserem virtuellen On-Demand-Workshop für Einsteiger, wie Sie Capture-the-Flag-Herausforderungen lösen.



