Indholdsbaseret tagging i werf-builderen: hvorfor og hvordan fungerer det?

Indholdsbaseret tagging i werf-builderen: hvorfor og hvordan fungerer det?

werf er vores open source GitOps CLI-værktøj til at bygge og levere applikationer til Kubernetes. I udgivelse v1.1 en ny funktion blev introduceret i billedsamleren: tagging af billeder efter indhold eller indholdsbaseret tagging. Indtil nu har det typiske tagging-skema i werf involveret tagging af Docker-billeder med Git tag, Git branch eller Git commit. Men alle disse ordninger har ulemper, som er fuldstændig løst af den nye tagging-strategi. Detaljer om det og hvorfor det er så godt er under snittet.

Udrulning af et sæt mikrotjenester fra ét Git-lager

En situation opstår ofte, når en ansøgning er opdelt i mange mere eller mindre selvstændige tjenester. Frigivelser af disse tjenester kan ske uafhængigt: En eller flere tjenester kan frigives ad gangen, mens resten skal fortsætte med at fungere uden ændringer. Men fra synspunktet om kodelagring og projektstyring er det mere bekvemt at opbevare sådanne applikationstjenester i et enkelt lager.

Der er situationer, hvor tjenester er virkelig uafhængige og ikke er forbundet med en enkelt applikation. I dette tilfælde vil de blive placeret i separate projekter, og deres frigivelse vil blive udført gennem separate CI/CD-processer i hvert af projekterne.

Men i virkeligheden opdeler udviklere ofte en enkelt applikation i flere mikrotjenester, men at skabe et separat lager og projekt for hver ... er en klar overkill. Det er denne situation, der vil blive diskuteret yderligere: flere sådanne mikrotjenester er placeret i et enkelt projektlager, og udgivelser sker gennem en enkelt proces i CI/CD.

Tagging efter Git branch og Git tag

Lad os sige, at den mest almindelige tagging-strategi bruges - tag-eller-gren. For Git-grene er billeder tagget med navnet på grenen, for én gren ad gangen er der kun ét offentliggjort billede med navnet på den gren. For Git-tags er billeder tagget i henhold til tagnavnet.

Når et nyt Git-tag er oprettet - for eksempel når en ny version frigives - oprettes et nyt Docker-tag for alle projektbilleder i Docker Registry:

  • 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

Disse nye billednavne sendes gennem Helm-skabeloner til Kubernetes-konfigurationen. Når du starter implementeringen med kommandoen werf deploy feltet bliver opdateret image i Kubernetes ressourcemanifester og genstart af de tilsvarende ressourcer på grund af det ændrede billednavn.

problem: i det tilfælde, hvor indholdet af billedet faktisk ikke er ændret siden den forrige udrulning (Git-tag), men kun dets Docker-tag, sker dette ekstra genstart af denne applikation, og derfor er der mulighed for en vis nedetid. Selvom der ikke var nogen reel grund til at udføre denne genstart.

Som et resultat er det med den nuværende tagging-ordning nødvendigt at indhegne flere separate Git-depoter, og problemet opstår med at organisere udrulningen af ​​disse flere repositories. Generelt viser en sådan ordning sig at være overbelastet og kompleks. Det er bedre at kombinere mange tjenester i et enkelt lager og oprette Docker-tags, så der ikke er unødvendige genstarter.

Tagging af Git commit

werf har også en tagging-strategi forbundet med Git commits.

Git-commit er en identifikator for indholdet af et Git-lager og afhænger af redigeringshistorikken for filer i Git-lageret, så det virker logisk at bruge det til at tagge billeder i Docker-registret.

Tagging af Git commit har dog de samme ulemper som tagging af Git branches eller Git tags:

  • Der kunne oprettes en tom commit, der ikke ændrer nogen filer, men Docker-tagget for billedet vil blive ændret.
  • En merge commit kunne oprettes, som ikke ændrer filerne, men Docker-tagget for billedet vil blive ændret.
  • En commit kan laves, der ændrer de filer i Git, der ikke er importeret til billedet, og Docker-tagget for billedet vil blive ændret igen.

Tagging af Git-grenens navn afspejler ikke billedversionen

Der er et andet problem forbundet med tagging-strategien for Git-grene.

Tagging efter filialnavn fungerer, så længe commits på den filial er indsamlet sekventielt i kronologisk rækkefølge.

Hvis brugeren i det nuværende skema begynder at genopbygge en gammel commit, der er knyttet til en bestemt branche, så vil werf omskrive billedet ved hjælp af det tilsvarende Docker tag med en nybygget version af billedet til den gamle commit. Implementeringer, der bruger dette tag fra nu af, risikerer at trække en anden version af billedet, når du genstarter pods, som følge heraf vil vores applikation miste forbindelsen til CI-systemet og blive desynkroniseret.

