1 Punkte von GN⁺ 5 시간 전 | Noch keine Kommentare. | Auf WhatsApp teilen
  • Container-Registries wirken auf den ersten Blick einfach, aber um Probleme wie falsche Tags, Plattform-Inkompatibilitäten, fehlende Layer oder fehlgeschlagene tatsächliche Löschungen zu debuggen, muss man ihre interne Funktionsweise unbedingt verstehen
  • Der Kern einer Registry ist ein content-addressable Blob-Store, in dem alle Layer, Konfigurationsdateien und Artefakte unter ihrer Digest-Adresse gespeichert werden
  • Ein Image-Push läuft in der Reihenfolge Blob-Upload, dann Bündelung per Manifest ab, während Pull den umgekehrten Ablauf nutzt: erst das Manifest abrufen, dann die Blobs nacheinander herunterladen
  • Image-Löschung bedeutet nicht automatisch vollständiges Entfernen: Nur ein Untagging reicht nicht aus, man muss erst prüfen, welche Layer von anderen Manifesten gemeinsam genutzt werden, und dann die Blobs direkt löschen
  • Multi-Plattform-Images werden umgesetzt, indem bei unveränderten bestehenden API-Endpunkten nur eine zusätzliche indirekte Schicht in Form eines image index (manifest list) eingeführt wird

Überblick über die Registry-API

  • Die meisten modernen Container-Registries implementieren die OCI Distribution Specification, die ein API-Protokoll zur Standardisierung der Verteilung von Inhalten definiert
  • Die Registry-API ist tatsächlich kompakt und leicht verständlich; sie lässt sich sogar allein mit curl direkt bedienen

Blob-Upload und -Download

  • Eine Registry ist im Wesentlichen ein content-addressable Blob-Store: Dateien werden lokal gehasht und dann mit ihrem Digest als Adresse hochgeladen
  • Die einfachste Upload-Methode ist Monolithic PUT mit einer zweistufigen Struktur: zuerst die Sitzung per POST initialisieren, dann den Blob per PUT senden
    • Für große Dateien ist die Chunk-Upload-Methode per POST + PATCH + PUT effizienter, für kleine Blobs reicht Monolithic PUT jedoch aus
  • Bei erfolgreichem Upload wird eine Antwort HTTP/2 201 Created zusammen mit einem Location-Header zurückgegeben, der auf den neuen Blob verweist
  • Für den Download reicht die Kenntnis des Digests; mit GET /v2/<repo>/blobs/<digest> kann er direkt ausgeführt werden

Image-Push

  • Ablauf eines Image-Pushs: (1) Upload jedes rootfs-Layer-Blobs → (2) Upload des image configuration-Blobs → (3) Push der Manifest-Datei, die alle Digests in einem JSON-Dokument zusammenfasst
  • Das Manifest wird über den Endpunkt PUT /v2/<repo>/manifests/<tag> hochgeladen; in diesem Moment wird auch das Tag erzeugt
  • Echte Clients wie docker push laden Blobs parallel hoch, zum Verständnis des Prinzips ist aber auch eine sequenzielle Verarbeitung möglich
  • Beispiel für die Struktur eines Image-Verzeichnisses: config.json, layer-1.tar.gz, layer-2.tar.gz, manifest.json

Tag-Liste abrufen

  • Über den Endpunkt GET /v2/<repo>/tags/list lässt sich die vollständige Tag-Liste eines bestimmten Repositorys abrufen
  • Diese Funktion wird in der docker-CLI nicht offengelegt und ist nur über Tools wie curl, crane oder regctl zugänglich
    • crane und regctl kapseln denselben Endpunkt über den Befehl ls

Image-Pull

  • Der Pull-Ablauf ist die Umkehrung von Push: (1) Manifest abrufen per GET /v2/<repo>/manifests/<tag> → (2) alle Blobs herunterladen anhand der im Manifest angegebenen Digests
  • Moderne Manifeste dienen neben rootfs-Layern und Image-Konfiguration auch als universeller Speicher, der beliebige Artefakte als Blobs referenziert, darunter Helm-Charts, SBOMs, Provenance Attestations und LLM-Gewichte

Image-Löschung

  • Das Löschen eines Images ist nicht trivial; das Entfernen eines Tags (Untagging) löscht das Manifest selbst nicht
  • Vollständiger Löschablauf:
    • (1) Tag entfernen mit DELETE /v2/<repo>/manifests/<tag>
    • (2) Manifest per Digest abrufen und alle referenzierten Blobs prüfen
    • (3) nur Blobs löschen, die nicht von anderen Manifesten gemeinsam genutzt werden
    • (4) Manifest-Blob löschen mit DELETE /v2/<repo>/blobs/<manifest-digest>
  • Da eine Registry ein content-addressable Speichersystem ist, können mehrere Images denselben rootfs-Layer gemeinsam nutzen; beim Löschen wirkt sich das auf alle Images aus, die auf diesen Layer verweisen
  • Alternativ kann man alle Tags entfernen und sich dann auf die Garbage-Collection-Einstellung der Registry verlassen, allerdings ist diese in öffentlichen Registries nicht immer aktiviert

Multi-Plattform-Images

  • Multi-Plattform-Images werden ohne Änderungen an der Struktur der Registry-API umgesetzt — die bestehende API wird unverändert weiterverwendet, ohne neue oder angepasste Endpunkte
  • Vorgehensweise:
    • Jede einzelne Plattformvariante (amd64, arm64 usw.) wird zunächst zusammen mit einem eigenen Manifest digest-basiert gepusht
    • Anschließend wird ein übergeordnetes Manifest namens image index (manifest list) zusammen mit dem Tag gepusht
  • Bei GET /v2/<repo>/manifests/<tag> wird entweder ein Single-Plattform-Manifest oder ein image index zurückgegeben; der Aufrufer muss beides über den Content-Type des zurückgegebenen Dokuments unterscheiden
  • Im Ergebnis ergänzt die Multi-Plattform-Unterstützung die bestehende Struktur nur um eine indirekte Schicht und einen zusätzlichen Schritt zum Hoch- und Herunterladen des Index-Dokuments

Schutz der Registry-API

  • Die OCI Distribution Spec definiert das Authentifizierungsverfahren nicht strikt, die meisten realen Registries verwenden jedoch HTTP Basic Authentication
  • Um zu verhindern, dass Zugangsdaten im Klartext übertragen werden, muss der Betrieb zwingend über HTTPS erfolgen

Noch keine Kommentare.

Noch keine Kommentare.