Inhaltsbasiertes Tagging im werf-Sammler: Warum und wie funktioniert es?



werf ist unser Open-Source-Dienstprogramm GitOps CLI zum Erstellen und Bereitstellen von Anwendungen für Kubernetes. In Version v1.1 gibt es eine neue Funktion für den Bildersammler: das Markieren von Bildern nach Inhalten oder das inhaltsbasierte Markieren . Bisher bestand das typische Tagging-Schema in werf darin, Docker-Bilder mit einem Git-Tag, einem Git-Zweig oder einem Git-Commit zu markieren. Alle diese Schemata weisen jedoch Mängel auf, die durch die neue Markierungsstrategie vollständig behoben werden. Details über sie und warum sie so gut ist - unter dem Schnitt.

Rollback einer Reihe von Microservices aus einem Git-Repository


Oft gibt es eine Situation, in der die Anwendung in viele mehr oder weniger unabhängige Dienste unterteilt ist. Die Freigabe dieser Dienste kann unabhängig voneinander erfolgen: Ein oder mehrere Dienste können gleichzeitig freigegeben werden, während der Rest ohne Änderungen weiterarbeiten sollte. Unter dem Gesichtspunkt der Codespeicherung und des Projektmanagements ist es jedoch bequemer, solche Anwendungsdienste in einem einzigen Repository zu speichern.

Es gibt Situationen, in denen Dienste wirklich unabhängig und nicht mit einer Anwendung verbunden sind. In diesem Fall befinden sie sich in separaten Projekten, und ihre Freigabe erfolgt über separate CI / CD-Prozesse in jedem der Projekte.

In der Realität teilen Entwickler eine einzelne Anwendung jedoch häufig in mehrere Microservices auf, aber ein separates Repository und Projekt für jeden ... ist ein offensichtlicher Overkill. Auf diese Situation wird weiter eingegangen: Mehrere solcher Microservices befinden sich in einem einzigen Projekt-Repository, und Releases erfolgen über einen einzigen Prozess in CI / CD.

Git-Tag und Git-Tagging


Angenommen, die am häufigsten verwendete Tagging-Strategie wird verwendet - Tag-or-Branch . Bei Git-Zweigen werden Bilder mit dem Namen des Zweigs versehen. Für jeweils einen Zweig gibt es jeweils nur ein veröffentlichtes Bild, das für diesen Zweig benannt ist. Bei Git-Tags werden Bilder entsprechend dem Tag-Namen markiert.

Beim Erstellen eines neuen Git-Tags - beispielsweise wenn eine neue Version veröffentlicht wird - wird für alle Projektabbilder in der Docker-Registrierung ein neues Docker-Tag erstellt:

  • myregistry.org/myproject/frontend:v1.1.10
  • myregistry.org/myproject/myservice1:v1.1.10
  • myregistry.org/myproject/myservice2:v1.1.10
  • myregistry.org/myproject/myservice3:v1.1.10
  • myregistry.org/myproject/myservice4:v1.1.10
  • myregistry.org/myproject/myservice5:v1.1.10
  • myregistry.org/myproject/database:v1.1.10

Diese neuen Bildnamen gelangen über die Helmmuster in die Kubernetes-Konfiguration. Wenn die Bereitstellung gestartet wird, werf deployaktualisiert das Team das Feld imagein den Kubernetes-Ressourcenmanifesten und startet die entsprechenden Ressourcen aufgrund des geänderten Image-Namens neu.

Problem : In einem Fall, in dem die vorherige tatsächliche Vykata (Git-Tag) den Inhalt des Bildes nicht geändert hat, sondern nur das Docker-Tag, das einmal auftritt , starten Sie diese Anwendung neu und sind dementsprechend einige einfach möglich. Obwohl es keinen wirklichen Grund gab, diesen Neustart durchzuführen.

Infolgedessen müssen Sie mit dem aktuellen Tagging-Schema mehrere separate Git-Repositorys umzäunen, und es tritt das Problem auf, den Rollout dieser verschiedenen Repositorys zu organisieren. Im Allgemeinen ist ein solches Schema überlastet und komplex. Es ist besser, viele Dienste in einem einzigen Repository zu kombinieren und solche Docker-Tags zu erstellen, damit keine unnötigen Neustarts stattfinden.

Git Commit Tagging


Werf hat auch eine Tagging-Strategie für Git-Commits.

Git-Commit ist die Kennung des Inhalts des Git-Repositorys und hängt vom Verlauf der Dateibearbeitungen im Git-Repository ab. Daher erscheint es logisch, es zum Kennzeichnen von Bildern in der Docker-Registrierung zu verwenden.

Das Taggen durch Git-Commit hat jedoch die gleichen Nachteile wie durch Git-Zweige oder Git-Tags:

  • , , Docker- .
  • merge-, , Docker- .
  • , Git, , Docker- .

Git-


Es gibt ein weiteres Problem im Zusammenhang mit der Tagging-Strategie für Git-Zweige.

Das Markieren mit dem Namen eines Zweigs funktioniert, solange die Commits dieses Zweigs nacheinander in chronologischer Reihenfolge erfasst werden.

Wenn der Benutzer im aktuellen Schema mit dem Wiederherstellen des alten Commits beginnt, das einem Zweig zugeordnet ist, löscht werf das Image mithilfe des entsprechenden Docker-Tags mit der neu zusammengestellten Version des Images für das alte Commit. Bereitstellungen, die dieses Tag verwenden, können ab sofort während des Neustarts des Pods eine andere Version des Images abrufen. Dadurch verliert unsere Anwendung die Verbindung zum CI-System und ist nicht mehr synchron.

