Bolje ikad nego nikad. Ili kako smo jedva izbjegli ozbiljnu grešku ne imajući podršku za obične Dockerfile za izradu aplikacijskih slika.

Govorit ćemo o — GitOps alatu koji se integrira sa bilo kojim CI/CD sustavom i omogućava upravljanje cijelim ciklusom života aplikacije, omogućujući:
- prikupljanje i objavu slika,
- implementaciju aplikacija u Kubernetes,
- uklanjanje neiskorištenih slika uz pomoć specijalnih pravila.
Filozofija projekta je okupiti niskorazinske alate u jedinstven, unificiran sustav koji daje DevOps inženjerima kontrolu nad aplikacijama. Gdje god je to moguće, trebali bi se koristiti već postojeći alati (poput Helma i Dockera). Ako rješenja za neki zadatak nema — možemo stvoriti i održavati sve što je potrebno za to.
Pozadina: naš vlastiti alat za izradu slika
Tako se dogodilo sa alatom za izradu slika u werf-u: nedostajao nam je uobičajeni Dockerfile. Ako se osvrnemo na povijest projekta, ovaj je problem postao očit već u prvim verzijama werfa (tada još ).
Stvarajući alat za izradu aplikacija u Docker slike, brzo smo shvatili da nam Dockerfile ne odgovara za neke vrlo specifične zadatke:
- Potrebna je izrada tipičnih manjih web aplikacija prema sljedećem standardnom obrascu:
- instalirati sistemske ovisnosti aplikacije,
- instalirati paket biblioteka ovisnosti aplikacije,
- prikupiti asete,
- i najvažnije — brzo i učinkovito ažurirati kod u slici.
- Pri promjenama u datotekama projekta, alat za izradu slika trebao bi brzo stvarati novu sloj preklapanjem izmijenjenih datoteka.
- Ako su se određene datoteke promijenile, potrebno je ponovo izraditi odgovarajuću ovisnu fazu.
Danas naš alat za izradu slika ima i mnoge druge mogućnosti, ali izvorne želje i povici bili su takvi.
Uglavnom, bez previše razmišljanja, opremili smo se korištenim programskim jezikom (vidi dolje) i krenuli — realizirati vlastiti DSL! U skladu s postavljenim zadacima, on je bio namijenjen opisivanju procesa izrade po fazama i određivanju ovisnosti tih faza o datotekama. A dopunjavali su ga vlastiti alat za izradu, koji je pretvarao DSL u konačni cilj — izrađenu sliku. Isprva je DSL bio na Ruby-ju, a kako je nastupila konfiguracija našeg alata za izradu postala je opisana u YAML datoteci.

Stara konfiguracija za dapp na Ruby-ju

Trenutna konfiguracija za werf na YAML-u
Mehanizam rada graditelja također se mijenjao tijekom vremena. Isprva smo jednostavno generirali određeni privremeni Dockerfile iz naše konfiguracije, a zatim smo počeli pokretati upute za gradnju u privremenim kontejnerima i praviti commit.
NB: Trenutno naš graditelj, koji radi sa svojom konfiguracijom (u YAML-u) i naziva se Stapel-graditelj, već se razvio u prilično moćan alat. Njegov detaljan opis zaslužuje odvojene članke, a osnovne detalje možete saznati iz .
Svijest o problemu
No, shvatili smo, i to ne odmah, da smo napravili jednu grešku: nismo dodali mogućnost graditi slike putem standardnog Dockerfile-a i integrirati ih u istu infrastrukturu za upravljanje aplikacijama (tj. graditi slike, implementirati ih i čistiti). Kako je bilo moguće napraviti alat za implementaciju u Kubernetes i ne implementirati podršku za Dockerfile, tj. standardni način opisa slika za većinu projekata?..
Umjesto odgovora na takvo pitanje predlažemo njegovo rješenje. Što učiniti ako već imate Dockerfile (ili set Dockerfile-ova) i želite koristiti werf?
NB: Usput, zašto bi ste uopće željeli koristiti werf? Glavne značajke svode se na sljedeće:
- cijeli ciklus upravljanja aplikacijom, uključujući čišćenje slika;
- mogućnost upravljanja gradnjom više slika iz jedne konfiguracije;
- poboljšani proces isporuke grafikonâ, kompatibilnih s Helm-om.
Potpun popis možete pronaći na .
Dakle, da smo prije savjetovali da prepišete Dockerfile u našu konfiguraciju, sada s radošću kažemo: «Dopustite werf-u da izgradi vaše Dockerfile-ove!»
Kako koristiti?
Puna implementacija ove mogućnosti pojavila se u izdanju . Opći princip je jednostavan: korisnik navodi put do postojećeg Dockerfile-a u konfiguraciji werf-a, nakon čega pokreće naredbu werf build… i to je to — werf će izgraditi sliku. Razmotrimo na apstraktnom primjeru.
Objavimo sljedeće Dockerfile u korijenu projekta:
FROM ubuntu:18.04
RUN echo Building ... I objavimo werf.yaml, koji koristi ovaj Dockerfile:
configVersion: 1
project: dockerfile-example
---
image: ~
dockerfile: .\/Dockerfile Sve! Ostalo je pokrenuti werf build:

Osim toga, možete objaviti sljedeće werf.yaml za izgradnju više slika iz različitih Dockerfile-ova:
configVersion: 1
project: dockerfile-example
---
image: backend
dockerfile: .\/dockerfiles\/Dockerfile-backend
---
image: frontend
dockerfile: .\/dockerfiles\/Dockerfile-frontend Konačno, podržano je i slanje dodatnih parametara za izgradnju — kao što su --build-arg i --add-host — putem werf konfiguracije. Potpuni opis konfiguracije Dockerfile slike dostupan je na .
Kako to radi?
Tijekom izrade koristi se standardna predmemorija lokalnih slojeva u Dockeru. Međutim, što je važno, werf također integrira konfiguraciju Dockerfile u svoju infrastrukturu. Što to znači?
- Svaka slika koja se gradi iz Dockerfile-a sastoji se od jedne faze pod nazivom
dockerfile(više o tome što su faze u werf-u može se pročitati ). - Za fazu
dockerfilewerf izračunava potpis koji ovisi o sadržaju konfiguracije Dockerfile-a. Kada se konfiguracija Dockerfile-a promijeni, dolazi do promjene potpisa fazedockerfilei werf pokreće ponovnu izgradnju te faze s novom konfiguracijom Dockerfile-a. Ako se potpis ne mijenja, werf uzima sliku iz predmemorije (više o korištenju potpisa u werf-u objašnjeno je u ). - Dalje, izgrađene slike mogu se objaviti pomoću naredbe
werf publish(iliwerf build-and-publish) i koristiti za implementaciju u Kubernetes. Objavljene slike u Docker Registry bit će očišćene standardnim sredstvima čišćenja werf-a, tj. doći će do automatskog čišćenja starih slika (starijih od N dana), slika povezanih s nepostojećim Git granama, i prema drugim politikama.
Više o ovdje opisanim pitanjima može se saznati iz dokumentacije:
- ;
- ;
- .
Napomene i upozorenja
1. Vanjski URL u ADD nije podržan
Trenutno nije podržano korištenje vanjskog URL-a u naredbi ADD. Werf neće pokrenuti ponovnu izgradnju prilikom promjene resursa na zadatom URL-u. U skoroj budućnosti planira se dodavanje ove mogućnosti.
2. Ne možete dodavati .git u sliku
Općenito, dodavanje direktorija .git u sliku je loša praksa, a evo i zašto:
- Ako
.gitostaje u konačnoj slici, što krši principe : budući da konačna slika treba biti povezana s jednim commit-om, ne bi smjelo biti moguće napravitigit checkoutbilo kojeg commit-a. -
.gitpovećava veličinu slike (repozitorij može biti velik zbog toga što su nekada dodani veliki datoteke, a zatim obrisani). Veličina work-tree-a povezanog samo s određenim commit-om neće ovisiti o povijesti operacija u Gitu. U tom smislu dodavanje i kasnije brisanje.gitPosljednji sloj iz konačne slike se neće primijeniti: slika će i dalje dobiti dodatni sloj — tako radi Docker. - Docker može inicirati nepotrebnu ponovnu izgradnju, čak i kada se gradi isti commit, ali iz različitih work-tree. Na primjer, GitLab stvara odvojene klonirane direktorije u
/home/gitlab-runner/builds/HASH/[0-N]/yourprojectuključujući paralelnu izgradnju. Nepotrebna ponovna izgradnja će biti povezana s tim što se direktorij.gitrazličito koristi u raznim kloniranim verzijama istog repozitorija, čak i kada se gradi isti commit.
Zadnja točka ima posljedicu i pri korištenju werf. Werf zahtijeva da spremljeni predmemorijski podaci budu prisutni prilikom pokretanja nekih komandi (na primjer, werf deploy). Dok takve komande rade, werf izračunava potpise faza za slike navedene u werf.yaml, i one moraju biti u građevnoj predmemoriji — inače komanda neće moći nastaviti s radom. Ako se potpis faza oslanja na sadržaj .git, tada dolazimo do predmemorije koja nije otporna na promjene u nepovezanim datotekama, a werf neće moći oprostiti takvu grešku (više o tome u ).
U globalu dodavanju samo određenih potrebnih datoteka putem upute ADD u svakom slučaju povećava efikasnost i pouzdanost napisanog Dockerfile, kao i poboljšava otpornost predmemorije koja je sastavljena prema ovom Dockerfile, na nepovezane promjene u Git-u.
Zaključak
Naš inicijalni put s pisanjem vlastitog graditelja za određene potrebe bio je težak, iskren i izravan: umjesto korištenja brzopletih rješenja preko standardnog Dockerfile-a, napisali smo svoje rješenje s prilagođenom sintaksom. I to je donijelo svoje prednosti: Stapel graditelj odlično obavlja svoj zadatak.
Međutim, tijekom pisanja vlastitog graditelja propustili smo podršku za već postojeće Dockerfile-ove. Sada je ovaj nedostatak ispravljen, a u budućnosti planiramo razvijati podršku za Dockerfile uz naš prilagođeni graditelj Stapel za distribuiranu izgradnju i za izgradnju koristeći Kubernetes (tj. izgradnje na runner-ima unutar Kubernetesa, kao što je to učinjeno u kaniku).
Dakle, ako imate par Dockerfile-ova... isprobajte !
P.S. Popis dokumentacije o temi
- ;
- ;
- ;
- ;
- ;
- ;
- .
Čitajte također na našem blogu: „».
Izvor: habr.com