Derudover kan den gamle commit blive kompileret senere end den nyere med successive push ind i én gren med et kort tidsrum mellem dem: den gamle version af billedet vil overskrive den nye ved at bruge Git branch-tagget. Sådanne problemer kan løses af et CI/CD-system (for eksempel i GitLab CI lanceres pipelinen af ​​sidstnævnte for en række commits). Det er dog ikke alle systemer, der understøtter dette, og der skal være en mere pålidelig måde at forhindre et så grundlæggende problem på.

Hvad er indholdsbaseret tagging?

Så hvad er indholdsbaseret tagging - tagging af billeder efter indhold.

For at oprette Docker-tags er det ikke Git-primitiver (Git-gren, Git-tag...), der bruges, men en kontrolsum forbundet med:

  • billedets indhold. Billed-id-tagget afspejler dets indhold. Når du bygger en ny version, ændres denne identifikator ikke, hvis filerne i billedet ikke er ændret;
  • historien om at skabe dette billede i Git. Billeder forbundet med forskellige Git-grene og forskellig byggehistorik via werf vil have forskellige ID-tags.

Et sådant identifikationsmærke er det såkaldte billedscenesignatur.

Hvert billede består af et sæt trin: from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patch etc. Hvert trin har en identifikator, der afspejler dets indhold − scenesignatur (scenesignatur).

Det endelige billede, der består af disse stadier, er mærket med den såkaldte signatur af sættet af disse stadier - etaper signatur, - hvilket er generaliserende for alle stadier af billedet.

For hvert billede fra konfigurationen werf.yaml i det generelle tilfælde vil der være sin egen signatur og følgelig et Docker-tag.

Scenesignaturen løser alle disse problemer:

  • Modstandsdygtig over for tomme Git-commits.
  • Resistant to Git commits, der ændrer filer, der ikke er relevante for billedet.
  • Fører ikke til problemet med at revidere den nuværende version af billedet, når du genstarter builds for gamle Git-commits af en filial.

Dette er nu den anbefalede tagging-strategi og er standard i werf for alle CI-systemer.

Sådan aktiveres og bruges i werf

Kommandoen har nu en tilsvarende mulighed werf publish: --tag-by-stages-signature=true|false

I et CI-system er tagging-strategien specificeret af kommandoen werf ci-env. Tidligere var parameteren defineret for den werf ci-env --tagging-strategy=tag-or-branch. Nu, hvis du specificerer werf ci-env --tagging-strategy=stages-signature eller undlad at specificere denne mulighed, vil werf bruge tagging-strategien som standard stages-signature. Hold werf ci-env vil automatisk indstille de nødvendige flag for kommandoen werf build-and-publish (eller werf publish), så der skal ikke angives yderligere indstillinger for disse kommandoer.

For eksempel kommandoen:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-by-stages-signature

...kan oprette følgende billeder:

  • registry.hello.com/web/core/system/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
  • registry.hello.com/web/core/system/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6

Her 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d er en signatur af billedets stadier backendOg f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - signatur af billedstadier frontend.

Ved brug af specialfunktioner werf_container_image и werf_container_env Der er ingen grund til at ændre noget i Helm-skabelonerne: disse funktioner genererer automatisk de korrekte billednavne.

Eksempel på konfiguration i et CI-system:

type multiwerf && source <(multiwerf use 1.1 beta)
type werf && source <(werf ci-env gitlab)
werf build-and-publish|deploy

Yderligere information om konfiguration er tilgængelig i dokumentationen:

I alt

  • Ny mulighed werf publish --tag-by-stages-signature=true|false.
  • Ny option værdi werf ci-env --tagging-strategy=stages-signature|tag-or-branch (hvis ikke angivet, vil standarden være stages-signature).
  • Hvis du tidligere har brugt tagging-mulighederne for Git commits (WERF_TAG_GIT_COMMIT eller mulighed werf publish --tag-git-commit COMMIT), så sørg for at skifte til tagging-strategien etaper-signatur.
  • Det er bedre straks at skifte nye projekter til den nye tagging-ordning.
  • Ved overførsel til werf 1.1 tilrådes det at skifte gamle projekter til den nye mærkningsordning, men den gamle tag-eller-gren er stadig understøttet.

Indholdsbaseret tagging løser alle de problemer, der er dækket i artiklen:

  • Docker tag navn modstand mod tomme Git commits.
  • Modstandsdygtighed af Docker-tagnavnet til Git-commits, der ændrer filer, der er irrelevante for billedet.
  • Fører ikke til problemet med at revidere den nuværende version af billedet ved genstart af builds for gamle Git-commits til Git-grene.

Brug det! Og glem ikke at besøge os kl GitHubat oprette et problem eller finde et eksisterende, tilføje et plus, oprette en PR eller blot se udviklingen af ​​projektet.

PS

Læs også på vores blog:

Kilde: www.habr.com

Tilføj en kommentar