Bei aufeinanderfolgenden Push'ahs in einem Zweig mit einem kleinen Zeitintervall zwischen ihnen kann das alte Commit später als das neuere erfasst werden: Die alte Version des Bildes löscht das neue mithilfe des Tags des Git-Zweigs. Solche Probleme können durch das CI / CD-System gelöst werden (in GitLab CI wird beispielsweise die Pipeline des letzteren für eine Reihe von Commits gestartet). Dies wird jedoch nicht von allen Systemen unterstützt, und es sollte einen zuverlässigeren Weg geben, um ein derart grundlegendes Problem zu verhindern.

Was ist inhaltsbasiertes Tagging?


Was genau ist inhaltsbasiertes Tagging? Markieren von Bildern nach Inhalten.

Zum Erstellen von Docker-Tags werden keine Git-Grundelemente (Git-Zweig, Git-Tag ...) verwendet, sondern eine Prüfsumme in Verbindung mit:

  • . - . , ;
  • Git. , Git- werf, -.

Die sogenannte Signatur der Bildstufen fungiert als solches Identifikations-Tag .

Jedes Bild besteht aus einer Reihe von Schritten: from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patchusw. Jede Stufe hat eine Kennung, die ihren Inhalt widerspiegelt - die Signaturstufe (Stufensignatur) .

Das endgültige Bild, das aus diesen Stufen besteht, ist mit der sogenannten Signatur des Satzes dieser Stufen - Stufensignatur - gekennzeichnet, die für alle Stufen des Bildes verallgemeinert wird.

Jedes Bild aus der Konfiguration hat werf.yamlim Allgemeinen eine eigene Signatur und dementsprechend das Docker-Tag.

Die Bühnenunterschrift löst all diese Probleme:

  • Beständig gegen leere Git-Commits.
  • Beständig gegen Git-Commits, die Dateien ändern, die für das Image nicht relevant sind.
  • Führt nicht zu einem Problem beim Schleifen der aktuellen Version des Image, wenn Assemblys für alte Git-Commits des Zweigs neu gestartet werden.

Dies ist jetzt die empfohlene Tagging-Strategie und wird standardmäßig in werf für alle CI-Systeme verwendet.

So aktivieren und verwenden Sie in werf


Für das Team erschien die entsprechende Option werf publish: --tag-by-stages-signature=true|false

Im CI-System wird die Tagging-Strategie durch den Befehl festgelegt werf ci-env. Zuvor wurde ein Parameter dafür definiert werf ci-env --tagging-strategy=tag-or-branch. Wenn Sie werf ci-env --tagging-strategy=stages-signaturediese Option angeben oder nicht, verwendet werf standardmäßig eine Tagging-Strategie stages-signature. Der Befehl setzt werf ci-envautomatisch die erforderlichen Flags für den Befehl werf build-and-publish(oder werf publish), daher müssen keine zusätzlichen Optionen für diese Befehle angegeben werden.

Zum Beispiel der Befehl:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-by-stages-signature

... kann folgende Bilder erstellen:

  • registry.hello.com/web/core/system/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
  • registry.hello.com/web/core/system/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6

Hier 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386dist die Signatur der Bildstufen backendund f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6die Signatur der Bildstufen frontend.

Bei Verwendung von Sonderfunktionen werf_container_imageund werf_container_envin Helm-Vorlagen muss nichts geändert werden: Diese Funktionen generieren automatisch die richtigen Bildnamen.

Beispielkonfiguration in einem CI-System:

type multiwerf && source <(multiwerf use 1.1 beta)
type werf && source <(werf ci-env gitlab)
werf build-and-publish|deploy

Weitere Konfigurationsinformationen finden Sie in der Dokumentation:


Gesamt


  • Neue Option werf publish --tag-by-stages-signature=true|false.
  • Der neue Wert der Option werf ci-env --tagging-strategy=stages-signature|tag-or-branch(falls nicht angegeben, wird er standardmäßig verwendet stages-signature).
  • Wenn die Tagging - Optionen für Git Commits , bevor sie verwendet wurden ( WERF_TAG_GIT_COMMIToder die Option werf publish --tag-git-commit COMMIT), dann sicher auf die zu wechseln Phasen-Signatur - Tagging - Strategie .
  • Neue Projekte sollten besser sofort auf ein neues Tagging-Schema umgestellt werden.
  • Bei der Übersetzung in werf 1.1 ist es ratsam, alte Projekte auf das neue Tagging-Schema umzustellen, das alte Tag-or-Branch wird jedoch weiterhin unterstützt.

Inhaltsbasiertes Tagging löst alle im Artikel hervorgehobenen Probleme:

  • Stabilität des Docker-Tag-Namens für leere Git-Commits.
  • Die Stabilität des Namens des Docker-Tags für Git schreibt fest, dass Dateien geändert werden, die für das Image nicht relevant sind.
  • Führt nicht zu einem Problem beim Schleifen der aktuellen Version des Bildes beim Neustart von Assemblys für alte Git-Commits für Git-Zweige.

Benutze es! Und vergessen Sie nicht, bei unserem GitHub vorbeizuschauen , um ein Problem zu erstellen oder ein vorhandenes zu finden, ein Plus zu setzen, eine PR zu erstellen oder einfach die Entwicklung des Projekts zu verfolgen.

PS


Lesen Sie auch in unserem Blog:


All Articles