Lépe pozdě, než nikdy. Nebo jak jsme málem udělali vážnou chybu, když jsme neměli podporu pro běžné Dockerfiles pro sestavování obrazů aplikace.

Bude se jednat o — nástroj GitOps, který se integruje s jakýmkoli systémem CI/CD a zajišťuje správu celého životního cyklu aplikace, umožňující:
- sestavovat a publikovat obrazy,
- nasazovat aplikace do Kubernetes,
- odstraňovat nepoužívané obrazy pomocí speciálních politik.
Filozofie projektu je spojit nízkoúrovňové nástroje do jednotného unifikovaného systému, který poskytuje DevOps inženýrům kontrolu nad aplikacemi. Kde je to možné, měly by být využity již existující nástroje (například Helm a Docker). Pokud však neexistuje řešení pro některý problém, můžeme vytvořit a udržovat vše potřebné pro to.
Pozadí: vlastní sestavovač obrazů
To se stalo se sestavovačem obrazů ve werf: obvyklý Dockerfile nám chyběl. Pokud se rychle podíváme do historie projektu, tento problém se projevoval už v prvních verzích werf (tehdy ještě ).
Při vytváření nástroje pro sestavování aplikací do Docker obrazů jsme rychle pochopili, že Dockerfile nám nevyhovuje pro některé zcela konkrétní úkoly:
- Nutnost sestavit typické malé webové aplikace podle následující standardní schémy:
- nainstalovat systémové závislosti aplikace,
- nainstalovat balíček závislostí aplikace,
- sestavit assety,
- a to nejdůležitější — rychle a efektivně aktualizovat kód v obraze.
- Při změnách v souborech projektu by měl sestavovač rychle vytvářet novou vrstvu formou použití patchu na změněné soubory.
- Pokud se změnily určité soubory, je nutné znovu sestavit odpovídající závislou fázi.
V současnosti má náš sestavovač mnoho dalších možností, ale původní touhy a impulsy byly takové.
Celkově, aniž bychom dlouho váhali, jsme se vybavili používaným programovacím jazykem (viz níže) a vyrazili jsme na cestu — realizovat vlastní DSL! Odpovídal zadaným úkolům a byl určen k popisu procesu sestavování po etapách a k určení závislostí těchto etap na souborech. Doplňoval ho vlastní sestavovač, který přetvářel DSL na konečný cíl — sestavený obraz. Zpočátku byl DSL napsán v Ruby, a s přechodem na se konfigurace našeho sestavovače začala popisovat v YAML souboru.

Starý konfigurace pro dapp na Ruby

Aktuální konfigurace pro werf na YAML
Mechanismus fungování build nástroje se také vyvíjel v průběhu času. Zpočátku jsme jednoduše generovali za běhu dočasný Dockerfile z naší konfigurace, a poté jsme začali spouštět build instrukce v dočasných kontejnerech a provádět commit.
NB: V současnosti náš builder, který pracuje se svým vlastním konfiguračním souborem (ve YAML) a nazývá se Stapel Builder, již vyvinul na dostatečně silný nástroj. Jeho podrobné popisování si zaslouží samostatné články, a základní informace můžete zjistit z .
Uvědomění si problému
Ale pochopili jsme, a to ne hned, že jsme udělali jednu chybu: nepřidali jsme možnost sestavovat obrazy pomocí standardního Dockerfile a integrovat je do stejné infrastruktury komplexního řízení aplikací (tj. sestavovat obrazy, deployovat je a uklízet). Jak jsme mohli vytvořit nástroj pro deploy v Kubernetes a neimplementovat podporu Dockerfile, tj. standardního způsobu popisu obrazů pro většinu projektů?..
Místo odpovědi na takovou otázku nabízíme její řešení. Co dělat, pokud již máte Dockerfile (nebo sadu Dockerfile) a chcete používat werf?
NB: Mimochodem, proč byste vůbec chtěli používat werf? Hlavní funkce se shrnují do následujících:
- kompletní cyklus řízení aplikace včetně čištění obrazů;
- možnost řídit sestavení několika obrazů z jediné konfigurace;
- vylepšený proces nasazení chartů kompatibilních s Helm.
Se seznamem jejich funkcí se můžete seznámit na .
Takže pokud jsme dříve doporučili přepsat Dockerfile na naši konfiguraci, nyní s radostí říkáme: "Nechte werf sestavit vaše Dockerfile!"
Jak používat?
Kompletní implementace této možnosti se objevila v verzi . Obecný princip je jednoduchý: uživatel určí cestu k existujícímu Dockerfile v konfiguraci werf, po čemž spustí příkaz werf build… a hotovo — werf sestaví obraz. Podívejme se na abstraktní příklad.
Deklarujeme následující Dockerfile v kořenovém adresáři projektu:
FROM ubuntu:18.04
RUN echo Building ... A deklarujeme werf.yaml, který používá tuto Dockerfile:
configVersion: 1
project: dockerfile-example
---
image: ~
dockerfile: .\/Dockerfile Vše! Zbývá spustit werf build:

Kromě toho lze deklarovat následující werf.yaml pro sestavení několika obrazů z různých Dockerfile:
configVersion: 1
project: dockerfile-example
---
image: backend
dockerfile: .\/dockerfiles\/Dockerfile-backend
---
image: frontend
dockerfile: .\/dockerfiles\/Dockerfile-frontend Konečně je podporován i přenos dalších parametrů sestavení — jako například --build-arg a --add-host — prostřednictvím konfigurace werf. Podrobné informace o konfiguraci Dockerfile image jsou k dispozici na .
Jak to funguje?
Během sestavování funguje standardní cache místních vrstev v Dockeru. Nicméně, co je důležité, werf také integruje konfiguraci Dockerfile do své infrastruktury. Co to znamená?
- Každý image sestavený z Dockerfile se skládá z jedné fáze nazvané
dockerfile(více o tom, co jsou fáze v werfu, si můžete přečíst ). - Pro fázi
dockerfilewerf vypočítává podpis, který závisí na obsahu konfigurace Dockerfile. Pokud dojde ke změně konfigurace Dockerfile, dojde ke změně podpisu fázedockerfilea werf iniciuje znovusestavení této fáze s novou konfigurací Dockerfile. Pokud se podpis nemění, werf vezme image z cache (více o používání podpisů v werfu bylo popsáno v ). - Následně může být sestavené image publikováno příkazem
werf publish(nebowerf build-and-publish) a použito pro nasazení do Kubernetes. Publikované image v Docker Registry budou čištěny standardními čisticími nástroji werfu, tj. dojde k automatickému vyčištění starých image (starších než N dní), image souvisejících s neexistujícími Git větvemi a podle dalších politik.
Více o zde popsaných záležitostech se můžete dozvědět z dokumentace:
- ;
- ;
- .
Poznámky a varování
1. Vnější URL v ADD není podporováno
V současné době není podporováno používání vnějšího URL v direktivě ADD. Werf nebude iniciovat znovusestavení při změně zdroje podle uvedeného URL. V blízké budoucnosti se plánuje přidání této možnosti.
2. Nelze přidávat .git do image
Obecně platí, že přidávání adresáře .git do image je špatná praxe a to z následujícího důvodu:
- Pokud
.gitzůstává ve finálním image, což narušuje principy : protože finální image by měl být spojen s jedním commitem, není povoleno, aby bylo možné provéstgit checkoutlibovolného commitu. -
.gitzvyšuje velikost image (repo může být velké kvůli tomu, že byly dříve přidány velké soubory, které pak byly odstraněny). Velikost však work-tree spojeného pouze s konkrétním commitem nebude závislá na historii operací v Gitu. Přitom přidání a následné odstranění.gitZ finálního obrazu se to nespustí: obraz stejně získá další vrstvu – to je způsob, jakým Docker funguje. - Docker může iniciovat zbytečnou překompilaci, i když se sestavuje stejný commit, ale z různých work-tree. Například GitLab vytváří samostatné zkopírované adresáře v
/home/gitlab-runner/builds/HASH/[0-N]/yourprojectpři povolené paralelní kompilaci. Zbytečná překompilace bude spojena s tím, že adresář.gitse liší v různých zkopírovaných verzích stejného repozitáře, i když se sestavuje stejný commit.
Poslední bod má důsledky i při používání werf. Werf vyžaduje, aby byl nashromážděný cache přítomen při spuštění některých příkazů (například, werf deploy). Během provozu těchto příkazů werf vypočítává signatury etap pro obrazy uvedené v werf.yaml, a tyto musí být v kompilovaném cache – jinak příkaz nebude moci pokračovat. Pokud bude signatura etap závislá na obsahu .git, dostáváme nestabilní s cache, které se mění v důsledku irrelevantních souborů, a werf tuto chybu neodpustí (více informací viz ).
Celkově přidání pouze určitých potřebných souborů prostřednictvím instrukce ADD v každém případě zvyšuje efektivitu a spolehlivost napsaného Dockerfile, stejně jako zlepšuje stabilitu cache vytvořeného podle tohoto Dockerfile, vůči irrelevantním změnám v Gitu.
Výsledek
Naše původní cesta psaní vlastního sestavovače pro specifické potřeby byla náročná, poctivá a přímočará: místo použití opravných prostředků na standardní Dockerfile jsme napsali své vlastní řešení s vlastním syntaxem. A to mělo své výhody: Stapel-sestavovač skvěle plní svůj úkol.
Nicméně během psaní vlastního sestavovače jsme zapomněli na podporu již existujících Dockerfile. Tento nedostatek byl nyní opraven a do budoucna plánujeme rozšiřovat podporu Dockerfile spolu s naším vlastním sestavovačem Stapel pro distribuovanou kompilaci a pro kompilaci s využitím Kubernetes (tj. sestavování na běžcích uvnitř Kubernetes, tak jak je to provedeno v kaniko).
Takže, pokud máte náhodou pár Dockerfile… zkuste !
P.S. Seznam dokumentace k tomuto tématu
- ;
- ;
- ;
- ;
- ;
- ;
- .
Přečtěte si také na našem blogu: „».
Zdroj: habr.com
