Most Docker images in werf can now be built using a regular Dockerfile

Better late than never. Or how we almost made a serious mistake by not having support for standard Dockerfiles for application image builds.

Most Docker images in werf can now be built using a regular Dockerfile

We will talk about werf — a GitOps utility that integrates with any CI/CD system and manages the entire application lifecycle, allowing:

  • to build and publish images,
  • to deploy applications in Kubernetes,
  • to delete unused images using special policies.


The project's philosophy is to combine low-level tools into a unified system that gives DevOps engineers control over applications. Existing utilities (like Helm and Docker) should be used whenever possible. If a solution to a specific task is not available, we can create and support everything necessary for that.

Background: our image builder

This is exactly what happened with the image builder in werf: we missed the familiar Dockerfile. If we briefly dive into the project's history, this problem manifested itself in the early versions of werf (then still known as dapp).

When creating a tool for building applications into Docker images, we quickly realized that Dockerfile did not fit for certain specific tasks:

  1. The need to build typical small web applications according to the following standard scheme:
    • install application system-wide dependencies,
    • install a bundle of application dependency libraries,
    • build assets,
    • and most importantly — update the code in the image quickly and efficiently.
  2. When files in the project are modified, the builder should quickly create a new layer by overlaying a patch on the modified files.
  3. If certain files are changed, the corresponding dependent stage must be rebuilt.

Today, our builder has many other capabilities, but the initial desires and impulses were as follows.

In general, without further ado, we armed ourselves with the programming language being used (see below) and set out to implement our own DSL! In line with the set tasks, it was intended to describe the build process step-by-step and define the dependencies of these stages on files. Additionally, it included our own builder, which transformed the DSL into the final goal — the built image. Initially, the DSL was written in Ruby, but as time went on, átállás a Golangra — a gyűjtőnk konfigurációját YAML-fájlban kezdtük leírni.

Most Docker images in werf can now be built using a regular Dockerfile
Régi konfiguráció dapp-re Ruby alatt

Most Docker images in werf can now be built using a regular Dockerfile
Aktuális konfiguráció werf-re YAML-ben

A gyűjtő működési mechanizmusa is idővel változott. Eleinte csak egy ideiglenes Dockerfile-t generáltunk a konfigurációnkból, majd elkezdtük a gyűjtési utasításokat ideiglenes konténerekben futtatni, és commit-oltunk.

NB: Jelenleg a gyűjtőnk, amely a saját konfigurációjával (YAML-ben) Stapel-gyűjtőnek hívják, már egy elég erős eszközzé fejlődött. Az alapos leírása külön cikkeket érdemel, a főbb részletek pedig megtalálhatók a dokumentáció.

A probléma felismerése

De hamar rájöttünk, hogy elkövettünk egy hibát: nem adtuk hozzá a lehetőséget képek létrehozására a szabványos Dockerfile segítségével és integrálni őket ugyanabba a komplex alkalmazáskezelési infrastruktúrába (azaz képek létrehozása, telepítés és tisztítás). Hogyan lehetett olyan telepítőeszközt készíteni a Kuberneteshez, amely nem valósította meg a Dockerfile támogatását, azaz a legtöbb projekt számára standard képleírási módot?..

Ahelyett, hogy válaszolnánk egy ilyen kérdésre, a megoldását kínáljuk. Mit tegyen, ha már van Dockerfile-ja (vagy Dockerfile-ok halmaza), és szeretné használni a werf-et?

NB: Egyébként miért is akarna használni werf-et? A főbb funkciói a következőkre terjednek ki:

  • teljes alkalmazáskezelési ciklus, beleértve a képek tisztítását;
  • lehetőség több kép összeállításának kezelésére egyetlen konfigurációból;
  • javított telepítési folyamat, a Helm-kompatibilis chartekhez.

A teljes listát megtalálhatja a projekt oldalán.

Tehát, ha korábban azt javasoltuk, hogy írja át a Dockerfile-t a mi konfigurációnkra, most örömmel mondjuk: „Engedje meg, hogy a werf elkészítse a Dockerfile-ját!”

Hogyan használható?

A funkció teljes megvalósítása a werf v1.0.3-beta.1. Az általános elv egyszerű: a felhasználó megadja a létező Dockerfile elérési útját a werf konfigurációjában, majd elindítja a parancsot werf build… és kész — a werf összeállítja a képet. Nézzük meg egy elvont példán.

Deklaráljunk egy következőt Dockerfile a projekt gyökerében:

FROM ubuntu:18.04
RUN echo Building ...

És deklaráljunk werf.yaml, amely ezt használja Dockerfile:

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

Minden! Csak el kell indítani werf build:

Most Docker images in werf can now be built using a regular Dockerfile

Továbbá, lehetőség van a következő deklarálására werf.yaml több kép egyszerre történő összeállításához különböző Dockerfile-okról:

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

Végre támogatja a további build-paraméterek átadását is, mint például --build-arg és --add-host — a werf konfiguráción keresztül. A Dockerfile image konfiguráció teljes leírása elérhető a dokumentációs oldalon.

Hogyan működik ez?

