Docker-Images in werf können jetzt auch mit einem normalen Dockerfile gebaut werden.

Besser spĂ€t als nie. Oder wie wir fast einen ernsthaften Fehler gemacht hĂ€tten, weil wir keine UnterstĂŒtzung fĂŒr gĂ€ngige Dockerfiles zum Erstellen von Anwendungsimages hatten.

Docker-Images in werf können jetzt auch mit einem normalen Dockerfile gebaut werden.

Es geht um werf — ein GitOps-Tool, das sich in jedes CI/CD-System integriert und die gesamte Lebenszyklusverwaltung von Anwendungen ermöglicht, indem es:

  • Images erstellt und veröffentlicht,
  • Anwendungen in Kubernetes bereitstellt,
  • nicht mehr benötigte Images durch spezielle Richtlinien entfernt.


Die Philosophie des Projekts besteht darin, grundlegende Werkzeuge in ein einheitliches System zu integrieren, das DevOps-Ingenieuren die Kontrolle ĂŒber Anwendungen gibt. Wo möglich, sollten bereits bestehende Tools (wie Helm und Docker) verwendet werden. Wenn jedoch keine Lösung fĂŒr eine bestimmte Aufgabe existiert, können wir alles Notwendige dafĂŒr schaffen und unterstĂŒtzen.

Vorgeschichte: unser Image-Builder

So kam es, dass wir fĂŒr den Image-Builder in werf einen gewohnten Dockerfile vermissten. Wenn wir kurz auf die Geschichte des Projekts zurĂŒckblicken, wird sichtbar, dass dieses Problem bereits in den ersten Versionen von werf (damals noch bekannt als dapp).

auftrat. Als wir ein Tool zur Erstellung von Anwendungen in Docker-Images entwickelten, merkten wir schnell, dass Dockerfile fĂŒr einige spezifische Aufgaben nicht geeignet war:

  1. Die Notwendigkeit, typische kleine Webanwendungen nach folgendem Standard-Schema zu erstellen:
    • SystemabhĂ€ngigkeiten der Anwendung zu installieren,
    • BĂŒndel von AbhĂ€ngigkeiten der Anwendung zu installieren,
    • Assets zu sammeln,
    • und das Wichtigste — den Code im Image schnell und effizient zu aktualisieren.
  2. Bei Änderungen in den Projektdateien muss der Builder schnell eine neue Schicht erstellen, indem er einen Patch auf die geĂ€nderten Dateien anwendet.
  3. Wenn bestimmte Dateien geÀndert werden, muss die entsprechende abhÀngige Phase neu erstellt werden.

Heute bietet unser Builder viele weitere Funktionen, aber die ursprĂŒnglichen WĂŒnsche und Impulse waren so.

Insgesamt haben wir kurzerhand die verwendete Programmiersprache gewĂ€hlt (siehe unten) und sind losgezogen — um umzusetzen unseren eigenen DSL! Entsprechend den Anforderungen war es vorgesehen, den Prozess der schrittweisen Erstellung und die AbhĂ€ngigkeiten dieser Phasen von Dateien zu beschreiben. ErgĂ€nzt wurde es durch unseren eigenen Builder, der DSL in das Endziel — das erstellte Image — umwandelte. ZunĂ€chst war DSL in Ruby, und im Zuge des Wechsels zu Golang wurde die Konfiguration unseres Builders in einer YAML-Datei beschrieben.

Docker-Images in werf können jetzt auch mit einem normalen Dockerfile gebaut werden.
Alterer Konfigurationsdatei fĂŒr dapp in Ruby

Docker-Images in werf können jetzt auch mit einem normalen Dockerfile gebaut werden.
Aktuelle Konfigurationsdatei fĂŒr werf in YAML

Der Arbeitsmechanismus des Builders hat sich im Laufe der Zeit ebenfalls verĂ€ndert. ZunĂ€chst haben wir einfach eine temporĂ€re Dockerfile aus unserer Konfiguration zur Laufzeit generiert. Anschließend begannen wir, Buildanweisungen in temporĂ€ren Containern auszufĂŒhren und sie zu committen.

NB: Derzeit ist unser Builder, der mit seiner Konfiguration (in YAML) arbeitet und Stapel-Builder genannt wird, zu einem leistungsstarken Werkzeug gereift. Eine ausfĂŒhrliche Beschreibung verdient eigene Artikel, wĂ€hrend die wichtigsten Details aus Dokumentation.

Das Bewusstsein fĂŒr das Problem

