Sie können jetzt Docker-Images in werf mit einer regulären Docker-Datei erstellen

Besser spät als nie. Oder wie wir fast einen schweren Fehler gemacht hätten, weil wir keine Unterstützung für reguläre Dockerfiles zum Erstellen von Anwendungsimages hatten.

Sie können jetzt Docker-Images in werf mit einer regulären Docker-Datei erstellen

Wir reden darüber Hof — GitOps-Dienstprogramm, das sich in jedes CI/CD-System integrieren lässt und die Verwaltung des gesamten Anwendungslebenszyklus ermöglicht und Folgendes ermöglicht:

  • Bilder sammeln und veröffentlichen,
  • Anwendungen in Kubernetes bereitstellen,
  • Löschen Sie nicht verwendete Bilder mithilfe spezieller Richtlinien.


Die Philosophie des Projekts besteht darin, Low-Level-Tools in einem einzigen einheitlichen System zusammenzufassen, das DevOps-Ingenieuren die Kontrolle über Anwendungen gibt. Wenn möglich, sollten vorhandene Dienstprogramme (wie Helm und Docker) verwendet werden. Sollte es für ein Problem keine Lösung geben, können wir alles dafür Notwendige schaffen und unterstützen.

Hintergrund: Ihr eigener Bildersammler

Dies ist mit dem Image-Collector in werf passiert: Die übliche Docker-Datei reichte uns nicht aus. Wenn man einen kurzen Blick auf die Geschichte des Projekts wirft, tauchte dieses Problem bereits in den ersten Versionen von werf auf (damals noch). bekannt als Dapp).

Als wir ein Tool zum Erstellen von Anwendungen in Docker-Images erstellten, stellten wir schnell fest, dass Dockerfile für einige ganz bestimmte Aufgaben nicht für uns geeignet war:

  1. Die Notwendigkeit, typische kleine Webanwendungen nach dem folgenden Standardschema zu erstellen:
    • systemweite Anwendungsabhängigkeiten installieren,
    • ein Paket von Anwendungsabhängigkeitsbibliotheken installieren,
    • Vermögen sammeln,
    • und vor allem: Aktualisieren Sie den Code im Bild schnell und effizient.
  2. Wenn Änderungen an Projektdateien vorgenommen werden, muss der Builder schnell eine neue Ebene erstellen, indem er einen Patch auf die geänderten Dateien anwendet.
  3. Wenn sich bestimmte Dateien geändert haben, ist es notwendig, die entsprechende abhängige Stufe neu zu erstellen.

Heute hat unser Sammler viele andere Möglichkeiten, aber das waren die ursprünglichen Wünsche und Triebe.

Im Allgemeinen haben wir uns ohne langes Nachdenken mit der von uns verwendeten Programmiersprache bewaffnet (siehe unten) und machen uns auf den Weg zur Umsetzung eigenes DSL! Entsprechend der Zielsetzung sollte der Montageprozess in Etappen beschrieben und die Abhängigkeiten dieser Etappen von Dateien ermittelt werden. Und es ergänzt eigener Sammler, was das DSL zum Endziel machte – ein zusammengesetztes Bild. Zuerst war das DSL in Ruby, aber so Übergang zu Golang – Die Konfiguration unseres Collectors wurde in einer YAML-Datei beschrieben.

Sie können jetzt Docker-Images in werf mit einer regulären Docker-Datei erstellen
Alte Konfiguration für Dapp in Ruby

Sie können jetzt Docker-Images in werf mit einer regulären Docker-Datei erstellen
Aktuelle Konfiguration für werf auf YAML

Auch der Mechanismus des Kollektors veränderte sich im Laufe der Zeit. Zuerst haben wir einfach spontan eine temporäre Docker-Datei aus unserer Konfiguration generiert und dann begonnen, Assembly-Anweisungen in temporären Containern auszuführen und festzuschreiben.

NB: Im Moment hat sich unser Collector, der mit einer eigenen Konfiguration (in YAML) arbeitet und Stapel-Collector genannt wird, bereits zu einem recht mächtigen Tool entwickelt. Seine ausführliche Beschreibung verdient separate Artikel, und grundlegende Details finden Sie in Dokumentation.

Bewusstsein für das Problem

Aber wir erkannten nicht sofort, dass wir einen Fehler gemacht hatten: Wir hatten die Fähigkeit nicht hinzugefügt Erstellen Sie Images über eine Standard-Docker-Datei und integrieren Sie sie in dieselbe End-to-End-Anwendungsverwaltungsinfrastruktur (d. h. Bilder sammeln, bereitstellen und bereinigen). Wie könnte es möglich sein, ein Tool für die Bereitstellung in Kubernetes zu erstellen und keine Dockerfile-Unterstützung zu implementieren, d. h. Standardmethode zur Beschreibung von Bildern für die meisten Projekte?

Anstatt diese Frage zu beantworten, bieten wir eine Lösung an. Was ist, wenn Sie bereits über eine Docker-Datei (oder eine Reihe von Docker-Dateien) verfügen und werf verwenden möchten?

NB: Übrigens, warum solltest du überhaupt werf verwenden wollen? Die Hauptmerkmale lassen sich wie folgt zusammenfassen:

  • vollständiger Anwendungsverwaltungszyklus einschließlich Bildbereinigung;
  • die Möglichkeit, die Zusammenstellung mehrerer Bilder gleichzeitig über eine einzige Konfiguration zu verwalten;
  • Verbesserter Bereitstellungsprozess für Helm-kompatible Diagramme.

Eine vollständigere Liste finden Sie unter Seite des Projekts.

Wenn wir also früher angeboten hätten, die Docker-Datei in unserer Konfiguration neu zu schreiben, würden wir jetzt gerne sagen: „Lass werf deine Docker-Dateien erstellen!“

Wie man verwendet?

Die vollständige Implementierung dieser Funktion erschien in der Veröffentlichung werf v1.0.3-beta.1. Das allgemeine Prinzip ist einfach: Der Benutzer gibt den Pfad zu einer vorhandenen Docker-Datei in der werf-Konfiguration an und führt dann den Befehl aus werf build... und das war’s – werf wird das Bild zusammenstellen. Schauen wir uns ein abstraktes Beispiel an.

Lassen Sie uns den nächsten ankündigen Dockerfile im Projektstamm:

FROM ubuntu:18.04
RUN echo Building ...

Und wir werden es bekannt geben werf.yamlder dies nutzt Dockerfile:

configVersion: 1
project: dockerfile-example
---
image: ~
dockerfile: ./Dockerfile

Alle! Links laufen werf build:

Sie können jetzt Docker-Images in werf mit einer regulären Docker-Datei erstellen

Darüber hinaus können Sie Folgendes deklarieren werf.yaml um mehrere Images aus verschiedenen Docker-Dateien gleichzeitig zu erstellen:

configVersion: 1
project: dockerfile-example
---
image: backend
dockerfile: ./dockerfiles/Dockerfile-backend
---
image: frontend
dockerfile: ./dockerfiles/Dockerfile-frontend

Schließlich unterstützt es auch die Übergabe zusätzlicher Build-Parameter, wie z --build-arg и --add-host - über die werf-Konfiguration. Eine vollständige Beschreibung der Dockerfile-Image-Konfiguration finden Sie unter Dokumentationsseite.

Wie funktioniert es?

Während des Build-Prozesses funktioniert der Standard-Cache lokaler Layer in Docker. Wichtig ist jedoch, dass es auch so ist integriert die Dockerfile-Konfiguration in seine Infrastruktur. Was bedeutet das?

  1. Jedes aus einer Docker-Datei erstellte Image besteht aus einer sogenannten Stufe dockerfile (Sie können mehr darüber lesen, welche Phasen es in werf gibt hier).
  2. Für die Bühne dockerfile werf berechnet eine Signatur, die vom Inhalt der Dockerfile-Konfiguration abhängt. Wenn sich die Dockerfile-Konfiguration ändert, ändert sich auch die Stage-Signatur dockerfile und werf initiiert einen Neuaufbau dieser Phase mit einer neuen Dockerfile-Konfiguration. Wenn sich die Signatur nicht ändert, holt werf das Bild aus dem Cache (Weitere Einzelheiten zur Verwendung von Signaturen in werf wurden in beschrieben dieser Bericht).
  3. Anschließend können die gesammelten Bilder mit dem Befehl veröffentlicht werden werf publish (oder werf build-and-publish) und verwenden Sie es für die Bereitstellung auf Kubernetes. Veröffentlichte Bilder in der Docker-Registrierung werden mit Standard-Werf-Bereinigungstools bereinigt, d. h. Alte Bilder (älter als N Tage), Bilder, die mit nicht vorhandenen Git-Zweigen verknüpft sind, und andere Richtlinien werden automatisch bereinigt.

Weitere Details zu den hier beschriebenen Punkten finden Sie in der Dokumentation:

Hinweise und Vorsichtsmaßnahmen

1. Externe URL wird in ADD nicht unterstützt

Derzeit wird die Verwendung einer externen URL in einer Direktive nicht unterstützt ADD. Werf initiiert keine Neuerstellung, wenn sich die Ressource unter der angegebenen URL ändert. Wir planen, diese Funktion bald hinzuzufügen.

2. Sie können dem Bild keine .git-Datei hinzufügen

Im Allgemeinen wird ein Verzeichnis hinzugefügt .git im Bild - eine bösartige schlechte Praxis und hier ist der Grund:

  1. wenn .git Bleibt im endgültigen Bild, verstößt dies gegen die Grundsätze 12-Faktor-App: Da das endgültige Bild mit einem einzelnen Commit verknüpft sein muss, sollte dies nicht möglich sein git checkout willkürliches Commit.
  2. .git erhöht die Größe des Bildes (das Repository kann groß sein, da ihm einmal große Dateien hinzugefügt und dann gelöscht wurden). Die Größe eines Arbeitsbaums, der nur einem bestimmten Commit zugeordnet ist, hängt nicht vom Verlauf der Vorgänge in Git ab. In diesem Fall erfolgt die Hinzufügung und anschließende Entfernung .git aus dem endgültigen Image funktioniert nicht: Das Image erhält trotzdem eine zusätzliche Ebene – so funktioniert Docker.
  3. Docker kann einen unnötigen Neuaufbau initiieren, selbst wenn derselbe Commit erstellt wird, jedoch aus unterschiedlichen Arbeitsbäumen. GitLab erstellt beispielsweise separate geklonte Verzeichnisse in /home/gitlab-runner/builds/HASH/[0-N]/yourproject wenn die parallele Montage aktiviert ist. Die zusätzliche Neuzusammenstellung ist auf die Tatsache zurückzuführen, dass das Verzeichnis .git ist in verschiedenen geklonten Versionen desselben Repositorys unterschiedlich, selbst wenn derselbe Commit erstellt wird.

Der letzte Punkt hat auch Konsequenzen bei der Verwendung von werf. Werf erfordert, dass der erstellte Cache vorhanden ist, wenn einige Befehle ausgeführt werden (z. B. werf deploy). Wenn diese Befehle ausgeführt werden, berechnet werf Bühnensignaturen für die in angegebenen Bilder werf.yaml, und sie müssen sich im Assembly-Cache befinden – andernfalls kann der Befehl nicht weiterarbeiten. Ob die Bühnensignatur vom Inhalt abhängt .git, dann erhalten wir einen Cache, der gegenüber Änderungen in irrelevanten Dateien instabil ist, und werf wird sich ein solches Versehen nicht verzeihen können (weitere Einzelheiten finden Sie unter Dokumentation).

Im Allgemeinen Hinzufügen nur bestimmter notwendiger Dateien durch die Anleitung ADD erhöht in jedem Fall die Effizienz und Zuverlässigkeit des Geschriebenen Dockerfile, und verbessert auch die Stabilität des dafür gesammelten Caches Dockerfile, zu irrelevanten Änderungen in Git.

Ergebnis

Unser anfänglicher Weg, unseren eigenen Builder für spezifische Anforderungen zu schreiben, war hart, ehrlich und unkompliziert: Anstatt Krücken auf der Standard-Docker-Datei zu verwenden, haben wir unsere Lösung mit benutzerdefinierter Syntax geschrieben. Und das hatte seine Vorteile: Der Stapelsammler meistert seine Aufgabe perfekt.

Beim Schreiben unseres eigenen Builders haben wir jedoch die Unterstützung für vorhandene Docker-Dateien aus den Augen verloren. Dieser Fehler wurde nun behoben und wir planen, in Zukunft zusammen mit unserem benutzerdefinierten Stapel-Builder Dockerfile-Unterstützung für verteilte Assembly und für Assembly mit Kubernetes zu entwickeln (d. h. Assembly auf Runnern innerhalb von Kubernetes, wie es in Kaniko erfolgt).

Wenn Sie also plötzlich ein paar Docker-Dateien herumliegen haben ... Versuchen Hof!

PS Liste der Dokumentation zum Thema

Lesen Sie auch in unserem Blog: „werf – unser Tool für CI/CD in Kubernetes (Übersicht und Videobericht)".

Source: habr.com

Kommentar hinzufügen