
— naše GitOps CLI nástroje s otevřeným zdrojovým kódem pro sestavení a doručování aplikací do Kubernetes. V byla představena nová funkce v nástroji pro vytváření obrazů: štítkování obrazů podle obsahu nebo content-based tagging. Dosud typická schéma štítkování v werf předpokládala štítkování Docker obrazů podle Git tagu, Git větve nebo Git commitu. Ale všechny tyto schémata mají nevýhody, které nová strategie štítkování zcela řeší. Podrobnosti o ní a proč je tak dobrá — níže.
Nasazení sady mikroslužeb z jednoho Git repozitáře
Často se setkáváme se situací, kdy je aplikace rozdělena na více či méně nezávislých služeb. Uvolnění těchto služeb může probíhat nezávisle: najednou může být uvolněna jedna nebo více služeb, zatímco ostatní by měly pokračovat v provozu bez jakýchkoli změn. Ale z pohledu uchovávání kódu a správy projektu je výhodnější držet takové služby aplikace v jednom repozitáři.
Jsou situace, kdy jsou služby skutečně nezávislé a nejsou spojeny s jednou aplikací. V takovém případě budou umístěny v oddělených projektech a jejich uvolnění bude realizováno prostřednictvím samostatných procesů CI/CD v každém projektu.
Ve skutečnosti však vývojáři často rozdělují jednu aplikaci na několik mikroslužeb, ale vytváření zvláštního repozitáře a projektu pro každou z nich… je zjevný overkill. O této situaci se bude dále hovořit: několik takových mikroslužeb leží v jednom repozitáři projektu a uvolnění probíhá prostřednictvím jediného procesu v CI/CD.
Štítkování podle Git větve a Git tagu
Předpokládejme, že se používá nejrozšířenější strategie štítkování — tag-or-branch. Pro Git větve jsou obrazy štítkovány názvem větve, pro jednu větev v jeden okamžik existuje pouze jeden publikovaný obraz se jménem této větve. Pro Git tagy jsou obrazy štítkovány podle názvu tagu.
Při vytváření nového Git tagu — například při vydání nové verze — pro všechny obrazy projektu v Docker Registry bude vytvořen nový Docker tag:
-
myregistry.org/myproject/frontend:v1.1.10 -
myregistry.org/myproject/myservice1:v1.1.10 -
myregistry.org/myproject/myservice2:v1.1.10 -
myregistry.org/myproject/myservice3:v1.1.10 -
myregistry.org/myproject/myservice4:v1.1.10 -
myregistry.org/myproject/myservice5:v1.1.10 -
myregistry.org/myproject/database:v1.1.10
Tato nová jména obrazů jsou přes Helm šablony integrována do konfigurace Kubernetes. Při spuštění nasazení příkazem werf deploy dochází k aktualizaci pole obrázek v manifestech prostředků Kubernetes a restartu odpovídajících prostředků kvůli změněnému jménu obrazu.
Problém: v případě, že se skutečně obsah obrazu z předchozího nasazení (Git tagu) nezměnil, pouze jeho Docker tag, dojde k zbytečnému restartu této aplikace a tím pádem je možný určitý prostoj. Ačkoli nebyly žádné skutečné důvody pro provádění tohoto restartu.
V důsledku aktuálního schématu označování je nutné vytvořit několik samostatných Git repozitářů a vznáší se problém organizace nasazování těchto několika repozitářů. Celkově je takové schéma neúměrně složité a komplikované. Je lepší spojit více služeb do jednoho repozitáře a vytvořit takové Docker tagy, aby nedocházelo k zbytečným restartům.
Označování podle Git commitu
V werf je také přítomna strategie označování spojená s Git commity.
Git commit je identifikátor obsahu Git repozitáře a závisí na historii úprav souborů v Git repozitáři, proto se zdá logické použít jej k označování obrazů v Docker Registry.
Nicméně označování podle Git commitu má stejné nevýhody jako označování podle Git větví nebo Git tagů:
- Mohlo být vytvořeno prázdné commit, který nemění soubory, ale Docker tag obraz bude změněn.
- Mohlo být vytvořeno merge commit, který nemění soubory, ale Docker tag obraz bude změněn.
- Mohlo bylo vytvořeno commit, který mění soubory v Git, které nejsou importovány do obrazu, a Docker tag obraz bude opět změněn.
Označování podle jména Git větve neodráží verzi obrazu
Existuje také další problém spojený se strategií označování podle Git větví.
Označování podle jména větve funguje, dokud jsou commity této větve shromažďovány v chronologickém pořadí.
Pokud v aktuálním schématu uživatel spustí znovuvytvoření starého commitu spojeného s nějakou větví, werf přepíše obraz podle odpovídajícího Docker tagu nově sestavenou verzí obrazu pro starý commit. Deploymenty používající tento tag se od tohoto okamžiku riskují, že během restartování podů provedou pull jiné verze obrazu, což povede k tomu, že naše aplikace ztratí spojení s CI systémem a dojde k desynchronizaci.
Kromě toho, při sériových pushech do jedné větve s malým časovým odstupem mezi nimi, může být starý commit sestaven později než novější: stará verze obrazu přepíše novou podle tagu Git větve. Tyto problémy může vyřešit CI/CD systém (například v GitLab CI se pro sérii commitů spouští pipeline posledního). Avšak ne všechny systémy tuto funkci podporují a mělo by existovat spolehlivější způsob, jak předcházet takové základní problematice.
Co je to označování na základě obsahu?
Takže, co je to označování na základě obsahu — označování obrazů podle obsahu.
Pro vytvoření Docker tagů se používají nikoli primitiva Git (Git větev, Git tag…), ale kontrolní součet související s:
- obsahem obrazu. Identifikátor-tag obrazu odráží jeho obsah. Při sestavení nové verze se tento identifikátor nezmění, pokud se v obrazu nezměnily soubory;
- historie vytváření tohoto obrazu v Git. Obrazy spojené s různými Git větvemi a různou historií sestavení přes werf budou mít různé tagy-identifikátory.
Jako takový tag-identifikátor slouží tzv. podpis fází obrazu.
Každý obraz se skládá z řady fází: from, before-install, git-archive, install, imports-after-install, before-setup,… git-latest-patch atd. Každá fáze má identifikátor, který odráží její obsah, — podpis fáze (stage signature).
Finální obraz, který se skládá z těchto fází, je označen tzv. podpisem souboru těchto fází — stages signature, — který je obecný pro všechny fáze obrazu.
Každý obraz z konfigurace werf.yaml bude mít obecně svůj vlastní takový podpis a odpovídající Docker tag.
Podpis fází řeší všechny uvedené problémy:
- Je odolný vůči prázdným Git commitům.
- Je odolný vůči Git commitům, které mění soubory, které nejsou relevantní pro obraz.
- Nedochází k problému s přepisováním aktuální verze obrazu při restartování sestavení pro staré Git commity větve.
Nyní je to doporučená strategie označování a ve výchozím nastavení se používá v werf pro všechny CI systémy.
Jak zapnout a používat v werf
Odpovídající možnost byla přidána do příkazu werf publish: --tag-by-stages-signature=true|false
Ve CI systému se strategie označování určuje příkazem werf ci-env. Dříve se pro něj určoval parametr werf ci-env --tagging-strategy=tag-or-branch. Nyní, pokud zadáte werf ci-env --tagging-strategy=stages-signature nebo nezkontrolujete tuto možnost, werf ve výchozím nastavení použije strategii označování stages-signature. Příkaz werf ci-env automaticky nastaví potřebné příznaky pro příkaz werf build-and-publish (nebo werf publish), proto není třeba pro tyto příkazy uvádět žádné další možnosti.
Například příkaz:
werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-by-stages-signature… může vytvořit následující obrazy:
-
registry.hello.com/web/core/system/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d -
registry.hello.com/web/core/system/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6
Zde 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d — to je signatura fází obrazu backend, a f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 — signatura fází obrazu frontend.
Při použití speciálních funkcí werf_container_image a werf_container_env v šablonách Helm není třeba nic měnit: tyto funkce automaticky generují správná jména obrazů.
Příklad konfigurace v CI systému:
type multiwerf && source <(multiwerf use 1.1 beta)
type werf && source <(werf ci-env gitlab)
werf build-and-publish|deployVíce informací o nastavení je k dispozici v dokumentaci:
- ;
- ;
- .
Celkem
- Nová možnost
werf publish --tag-by-stages-signature=true|false. - Nová hodnota možnosti
werf ci-env --tagging-strategy=stages-signature|tag-or-branch(pokud není uvedeno, pak ve výchozím nastavení budestages-signature). - Pokud dříve byly použity možnosti označování podle Git commitů (
WERF_TAG_GIT_COMMITnebo možnostwerf publish --tag-git-commit COMMIT), je nutné přepnout na strategii označování stages-signature. - Nové projekty je lepší hned přepnout na nové schéma označování.
- Staré projekty při přechodu na werf 1.1 je vhodné přepnout na nové schéma označování, avšak staré tag-or-branch je stále podporováno.
Označování na základě obsahu řeší všechny v článku uvedené problémy:
- Odolnost názvu Docker tagu vůči prázdným Git commitům.
- Odolnost názvu Docker tagu vůči Git commitům, které mění pro obraz nerelevantní soubory.
- Nedochází k problému s přepisováním aktuální verze obrazu při restartování sestavení pro staré Git commity pro Git větve.
Používejte! A nezapomeňte se k nám podívat na , abyste vytvořili issue nebo našli již existující, přidali plus, vytvořili PR nebo jednoduše sledovali vývoj projektu.
P.S.
Přečtěte si také náš blog:
- «»
- «»
- «»;
- Cyklus poznámek o nových funkcích ve werf:
- «»;
- «»;
- «»;
- «».
Zdroj: habr.com