Aber wir haben, was nicht sofort klar wurde, einen Fehler gemacht: Wir haben die Möglichkeit nicht hinzugefĂŒgt, Images ĂŒber die Standard-Dockerfile zu bauen und sie in die gleiche Infrastruktur des umfassenden Anwendungsmanagements zu integrieren (d.h. Images zu bauen, sie zu deployen und sie zu bereinigen). Wie konnte man ein Deployment-Tool fĂŒr Kubernetes entwickeln und dabei den Support fĂŒr Dockerfile, das heißt die standardisierte Art der Beschreibung von Images fĂŒr die meisten Projekte, nicht implementieren?

Anstatt auf diese Frage zu antworten, bieten wir eine Lösung. Was tun, wenn Sie bereits ein Dockerfile (oder eine Reihe von Dockerfiles) haben und werf verwenden möchten?

NB: Übrigens, warum sollten Sie ĂŒberhaupt werf verwenden wollen? Die Hauptmerkmale lassen sich wie folgt zusammenfassen:

  • vollstĂ€ndiger Lebenszyklus des Anwendungsmanagements einschließlich der Bereinigung von Images;
  • Möglichkeit, den Build mehrerer Images aus einer einzigen Konfiguration zu steuern;
  • verbesserten Deployment-Prozess fĂŒr Helm-kompatible Charts.

Eine vollstÀndige Liste der Funktionen finden Sie auf Projekseite.

Also, wenn wir frĂŒher vorgeschlagen hĂ€tten, das Dockerfile in unsere Konfiguration umzuschreiben, sagen wir jetzt gerne: „Lassen Sie werf Ihre Dockerfiles bauen!“

Wie verwendet man das?

Die vollstĂ€ndige Implementierung dieses Features wurde in der Version werf v1.0.3-beta.1. Das Grundprinzip ist einfach: Der Benutzer gibt den Pfad zur bestehenden Dockerfile in der werf-Konfiguration an und fĂŒhrt dann den Befehl aus werf build
 und das war's — werf wird das Image bauen. Lassen Sie uns ein abstraktes Beispiel betrachten.

Lassen Sie uns den nÀchsten Dockerfile im Stammverzeichnis des Projekts deklarieren:

FROM ubuntu:18.04
RUN echo Bau ...

Und erklÀren wir werf.yaml, der dieses nutzt Dockerfile:

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

Das ist alles! Jetzt bleibt es gestart werden werf build:

Docker-Images in werf können jetzt auch mit einem normalen Dockerfile gebaut werden.

DarĂŒber hinaus kann der nĂ€chste werf.yaml fĂŒr den gleichzeitigen Bau mehrerer Images aus verschiedenen Dockerfiles deklariert werden:

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

Endlich wird auch die Übertragung zusĂ€tzlicher Build-Parameter unterstĂŒtzt, wie z. B. --build-arg und --add-host — ĂŒber die werf-Konfiguration. Eine vollstĂ€ndige Beschreibung der Dockerfile-Image-Konfiguration ist verfĂŒgbar auf der Dokumentationsseite.

Wie funktioniert das?

WĂ€hrend des Build-Vorgangs funktioniert der Standard-Cache der lokalen Schichten in Docker. Wichtig ist jedoch, dass werf auch die Dockerfile-Konfiguration in seine Infrastruktur integriert.. Was bedeutet das?

  1. Jedes Image, das aus einem Dockerfile erstellt wird, besteht aus einer Phase, die genannt wird dockerfile (weiterfĂŒhrende Informationen zu Phasen in werf können gelesen werden hier).
  2. FĂŒr die Phase dockerfile berechnet werf eine Signatur, die von dem Inhalt der Dockerfile-Konfiguration abhĂ€ngt. Wenn die Dockerfile-Konfiguration geĂ€ndert wird, Ă€ndert sich die Signatur der Phase dockerfile und werf initiiert die Neubau dieser Phase mit der neuen Dockerfile-Konfiguration. Wenn sich die Signatur jedoch nicht Ă€ndert, verwendet werf das Image aus dem Cache (nĂ€here Informationen zur Verwendung von Signaturen in werf wurden in diesem Vortrag besprochen).
  3. Die erstellten Images können dann mit dem Befehl werf publish (oder werf build-and-publish) veröffentlicht und zur Bereitstellung in Kubernetes verwendet werden. Die veröffentlichten Images im Docker-Registry werden mit den Standardbereinigungsmethoden von werf bereinigt, das heißt, es erfolgt eine automatische Bereinigung alter Images (Ă€lter als N Tage), von Images, die mit nicht existierenden Git-Zweigen verbunden sind, und gemĂ€ĂŸ anderen Richtlinien.

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

Anmerkungen und Vorsichtsmaßnahmen

1. Externe URLs in ADD werden nicht unterstĂŒtzt

Derzeit wird die Verwendung externer URLs in der Direktive ADD. Werf wird bei einer Änderung der Ressource unter der angegebenen URL keine Neubau initiieren. Diese Funktion wird in naher Zukunft hinzugefĂŒgt.

2. .git darf nicht in das Image hinzugefĂŒgt werden

Im Allgemeinen ist das HinzufĂŒgen des Verzeichnisses .git zum Image eine schlechte Praxis, und das sind die GrĂŒnde:

  1. Wenn .git bleibt im finalen Image, was die Prinzipien von 12 factor app: da das finale Image mit einem Commit verknĂŒpft sein sollte, darf es keine Möglichkeit geben, einen git checkout willkĂŒrlichen Commit zu machen.
  2. .git erhöht die GrĂ¶ĂŸe des Images (das Repository könnte groß sein, weil irgendwann große Dateien hinzugefĂŒgt wurden und spĂ€ter gelöscht wurden). Die GrĂ¶ĂŸe des Arbeitsbaums, der nur mit einem bestimmten Commit verbunden ist, hĂ€ngt nicht von der Historie der Operationen in Git ab. Dabei fĂŒhrt das HinzufĂŒgen und anschließende Löschen .git Das finale Image wird nicht funktionieren: Das Image wird dennoch eine zusĂ€tzliche Schicht erhalten – so funktioniert Docker.
  3. Docker kann eine unnötige Neuaufbau-Aktion 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]/yourproject aktiviertem Parallelaufbau. Die unnötige Neuaufbau-Aktion wird damit zusammenhÀngen, dass das Verzeichnis .git in den verschiedenen geklonnten Versionen des gleichen Repositories unterschiedlich ist, auch wenn derselbe Commit gebaut wird.

Der letzte Punkt hat auch eine Konsequenz bei der Verwendung von werf. Werf erfordert, dass der gebaute Cache bei der AusfĂŒhrung bestimmter Befehle vorhanden ist (z. B. werf deploy). WĂ€hrend der AusfĂŒhrung solcher Befehle berechnet werf die Signaturen der Stufen fĂŒr die angegebenen Images, werf.yaml, und diese mĂŒssen sich im Build-Cache befinden – andernfalls kann der Befehl nicht fortgesetzt werden. Wenn jedoch die Signatur der Stufen von den Inhalten .gitabhĂ€ngt, erhalten wir einen instabilen Cache, der nicht gegen Änderungen in irrelevanten Dateien resistent ist, und werf kann einen solchen Fehler nicht verzeihen (siehe dazu Dokumentation).

Im Allgemeinen das HinzufĂŒgen nur bestimmter notwendiger Dateien ĂŒber die Anweisung ADD in jedem Fall erhöht die Effizienz und ZuverlĂ€ssigkeit des Geschriebenen Dockerfile, sowie die Resistenz des in Bezug auf das Build-Cache gegen irrelevante Änderungen in Git. DockerfileUnser ursprĂŒnglicher Weg, einen eigenen Builder fĂŒr spezifische BedĂŒrfnisse zu schreiben, war mĂŒhsam, ehrlich und geradlinig: Anstatt Notlösungen ĂŒber dem Standard-Dockerfile zu verwenden, haben wir unsere eigene Lösung mit benutzerdefinierter Syntax geschrieben. Und das brachte seine Vorteile: Der Stapel-Builder erfĂŒllt seine Aufgabe hervorragend.

Fazit

Allerdings haben wir bei der Erstellung unseres eigenen Builders die UnterstĂŒtzung bereits vorhandener Dockerfiles außer Acht gelassen. Dieser Mangel ist jetzt behoben, und in Zukunft planen wir, die UnterstĂŒtzung von Dockerfiles parallel zu unserem benutzerdefinierten Stapel-Builder fĂŒr verteilte Builds und fĂŒr Builds mit Kubernetes weiterzuentwickeln (d. h. Builds auf Runnern innerhalb von Kubernetes, wie es in kaniko gemacht wird).

Also, falls Sie zufÀllig ein paar Dockerfiles herumliegen haben...

P.S. Eine Liste von Dokumentationen zu diesem Thema versuchen Sie es werf!

LeitfĂ€den fĂŒr einen schnellen Einstieg

Besser spÀt als nie.Release des Konsolen-XMPP/Jabber-Clients profanity 0.7.0».

Quelle: habr.com

ZuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz kaufen, VPS VDS Server đŸ”„ ZuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster