Besser spĂ€t als nie. Oder wie wir fast einen schwerwiegenden Fehler gemacht hĂ€tten, weil wir keine UnterstĂŒtzung fĂŒr normale Dockerfiles zur Erstellung von Anwendungsbildern hatten.

Es geht um â ein GitOps-Tool, das sich in jede CI/CD-System integrieren lĂ€sst und das gesamte Anwendungslebenszyklusmanagement ermöglicht, einschlieĂlich:
- Erstellung und Veröffentlichung von Bildern,
- Bereitstellung von Anwendungen in Kubernetes,
- Löschung ungenutzter Bilder gemÀà speziellen Richtlinien.
Die Philosophie des Projekts besteht darin, Low-Level-Tools in ein einheitliches System zu integrieren, das DevOps-Ingenieuren die Kontrolle ĂŒber Anwendungen gibt. So weit wie möglich sollen bereits vorhandene Tools (wie Helm und Docker) verwendet werden. Falls jedoch keine Lösung fĂŒr ein bestimmtes Problem existiert, können wir alles Notwendige dafĂŒr erstellen und pflegen.
Hintergrund: unser Bildgenerator
So kam es zu dem Bildgenerator in werf: uns fehlte das vertraute Dockerfile. Wenn wir einen schnellen Blick auf die Geschichte des Projekts werfen, wurde dieses Problem bereits in den ersten Versionen von werf (damals noch ).
Bei der Entwicklung eines Tools zur Erstellung von Anwendungen in Docker-Images haben wir schnell festgestellt, dass ein Dockerfile fĂŒr einige spezifische Aufgaben nicht geeignet ist:
- Die Notwendigkeit, typische kleine Webanwendungen nach einem standardisierten Schema zu erstellen:
- SystemabhÀngigkeiten der Anwendung zu installieren,
- die Bundle-Bibliotheken der Anwendung zu installieren,
- Assets zu sammeln,
- und das Wichtigste â den Code im Image schnell und effizient zu aktualisieren.
- Bei Ănderungen an den Projektdateien sollte der Builder schnell eine neue Schicht erstellen, indem er einen Patch auf die geĂ€nderten Dateien anwendet.
- Wenn bestimmte Dateien geÀndert wurden, muss die entsprechende abhÀngige Phase neu zusammengestellt werden.
Heute verfĂŒgt unser Builder ĂŒber viele weitere Möglichkeiten, aber die ursprĂŒnglichen WĂŒnsche und Impulse waren solche.
Kurz gesagt, wir haben uns mit der Programmiersprache bewaffnet, die wir verwenden, (siehe unten) und sind auf den Weg gegangen â unser eigenes DSL! Entsprechend den gestellten Anforderungen wurde es entwickelt, um den Aufbauprozess in Phasen zu beschreiben und die AbhĂ€ngigkeiten dieser Phasen von Dateien zu definieren. DarĂŒber hinaus ergĂ€nzte es unseren eigenen Builder, der DSL in das endgĂŒltige Ziel â ein erstelltes Abbild â verwandelte. UrsprĂŒnglich war DSL in Ruby geschrieben, und im Laufe der Zeit â die Konfiguration unseres Builders wird nun in einer YAML-Datei beschrieben.

Die alte Konfiguration fĂŒr dapp in Ruby

Die aktuelle Konfiguration fĂŒr werf in YAML
Der Mechanismus des Builders hat sich ebenfalls im Laufe der Zeit geĂ€ndert. ZunĂ€chst generierten wir einfach zur Laufzeit ein temporĂ€res Dockerfile aus unserer Konfiguration, und spĂ€ter begannen wir, Build-Anweisungen in temporĂ€ren Containern auszufĂŒhren und zu committen.
NB: GegenwĂ€rtig hat sich unser Builder, der mit seiner eigenen Konfiguration (in YAML) arbeitet und Stapel-Builder genannt wird, bereits zu einem leistungsstarken Werkzeug entwickelt. Eine ausfĂŒhrliche Beschreibung verdient eigene Artikel, wĂ€hrend die wichtigsten Details aus dem .
Bewusstsein fĂŒr das Problem
Aber wir haben, allerdings nicht sofort, verstanden, dass wir einen Fehler gemacht haben: Wir haben die Möglichkeit nicht hinzugefĂŒgt, Abbilder ĂŒber ein Standard-Dockerfile zu erstellen. und diese in die gleiche Infrastruktur fĂŒr das umfassende Anwendungsmanagement zu integrieren (d.h. Images zu erstellen, bereitzustellen und zu bereinigen). Wie könnte man ein Bereitstellungstool fĂŒr Kubernetes entwickeln, ohne die UnterstĂŒtzung von Dockerfile zu implementieren, dem standardisierten Weg, um Images fĂŒr die meisten Projekte zu beschreiben?
Anstelle einer Antwort auf diese Frage bieten wir eine Lösung dafĂŒr an. Was tun, wenn Sie bereits ein Dockerfile (oder eine Reihe von Dockerfiles) haben und werf verwenden möchten?
NB: Ăbrigens, warum sollten Sie ĂŒberhaupt daran interessiert sein, werf zu verwenden? Die Hauptfunktionen lassen sich wie folgt zusammenfassen:
- vollstĂ€ndiger Anwendungsmanagement-Zyklus einschlieĂlich der Bereinigung von Images;
- die Möglichkeit, mehrere Images aus einer einzigen Konfiguration gleichzeitig zu verwalten;
- ein verbesserter Bereitstellungsprozess fĂŒr mit Helm kompatible Charts.
Eine vollstÀndige Liste finden Sie auf .
Wenn wir frĂŒher vorgeschlagen hĂ€tten, das Dockerfile in unsere Konfiguration umzuschreiben, können wir jetzt mit Freude sagen: âLassen Sie werf Ihre Dockerfiles erstellen!â
Wie verwendet man das?
Die vollstĂ€ndige Umsetzung dieser Möglichkeit erschien in der Version . Das allgemeine Prinzip ist einfach: Der Benutzer gibt den Pfad zur bestehenden Dockerfile in der werf-Konfiguration an und startet dann den Befehl. werf build⊠und das ist alles â werf wird das Image erstellen. Schauen wir uns ein abstraktes Beispiel an.
Wir deklarieren den nÀchsten Dockerfile im Projektstamm:
FROM ubuntu:18.04
RUN echo Baue ... Und wir deklarieren werf.yaml, das dies verwendet Dockerfile:
configVersion: 1
project: dockerfile-example
---
image: ~
dockerfile: ./Dockerfile Fertig! Es bleibt nur noch seinen eigenen Server starten. werf build:

AuĂerdem kann der nĂ€chste deklariert werden werf.yaml um mehrere Images gleichzeitig aus verschiedenen Dockerfiles zu erstellen:
configVersion: 1
project: dockerfile-example
---
image: backend
dockerfile: ./dockerfiles/Dockerfile-backend
---
image: frontend
dockerfile: ./dockerfiles/Dockerfile-frontend SchlieĂlich wird auch die Ăbertragung zusĂ€tzlicher Build-Parameter unterstĂŒtzt â wie etwa --build-arg und --add-host â durch die werf-Konfiguration. Eine vollstĂ€ndige Beschreibung der Dockerfile-Image-Konfiguration ist verfĂŒgbar auf .
Wie funktioniert das?
WĂ€hrend des Builds funktioniert der Standard-Cache von lokalen Schichten in Docker. Wichtig ist jedoch, dass werf auch die Dockerfile-Konfiguration in seine Infrastruktur integriert. Was bedeutet das?
- Jedes Image, das aus einem Dockerfile erstellt wird, besteht aus einem Stage mit dem Namen
dockerfile(mehr dazu, was Stages in werf sind, kann man nachlesen ). - FĂŒr das Stage
dockerfileberechnet werf die Signatur, die von den Inhalten der Dockerfile-Konfiguration abhĂ€ngt. Wenn die Dockerfile-Konfiguration geĂ€ndert wird, Ă€ndert sich die Signatur des Stages.dockerfileund werf initiiert einen Neuaufbau dieser Phase mit der neuen Dockerfile-Konfiguration. Wenn sich die Signatur nicht Ă€ndert, nimmt werf das Image aus dem Cache. (mehr ĂŒber die Verwendung von Signaturen in werf wurde in ). - erlĂ€utert. Die gesammelten Images können dann mit dem Befehl
werf publish(oderwerf build-and-publish) veröffentlicht und fĂŒr das Deployment in Kubernetes verwendet werden. Die veröffentlichten Images im Docker Registry werden mit den Standardbereinigungswerkzeugen von werf gereinigt, d.h. es erfolgt eine automatische Bereinigung alter Images (Ă€lter als N Tage), Images, die mit nicht existierenden Git-Zweigen verknĂŒpft sind, und nach anderen Richtlinien.
Weitere Informationen zu den hier genannten Punkten finden Sie in der Dokumentation:
- ;
- ;
- .
Hinweise und VorsichtsmaĂnahmen
1. Externe URLs in ADD werden nicht unterstĂŒtzt.
Derzeit wird die Verwendung einer externen URL in der Direktive ADDnicht unterstĂŒtzt. Werf wird beim Ăndern der Ressource unter der angegebenen URL keinen Neuaufbau initiieren. Diese Möglichkeit ist in KĂŒrze geplant.
2. .git kann nicht in das Image hinzugefĂŒgt werden.
Im Allgemeinen ist das HinzufĂŒgen des Verzeichnisses .git zum Image eine unzulĂ€ssige schlechte Praxis, und das sind die GrĂŒnde dafĂŒr:
- Wenn
.gitbleibt im finalen Image, was gegen die Prinzipien verstöĂt : da das endgĂŒltige Image mit einem einzelnen Commit verknĂŒpft sein muss, sollte es keine Möglichkeit geben,git checkouteines beliebigen Commits zu machen. -
.gitvergröĂert die GröĂe des Images (das Repository kann groĂ sein, weil einmal groĂe Dateien hinzugefĂŒgt und dann gelöscht wurden). Die GröĂe des Work-Trees, das nur mit einem bestimmten Commit verbunden ist, hĂ€ngt jedoch nicht von der Operationshistorie in Git ab. Das HinzufĂŒgen und anschlieĂende Löschen.gitaus dem finalen Bild funktioniert nicht: das Image wird trotzdem eine unnötige Schicht erwerben â so funktioniert Docker. - Docker kann unnötige Neubauten initiieren, selbst wenn der gleiche Commit aus verschiedenen Work-Trees gebaut wird. Zum Beispiel erstellt GitLab separate geklonte Verzeichnisse in
/home/gitlab-runner/builds/HASH/[0-N]/yourprojectbei aktivierter paralleler Erstellung. Die unnötige Neubauten sind darauf zurĂŒckzufĂŒhren, dass das Verzeichnis.gitin verschiedenen geklonnten Versionen des gleichen Repositories unterschiedlich ist, selbst wenn der gleiche Commit kompiliert wird.
Der letzte Punkt hat auch Auswirkungen bei der Verwendung von werf. Werf verlangt, dass der gebaute Cache bei der AusfĂŒhrung bestimmter Befehle vorhanden ist (zum Beispiel, werf deploy). WĂ€hrend der Arbeit solcher Kommandos berechnet werf die Signaturen der Phasen fĂŒr die angegebenen Images, werf.yaml, und diese mĂŒssen im Build-Cache sein â andernfalls kann das Kommando die Arbeit nicht fortsetzen. Sollte jedoch die Signatur der Phasen vom Inhalt abhĂ€ngen, .git, erhalten wir einen Cache, der unbestĂ€ndig gegenĂŒber Ănderungen in irrelevanten Dateien ist, und werf kann einen solchen Fehler nicht verzeihen (siehe dazu ).
Insgesamt HinzufĂŒgen nur bestimmter notwendiger Dateien durch die Anweisung ADD steigert in jedem Fall die Effizienz und ZuverlĂ€ssigkeit des geschriebenen Dockerfile, sowie verbessert die StabilitĂ€t des Caches, der auf diesem Dockerfile, gegenĂŒber irrelevanten Ănderungen in Git.
Zusammenfassung
Unser ursprĂŒnglicher Weg, einen eigenen Builder fĂŒr bestimmte BedĂŒrfnisse zu schreiben, war mĂŒhsam, ehrlich und direkt: anstatt auf Standard-Dockerfiles mit Workarounds zurĂŒckzugreifen, haben wir unsere eigene Lösung mit einer angepassten Syntax erstellt. Und das hat sich ausgezahlt: Der Stapel-Builder erfĂŒllt seine Aufgabe hervorragend.
Beim Schreiben unseres eigenen Builders haben wir jedoch die UnterstĂŒtzung bestehender Dockerfiles ĂŒbersehen. Dieser Mangel wurde jetzt behoben, und wir planen, die UnterstĂŒtzung von Dockerfiles zusammen mit unserem benutzerdefinierten Stapel-Builder fĂŒr verteilte Builds und Builds mit Kubernetes weiterzuentwickeln (d.h. Builds auf Runnern innerhalb von Kubernetes, Ă€hnlich wie bei kaniko).
Wenn Sie also noch ein paar Dockerfiles haben... probieren Sie es aus. !
P.S. Dokumentationsliste zu diesem Thema
- ;
- ;
- ;
- ;
- ;
- ;
- .
Lesen Sie auch in unserem Blog: â».
Quelle: habr.com