A build folyamat során a Dockerben a helyi rétegek standard gyorsítótára működik. Fontos azonban, hogy a werf is integrálja a Dockerfile konfigurációt a saját infrastruktúrájába. Mit jelent ez?

  1. Minden Dockerfile-ból készült image egy dockerfile (további információ arról, hogy mik a stagingek a werf-ben, itt olvashat) itt).
  2. A staginghez dockerfile a werf kiszámítja a szignatúrát, amely a Dockerfile konfiguráció tartalmától függ. Ha a Dockerfile konfiguráció megváltozik, a stage szignatúrája is megváltozik dockerfile és a werf újraépíti ezt a staginget az új Dockerfile konfigurációval. Ha viszont a szignatúra nem változik, akkor a werf a gyorsítótárból veszi az image-t (bővebben a werf szignatúrák használatáról itt volt szó ebben a beszámolóban).
  3. A későbbiekben a létrehozott image-eket a következő parancs segítségével publikálhatjuk werf publish SysWOW64 werf build-and-publish) és használhatjuk a Kubernetesben való telepítéshez. A Docker Registry-ben közzétett image-eket a werf standard tisztítószerei fognak kezelni, azaz automatikusan megtisztítja a régi image-eket (N napnál idősebb), a nem létező Git-ágakkal összefüggő image-eket és egyéb irányelvek szerint.

További információkat a fent említett pontokkal kapcsolatban a dokumentációból lehet szerezni:

Megjegyzések és figyelmeztetések

1. Külső URL az ADD utasításban nem támogatott

Jelenleg nem támogatott a külső URL használata az ADDutasításban. A werf nem indít újraépítést, ha a megadott URL erőforrása megváltozik. Hamarosan tervezik ennek a lehetőségnek a hozzáadását.

2. A .git nem adható hozzá az image-hez

Általában véve a .git mappa hozzáadása az image-hez rossz gyakorlat, és hogy miért:

  1. Ha .git marad a végső image-ben, ez megsérti a 12 faktoros alkalmazáselveit: mivel a végső image-nek egyetlen commit-hoz kell kapcsolódnia, nem lehetőség szabad commit létrehozása. git checkout önkényes elköteleződést.
  2. .git növeli a képméretet (a tároló nagy lehet, mert valaha nagy fájlokat adtak hozzá, majd eltávolították őket). A work-tree mérete, amely csak egy adott commit-hoz kapcsolódik, nem függ a Git műveletek történetétől. Ezzel együtt a hozzáadás és a későbbi eltávolítás .git a végső képből nem fog működni: a kép így is kap egy további réteget — így működik a Docker.
  3. A Docker kezdeményezheti a felesleges újrafelépítést, még akkor is, ha ugyanannak a commit-nak az összeállítása történik, de különböző work-tree-kből. Például a GitLab külön klónozott könyvtárakat hoz létre /home/gitlab-runner/builds/HASH/[0-N]/yourproject párhuzamos összeállítás engedélyezése esetén. A felesleges újrafelépítés azzal lesz összefüggésben, hogy a könyvtár .git különbözik a ugyanazon tároló különböző klónozott verzióiban, még ha ugyanaz a commit is kerül összeállításra.

Az utolsó pontnak következményei vannak a werf használatakor is. A werf megköveteli, hogy a környezeti cache, amely a küldött parancsok során szükséges, jelen legyen (például werf deploy). Az ilyen parancsok végrehajtása során a werf az adott képekre vonatkozó fázisok aláírásait számítja ki, amelyeknek a werf.yaml, a build cache-ben kell lenniük — különben a parancs nem tud folytatódni. Ha azonban az aláírások a tartalomtól függenek .git, akkor egy instabil cache-t kapunk, amely érzéketlen a nem releváns fájlok módosításaira, és a werf nem tud megbocsátani egy ilyen hibát (további részletekért lásd dokumentáció).

Általában csak bizonyos szükséges fájlok hozzáadása a parancs révén ADD mindig növeli a megírtak hatékonyságát és megbízhatóságát Dockerfile, valamint javítja a cache stabilitását, amelyet az adott Dockerfile, nem releváns módosításokkal szemben készítettek a Git-ben.

Result

A mi kezdeti utunk egy saját építő írásával bizonyos igények kielégítésére nehéz, megtisztelő és egyenes volt: ahelyett, hogy a standard Dockerfile fölé lábakra támaszkodtunk volna, saját megoldásunkat írtuk egy egyedi szintaxissal. Ez előnyöket hozott: a Stapel-építő kiválóan végzi a feladatát.

Azonban a saját építőnk írása közben figyelmen kívül hagytuk a már létező Dockerfile-ok támogatását. Most ezt a hiányosságot kijavítottuk, és a jövőben tervezzük a Dockerfile támogatásának fejlesztését a saját egyedi Stapel építőnkkel párhuzamosan a elosztott építéshez és a Kubernetes használatával történő építéshez (azaz építések a Kubernetes belsejében lévő futtatókban, ahogy azt a kanikóban is tették).

Nos, ha egy pár Dockerfile-ad akadt… próbáld ki werf!

P.S. A témához kapcsolódó dokumentációs lista

Olvasd el blogunkon is: „werf — az eszközünk CI/CD-hez Kubernetes-ben (áttekintés és a beszámoló videója)».

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster