Sestavovat Docker obrazy v werf nyní lze i podle běžného Dockerfile

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.

Sestavovat Docker obrazy v werf nyní lze i podle běžného Dockerfile

Bude se jednat o werf — 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ě známého jako dapp).

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:

  1. 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.
  2. 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.
  3. 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 Golang se konfigurace našeho sestavovače začala popisovat v YAML souboru.

Sestavovat Docker obrazy v werf nyní lze i podle běžného Dockerfile
Starý konfigurace pro dapp na Ruby

Sestavovat Docker obrazy v werf nyní lze i podle běžného Dockerfile
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 dokumentaci.

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 stránce projektu.

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 werf v1.0.3-beta.1. 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:

Sestavovat Docker obrazy v werf nyní lze i podle běžného Dockerfile

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 stránce dokumentace.

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á?

  1. 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 zde).
  2. Pro fázi dockerfile werf vypočítává podpis, který závisí na obsahu konfigurace Dockerfile. Pokud dojde ke změně konfigurace Dockerfile, dojde ke změně podpisu fáze dockerfile a 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 této prezentaci).
  3. Následně může být sestavené image publikováno příkazem werf publish (nebo werf 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:

  1. Pokud .git zůstává ve finálním image, což narušuje principy 12 factor app: protože finální image by měl být spojen s jedním commitem, není povoleno, aby bylo možné provést git checkout libovolného commitu.
  2. .git zvyš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í .git Z finálního obrazu se to nespustí: obraz stejně získá další vrstvu – to je způsob, jakým Docker funguje.
  3. 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]/yourproject při povolené paralelní kompilaci. Zbytečná překompilace bude spojena s tím, že adresář .git se 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 dokumentaci).

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 werf!

P.S. Seznam dokumentace k tomuto tématu

Přečtěte si také na našem blogu: „werf — náš nástroj pro CI/CD v Kubernetes (přehled a video přednášky)».

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster