Innholdsbasert tagging i werfbyggeren: hvorfor og hvordan fungerer det?

Innholdsbasert tagging i werfbyggeren: hvorfor og hvordan fungerer det?

werf er vårt åpen kildekode GitOps CLI-verktøy for å bygge og levere applikasjoner til Kubernetes. I utgivelse v1.1 en ny funksjon ble introdusert i bildesamleren: merking av bilder etter innhold eller innholdsbasert tagging. Til nå har det typiske merkeskjemaet i werf involvert merking av Docker-bilder med Git-tag, Git-gren eller Git-commit. Men alle disse ordningene har ulemper som er fullstendig løst av den nye taggestrategien. Detaljer om det og hvorfor det er så bra er under snittet.

Utrulling av et sett med mikrotjenester fra ett Git-depot

En situasjon oppstår ofte når en søknad er delt opp i mange mer eller mindre uavhengige tjenester. Utgivelser av disse tjenestene kan skje uavhengig: én eller flere tjenester kan frigis om gangen, mens resten må fortsette å fungere uten endringer. Men med tanke på kodelagring og prosjektstyring er det mer praktisk å holde slike applikasjonstjenester i ett enkelt depot.

Det er situasjoner når tjenester er virkelig uavhengige og ikke knyttet til en enkelt applikasjon. I dette tilfellet vil de være lokalisert i separate prosjekter og utgivelsen vil bli utført gjennom separate CI/CD-prosesser i hvert av prosjektene.

Men i virkeligheten deler utviklere ofte en enkelt applikasjon i flere mikrotjenester, men å lage et separat depot og prosjekt for hver ... er en klar overkill. Det er denne situasjonen som vil bli diskutert videre: flere slike mikrotjenester er plassert i et enkelt prosjektlager og utgivelser skjer gjennom en enkelt prosess i CI/CD.

Tagging etter Git-gren og Git-tag

La oss si at den vanligste taggestrategien brukes - tag-eller-gren. For Git-grener er bilder merket med navnet på grenen, for én gren om gangen er det bare ett publisert bilde med navnet på den grenen. For Git-tagger merkes bilder i henhold til tag-navnet.

Når en ny Git-tag opprettes – for eksempel når en ny versjon slippes – vil en ny Docker-tag bli opprettet for alle prosjektbilder i Docker-registeret:

  • 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 bildenavnene sendes gjennom Helm-maler til Kubernetes-konfigurasjonen. Når du starter distribusjonen med kommandoen werf deploy feltet blir oppdatert image i Kubernetes ressursmanifester og omstart av de tilsvarende ressursene på grunn av endret bildenavn.

problem: i tilfelle hvor innholdet i bildet faktisk ikke har endret seg siden forrige utrulling (Git-tag), men bare Docker-taggen, skjer dette ekstra omstart av denne applikasjonen og følgelig noe nedetid er mulig. Selv om det ikke var noen reell grunn til å utføre denne omstarten.

Som et resultat, med den nåværende tagging-ordningen, er det nødvendig å inngjerde flere separate Git-repositorier, og problemet oppstår med å organisere utrullingen av disse flere repositoriene. Generelt viser en slik ordning seg å være overbelastet og kompleks. Det er bedre å kombinere mange tjenester til et enkelt depot og lage Docker-tagger slik at det ikke er unødvendige omstarter.

Tagging av Git commit

werf har også en tagging-strategi knyttet til Git commits.

Git-commit er en identifikator for innholdet i et Git-depot og avhenger av redigeringshistorikken til filer i Git-depotet, så det virker logisk å bruke det til å merke bilder i Docker-registeret.

Imidlertid har tagging av Git commit de samme ulempene som tagging av Git-grener eller Git-tagger:

  • En tom commit kan opprettes som ikke endrer noen filer, men Docker-koden til bildet vil bli endret.
  • En merge commit kan opprettes som ikke endrer filene, men Docker-taggen til bildet vil bli endret.
  • En commit kan gjøres som endrer de filene i Git som ikke er importert til bildet, og Docker-taggen til bildet vil bli endret igjen.

Merking av Git-grennavn gjenspeiler ikke bildeversjonen

Det er et annet problem knyttet til tagging-strategien for Git-grener.

Merking etter filialnavn fungerer så lenge forpliktelsene på den grenen samles sekvensielt i kronologisk rekkefølge.

Hvis brukeren i det gjeldende opplegget begynner å gjenoppbygge en gammel commit knyttet til en bestemt gren, vil werf skrive om bildet ved å bruke den tilsvarende Docker-taggen med en nybygd versjon av bildet for den gamle commit. Implementeringer som bruker denne taggen fra nå av risikerer å trekke en annen versjon av bildet ved omstart av pods, som et resultat av at applikasjonen vår vil miste forbindelsen med CI-systemet og bli desynkronisert.

I tillegg, med påfølgende push inn i en gren med kort tid mellom dem, kan den gamle commit kompileres senere enn den nyere: den gamle versjonen av bildet vil overskrive den nye ved å bruke Git branch-taggen. Slike problemer kan løses med et CI/CD-system (for eksempel i GitLab CI lanseres pipelinen til sistnevnte for en rekke forpliktelser). Imidlertid støtter ikke alle systemer dette, og det må finnes en mer pålitelig måte å forhindre et så grunnleggende problem på.

Hva er innholdsbasert tagging?

Så, hva er innholdsbasert tagging - tagging av bilder etter innhold.

For å lage Docker-tagger er det ikke Git-primitiver (Git-gren, Git-tag...) som brukes, men en kontrollsum assosiert med:

  • innholdet i bildet. Bilde-ID-taggen gjenspeiler innholdet. Når du bygger en ny versjon, vil ikke denne identifikatoren endres hvis filene i bildet ikke er endret;
  • historien om å lage dette bildet i Git. Bilder assosiert med forskjellige Git-grener og ulik byggehistorikk via werf vil ha forskjellige ID-tagger.

En slik identifikasjonsbrikke er den såkalte bildescenesignatur.

Hvert bilde består av et sett med stadier: from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patch etc. Hvert trinn har en identifikator som gjenspeiler innholdet − scenesignatur (scenesignatur).

Det endelige bildet, som består av disse stadiene, er merket med den såkalte signaturen til settet med disse stadiene - etapper signatur, - som er generaliserende for alle stadier av bildet.

For hvert bilde fra konfigurasjonen werf.yaml i det generelle tilfellet vil det være sin egen signatur og følgelig en Docker-tag.

Scenesignaturen løser alle disse problemene:

  • Motstandsdyktig mot tomme Git-commits.
  • Resistant to Git commits som endrer filer som ikke er relevante for bildet.
  • Fører ikke til problemet med å overhale den nåværende versjonen av bildet ved omstart av builds for gamle Git-commits av en gren.

Dette er nå den anbefalte taggingstrategien og er standard i werf for alle CI-systemer.

Hvordan aktivere og bruke i werf

Kommandoen har nå et tilsvarende alternativ werf publish: --tag-by-stages-signature=true|false

I et CI-system er taggestrategien spesifisert av kommandoen werf ci-env. Tidligere ble parameteren definert for den werf ci-env --tagging-strategy=tag-or-branch. Nå, hvis du spesifiserer werf ci-env --tagging-strategy=stages-signature eller ikke spesifiser dette alternativet, vil werf bruke tagging-strategien som standard stages-signature. Team werf ci-env vil automatisk sette de nødvendige flaggene for kommandoen werf build-and-publish (eller werf publish), så ingen tilleggsalternativer trenger å spesifiseres for disse kommandoene.

For eksempel kommandoen:

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

...kan lage følgende bilder:

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

Her 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d er en signatur av stadiene i bildet backendOg f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - signatur av bildestadier frontend.

Ved bruk av spesialfunksjoner werf_container_image и werf_container_env Det er ikke nødvendig å endre noe i Helm-malene: disse funksjonene vil automatisk generere de riktige bildenavnene.

Eksempel på konfigurasjon i et CI-system:

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

Mer informasjon om konfigurasjon er tilgjengelig i dokumentasjonen:

Totalt

  • Nytt alternativ werf publish --tag-by-stages-signature=true|false.
  • Ny opsjonsverdi werf ci-env --tagging-strategy=stages-signature|tag-or-branch (hvis ikke spesifisert, vil standarden være stages-signature).
  • Hvis du tidligere har brukt tagging-alternativene for Git commits (WERF_TAG_GIT_COMMIT eller alternativ werf publish --tag-git-commit COMMIT), så pass på å bytte til taggestrategien etapper-signatur.
  • Det er bedre å umiddelbart bytte nye prosjekter til den nye merkeordningen.
  • Ved overføring til werf 1.1 er det tilrådelig å bytte gamle prosjekter til det nye merkeordningen, men det gamle tag-eller-gren er fortsatt støttet.

Innholdsbasert tagging løser alle problemene som dekkes i artikkelen:

  • Docker tag navn motstand mot tomme Git commits.
  • Motstand av Docker-tag-navnet til Git-forpliktelser som endrer filer som er irrelevante for bildet.
  • Fører ikke til problemet med å overhale den nåværende versjonen av bildet ved omstart av bygg for gamle Git-commits for Git-grener.

Bruk det! Og ikke glem å besøke oss kl GitHubfor å opprette et problem eller finne et eksisterende, legge til et pluss, lage en PR eller bare se utviklingen av prosjektet.

PS

Les også på bloggen vår:

Kilde: www.habr.com

Legg til en kommentar