
Das Thema des Monorepositories wurde bereits mehrfach diskutiert und führt in der Regel zu lebhaften Kontroversen. Bei der Erstellung eines Open Source-Tools, das darauf abzielt, die Prozesse des Code-Bauens von Anwendungen aus Git in Docker-Images (und deren anschließender Bereitstellung in Kubernetes) zu verbessern, machen wir uns selten Gedanken darüber, welche Wahl die bessere ist. Es ist uns wichtig, alles Notwendige für Unterstützer unterschiedlicher Meinungen bereitzustellen (sofern es natürlich dem gesunden Menschenverstand nicht widerspricht).
Die kürzlich eingeführte Unterstützung für Mono-Repo in werf ist ein gutes Beispiel. Aber lassen Sie uns zunächst klären, wie diese Unterstützung überhaupt mit der Nutzung von werf zusammenhängt und welche Rolle das Docker Registry dabei spielt...
Problemstellung
Stellen Sie sich die folgende Situation vor: In einem Unternehmen gibt es viele Entwicklungsteams, die an unabhängigen Projekten arbeiten. Die meisten Anwendungen laufen in Kubernetes und werden daher containerisiert. Für die Speicherung der Container und Images ist ein Registry erforderlich. In diesem Unternehmen wird Docker Hub mit einem einzigen Konto als solches Registry verwendet. COMPANY. Ähnlich wie bei den meisten Systemen zur Speicherung von Quellcode erlaubt Docker Hub keine verschachtelte Hierarchie von Repositories, wie zum Beispiel UNTERNEHMEN/PROJEKT/BILD. In diesem Fall… wie kann man unter dieser Einschränkung nicht monolithische Anwendungen im Registry speichern, ohne für jedes Projekt ein separates Konto zu erstellen?

Möglicherweise ist die beschriebene Situation für einige bekannt, aber lassen Sie uns die Frage der Speicherung von Anwendungen allgemein betrachten, ohne an das oben beschriebene Beispiel und Docker Hub gebunden zu sein.
Lösungswege
Wenn die Anwendung monolithisch, in einem einzigen Image bereitgestellt wird, gibt es keine Fragen, und wir speichern einfach die Images im Container-Registry des Projekts.
Wenn die Anwendung aus mehreren Komponenten besteht, Mikrodiensten, muss ein bestimmter Ansatz gewählt werden. Am Beispiel einer typischen Webanwendung, die aus zwei Images besteht: Frontend und backend — mögliche Optionen sind:
- Images in separaten, verschachtelten Repositories speichern:

- Alles in einem Repository speichern und den Namen des Images im Tag berücksichtigen, zum Beispiel wie folgt:

NB: Eigentlich gibt es auch die Möglichkeit, in verschiedenen Repositories zu speichern, PROJEKT-frontend und PROJEKT-backend, aber dies werden wir aufgrund der Komplexität von Wartung, Organisation und Verteilung von Rechten zwischen den Nutzern nicht betrachten.
Unterstützung in werf
Ursprünglich beschränkte sich werf auf verschachtelte Repositories – glücklicherweise unterstützen die meisten Registries diese Funktionalität. Seit Version , ist die Arbeit mit Registries hinzugefügt worden, in denen Verschachtelung nicht unterstützt wird, und Docker Hub zählt dazu. Ab diesem Zeitpunkt hat der Nutzer die Wahl, wie die Anwendungs-Images gespeichert werden.
Die Implementierung ist im Rahmen der Option --images-repo-mode=multirepo|monorepo standardmäßig multirepo, d.h. Speicherung in verschachtelten Repositories. Sie definiert die Vorlagen, nach denen die Images in der Registry gespeichert werden. Es genügt, den gewünschten Modus bei der Verwendung der Hauptkommandos auszuwählen, während der Rest unverändert bleibt.
Da die meisten Optionen von werf als Umgebungsvariablenfestgelegt werden können, lässt sich der Speicherungsmodus in CI/CD-Systemen in der Regel global für das gesamte Projekt leicht festlegen. Beispielsweise im Fall von GitLab reicht es aus, eine Umgebungsvariable in den Projekteinstellungen hinzuzufügen: Einstellungen -> CI / CD -> Variablen: WERF_IMAGES_REPO_MODE: multirepo|monorepo.
Was die Veröffentlichung von Images und das Deployment von Anwendungen angeht (über diese Prozesse kann in den entsprechenden Artikeln der Dokumentation ausführlich gelesen werden: und ), der Modus bestimmt ausschließlich das Muster, nach dem man mit dem Image arbeiten kann.
Der Teufel steckt im Detail
Der Unterschied und die Hauptherausforderung beim Hinzufügen neuer Speicheroptionen liegen im Bereinigungsprozess der Registry (für die in werf unterstützten Bereinigungsmöglichkeiten siehe ).
Bei der Bereinigung berücksichtigt werf die in den Kubernetes-Clustern verwendeten Images sowie vom Benutzer festgelegte Richtlinien. Die Richtlinien basieren auf der Trennung der Tags in Strategien. Momentan unterstützte Strategien sind:
- 3 Strategien, die mit Git-Primitiven wie Tag, Branch und Commit verbunden sind;
- 1 Strategie für beliebige benutzerdefinierte Tags.
Informationen zur Tag-Strategie werden beim Veröffentlichen des Images in den Labels des Endimages gespeichert. Der Wert selbst ist der sogenannte Metatag — notwendig für die Anwendung eines Teils der Richtlinien. Zum Beispiel macht es Sinn, beim Löschen eines Branches oder Tags aus dem Git-Repository auch die verbundenen unbenutzten Images aus dem Registry zu entfernen, was durch einen Teil unserer Richtlinien abgedeckt wird.
Beim Speichern in einem einzigen Repository (monorepo), kann im Tag des Images zusätzlich zum Metatag auch der Name des Images gespeichert werden: PROJEKT:Frontend-META-TAG. Um sie zu trennen, haben wir keinen spezifischen Trennzeichen verwendet, sondern einfach den erforderlichen Wert im Label des endgültigen Abbilds bei der Veröffentlichung hinzugefügt.
NB: Falls Sie interessiert sind, den gesamten beschriebenen Code von werf zu sehen, könnte der Ausgangspunkt sein .
In diesem Artikel werden wir nicht weiter auf die Problematik und Begründung unseres Ansatzes eingehen: zu Strategien der Tag-Generierung, der Datenspeicherung in Labels und dem Veröffentlichungsprozess insgesamt - all dies wurde ausführlich im aktuellen Bericht von Dmitri Stolyarov behandelt: «».
Zusammenfassend
Das Fehlen von unterstützten Registries ohne Verschachtelung war für uns oder unseren bekannten Nutzern von werf kein Hindernis – schließlich kann man immer ein separates Abbild-Registry erstellen (oder auf das Container Registry in Google Cloud umsteigen). Dennoch schien es logisch, solch eine Einschränkung aufzuheben, damit das Tool für eine breitere DevOps-Community zugänglicher wird. Bei der Umsetzung stießen wir auf die größte Herausforderung: die Überarbeitung des Mechanismus zur Bereinigung des Container-Registries. Jetzt, wo alles bereit ist, erfreut es uns zu wissen, dass es jemandem leichter gefallen ist und wir (als Hauptentwickler des Projekts) keine wesentlichen Schwierigkeiten bei der weiteren Unterstützung dieser Funktion erwarten.
Bleiben Sie bei uns, und bald werden wir über weitere Neuerungen berichten. !
P.S.
Lesen Sie auch in unserem Blog:
- «»;
- «».
Quelle: habr.com


