Minimale Container-Images verzichten auf Komponenten wie Shells oder Paketmanager, die zur Laufzeit normalerweise nicht gebraucht werden. Sie sind auch als "distroless" oder "chiseled" Images bekannt. Weil weniger Komponenten weniger Schwachstellen bedeuten, reduzieren diese Images die Angriffsfläche und erhöhen dadurch die Sicherheit.
Schlüsselfertige Images für ein Basis-Linux sowie die Sprachen PHP, Python, Java, C# und Node.js hat Teil 2 der Artikelserie vorgestellt. Diese vorkonfektionierten Images passen jedoch nicht immer zu den eigenen Anforderungen und es kann notwendig sein, eigene zu erstellen. Dieser Artikel zeigt, wie Softwareentwicklerinnen und -entwickler eigene minimale Images basierend auf den Angeboten Ubuntu Chiseled, Chainguard/WolfiOS und Azure Linux bauen (siehe die folgende Tabelle).
| Drei Anbieter minimaler Images im Vergleich | |||
| Bewertungskriterium | Ubuntu Chiseled | WolfiOS / Chainguard | Azure Linux |
| Verfügbare Pakete | ~500 | ~3000 | ~3000 |
| Qualität der Dokumentation / Schwierigkeit der Nutzung | ➕➕ | ➕➕➕ | ➕ |
| Integrationsgeschwindigkeit von Paket-Versionsupdates (Upstream) | Langsam | Schnell | Mittel |
| Reproduzierbare Image-Builds / Pinnen der zu installierenden Paket-Versionen | ❌ | ✅ | ❌ |
| Kommerzieller Support | ✅ | ✅ | ❌ |
Canonical verwendet die Bezeichnung "Chiseled" für minimale, Ubuntu-basierte Images. Ein Blogbeitrag stellt das Chisel-CLI von Ubuntu vor. Chisel ist ein Build-Tool, das Entwickler mit der gewünschten Ubuntu-Version (beispielsweise "24.04") und einer Liste von "Slices" aufrufen, die Chisel zu einem neuen Root-Filesystem zusammenbaut. Dieses Filesystem kopiert man anschließend in ein leeres scratch-Image, wie der Ablaufplan in Abbildung 1 verdeutlicht:
Bau eines Chiseled-Image via Multi-Stage Dockerfile (Abb.1)
Das Ubuntu-Team hat einige (jedoch nicht alle) der offiziellen Ubuntu-Pakete in mehrere Slices aufgeteilt und diese auf GitHub veröffentlicht. Falls Slices für ein gewünschtes Paket fehlen, sollte man auf andere im Artikel erwähnte Ansätze wechseln. Denn bestehende GitHub Issues zeigen, dass reine Feature-Requests lange oder gänzlich ignoriert werden, und der Zeitinvest für die Einarbeitung für eigene Pull Requests (PRs) hoch ist.
Aufbauend auf Chisel stellt Canonical zudem das Rockcraft-Tool zur Verfügung, das auf einer höheren Abstraktionsebene arbeitet.
Bevor Entwickler tiefer in den Build-Prozess von Ubuntu Chiseled-Images einsteigen, sollten sie sich der folgenden zwei Einschränkungen bewusst sein:
Es lassen sich nur Pakete installieren, für die das Ubuntu-Team bereits Slice-Definitionen erstellt hat. Die Slices unterscheiden sich je nach Ubuntu-Version (beispielsweise hat 22.04 andere Slices als 24.04). Das ist insbesondere beim Erstellen eines Image für einen Interpreter einer Programmiersprache wie Java, Node.js oder Python relevant. Dabei stehen lediglich die in der jeweiligen Distro-Version mitgelieferten Interpreter-Versionen zur Verfügung. So gibt es bei Python im neuesten Ubuntu-LTS-Release (24.04) nur Python 3.12.3. Neuere 3.12-Versionen (oder 3.13) fehlen. Für Python 3.12.3 hat Ubuntu jedoch zumindest die seit dieser Version 3.12.3 bekannt gewordenen Schwachstellen behoben (sogenannte "Backports").Es ist nicht möglich, die Versionen der Pakete oder Slices zu pinnen! Das Chisel CLI installiert immer die aktuelle Version des Pakets, die zum Zeitpunkt der Chisel-Ausführung im offiziellen Ubuntu-Repo verfügbar ist.Der einfachste Weg, ein Chiseled-Image zu erstellen, ist ein Docker Multi-Stage Build. Wie man für ein Python-Image (mit Python 3.12.3) auf Basis von Ubuntu 24.04 vorgeht, erklärt das offizielle Chisel-Tutorial.
Da Schwachstellenscanner wie Trivy oder Grype die Pakete im frisch gebauten Image leider nicht korrekt identifizieren können, sind weitere Anpassungen am Dockerfile nötig. Der Grund dafür, warum die Scanner relevante Schwachstellen übersehen, geht aus einem GitHub Issue hervor: Ubuntu hat entschieden, für Chisel-Images ein eigenes proprietäres Paket-Manifest-Format zu erfinden, das Scanner wie Trivy bisher nicht verstehen.
Ubuntu versucht daher mit Scanner-Anbietern zusammenzuarbeiten, wie beispielsweise eine GitHub-Diskussion zu Trivy zeigt. Bis es so weit ist, können Entwickler einen Workaround nutzen: Das chisel-wrapper-Skript generiert Metadaten im Standard-Debian-Paket-Format, das Scanner wie Trivy verstehen. Dazu sind im Dockerfile des Multi-Stage-Builds (vom offiziellen Tutorial) folgende Änderungen vorzunehmen:
# Einfügen der folgenden 3 RUN-Zeilen, irgendwo vor dem "chisel cut" Befehl des Tutorials: # "file" wird vom chisel-wrapper script benötigt RUN apt-get update && apt-get install -y git file RUN git clone --depth 1 -b main https://github.com/canonical/rocks-toolbox /rocks-toolbox && mv /rocks-toolbox/chisel-wrapper /usr/local/bin/ && rm -rf /rocks-toolbox RUN mkdir -p /staging-rootfs/var/lib/dpkg # Ersetzen der RUN-Zeile, die den "chisel cut" Befehl ausführt, mit folgender Zeile: RUN chisel-wrapper --generate-dpkg-status /staging-rootfs/var/lib/dpkg/status -- --release "ubuntu-$UBUNTU_RELEASE" --root /staging-rootfs <space-separated-chisel-list>Ein vollständiges Beispiel für Python 3 liegt im GitHub-Repository des Autors öffentlich parat. Es veranschaulicht den Build einer Flask-basierten Demo-Anwendung. Zudem demonstriert es, wie man ein Problem löst, das dadurch entsteht, dass der Python-Interpreter im Chiseled Basis-Image an einem anderen Pfad liegt als beim python-Image, das in der Build-Stage verwendet wird. Ein weiteres GitHub-Gist des Autors zeigt, wie man ein Chiseled Java JRE-Image erstellt und darin die Springboot-Petclinic-Anwendung ausführt.
Ein weiterer Ansatz, Ubuntu Chiseled Images zu erstellen, ist das Rockcraft-CLI, das auf einer höheren Abstraktionsebene als Chisel arbeitet.
Rockcraft greift intern auf Chisel zurück, um das Root-Filesystem zu erstellen. Über eine von Rockcraft eingelesene YAML-Datei legt man deklarativ die folgenden Aspekte fest:
Die Ubuntu-Version, deren Slices verwendet werden sollenDie Liste der zu installierenden SlicesDie CPU-Architekturen, für die Rockcraft das Image erstellen soll (für Multiplattform-Builds)Welcher Nicht-Root-Linux-User erstellt und automatisch beim Image-Start verwendet werden sollWelche Linux-Services zum Image-Start mit dem Pebble Service-Manager gestartet werden sollen (Pebble ist eine Alternative zu systemd)Mit Rockcraft erstellte, vorgefertigte Images lassen sich mit dem Suchbegriff "chisel" in der Canonical GitHub-Organisation finden, beispielsweise:
Die größten Nachteile von Rockcraft sind:
Rockcraft macht den Build-Prozess durch zusätzliches Tooling komplexer (verglichen mit einem direkten Chisel-CLI-Aufruf).Es erzwingt die Nutzung des Pebble Service Managers, der als ENTRYPOINT für das Image gesetzt wird. Dies ist unnötig, denn im Gegensatz zur Vorgehensweise bei virtuellen Maschinen (VMs) sind Service-Manager bei Containern nicht üblich. In diesen Umgebungen ist es gewollt, dass der gesamte Container beendet wird, wenn das im ENTRYPOINT festgelegte Programm abstürzt. Denn Container Runtimes wie Docker Compose oder Kubernetes überwachen den Container-Status und starten ihn dann neu. Zudem finden Schwachstellenscanner wie Trivy im Pebble-Binary häufig CVEs. Diese stellen zwar meistens keine Bedrohung dar, verursachen allerdings unnötigen Diagnose-Aufwand.Die von Rockcraft generierten Images verwenden den chisel-wrapper-Trick für Schwachstellenscanner nicht. Folglich können diese die im Image installierten Komponenten nicht korrekt identifizieren und keine Schwachstellen melden.Um sichere, minimale Images zu erstellen, ist es daher empfehlenswert, direkt das Chisel-CLI statt Rockcraft zu verwenden. Dennoch lohnt sich ein Blick in die stage-packages-Einträge der rockcraft.yaml-Dateien in den oben gelisteten Repositorys (beispielsweise für Python), um eine Idee dafür zu bekommen, welche Slices im eigenen Image sinnvoll sind.
Dieser Link ist leider nicht mehr gültig. Links zu verschenkten Artikeln werden ungültig, wenn diese älter als 7 Tage sind oder zu oft aufgerufen wurden. Sie benötigen ein heise+ Paket, um diesen Artikel zu lesen. Jetzt eine Woche unverbindlich testen – ohne Verpflichtung! Wochenpass bestellenSie haben heise+ bereits abonniert? Hier anmelden.
Oder benötigen Sie mehr Informationen zum heise+ Abo

Kommentare