Označevanje vsebine v zbiralniku werf: zakaj in kako deluje?

Označevanje vsebine v zbiralniku werf: zakaj in kako deluje?

werf — naš GitOps CLI alat za izgradnju i isporuku aplikacija u Kubernetes s otvorenim kodom. U izdanju v1.1 predstavljena je nova značajka u alatu za izgradnju: označavanje slika prema sadržaju ili označavanje zasnovano na sadržaju. Do sada je tipična shema označavanja u werf pretpostavljala označavanje Docker slika prema Git oznakama, Git granama ili Git commitovima. No, sve te sheme imaju nedostatke koji se potpuno rješavaju novom strategijom označavanja. Detalji o tome i zašto je to tako dobro — u nastavku.

Izdavanje skupa mikroservisa iz jednog Git repozitorija

Često se događa da je aplikacija razdvojena na više manje neovisnih servisa. Izdavanja tih servisa mogu se odvijati neovisno: u jednom trenutku može biti izdano jedan ili više servisa, dok ostali moraju nastaviti raditi bez ikakvih promjena. No, s obzirom na pohranu koda i upravljanje projektom, praktičnije je takve servise aplikacije držati u jedinstvenom repozitoriju.

Postoje situacije kada su servisi zaista neovisni i nisu povezani s jednom aplikacijom. U tom slučaju bit će smješteni u odvojenim projektima i njihovo će se izdavanje provoditi putem odvojenih CI/CD procesa u svakom projektu.

Međutim, u stvarnosti programeri često razdvajaju jedinstvenu aplikaciju na nekoliko mikroservisa, ali otvaranje svakog zasebnog repozitorija i projekta… — očiti je overkill. O ovoj situaciji bit će riječ dalje: nekoliko takvih mikroservisa nalazi se u jedinstvenom repozitoriju projekta, a izdanja se odvijaju putem jedinstvenog procesa u CI/CD.

Označavanje prema Git grani i Git oznaci

Pretpostavimo da se koristi najraširenija strategija označavanja — tag-or-branch. Za Git grane, slike se označavaju imenom grane, za jednu granu u jednom trenutku postoji samo jedna objavljena slika pod imenom te grane. Za Git oznake, slike se označavaju odgovarajuće imenom oznake.

Pri stvaranju nove Git oznake — na primjer, pri izlasku nove verzije — za sve slike projekta u Docker Registry će biti stvorena nova Docker oznaka:

  • 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

Ta nova imena slik prihajajo preko Helm predlog v konfiguracijo Kubernetes. Pri zagonu implementacije z ukazom werf deploy pride do posodobitve polja image v manifestih virov Kubernetes in ponovnem zagonu ustreznih virov zaradi spremenjenega imena slike.

Težava: v primeru, ko se dejansko od prejšnjega izpustitve (Git oznake) ni spremenila vsebina slike, temveč le njen Docker oznaka, pride do odvečnega ponovnega zagona te aplikacije in zato je lahko prisotna neka preprosta. Čeprav ni bilo nobenih pravih razlogov za izvedbo tega ponovnega zagona.

Kot posledica trenutne sheme označevanja je treba ustvariti več ločenih Git repozitorijev in se pojavi problem organizacije izpustov teh več repozitorijev. Na splošno se ta shema izkaže za prenatrpano in zapleteno. Bolje je povezati veliko storitev v en sam repozitorij in ustvariti takšne Docker oznake, da ni odvečnih ponovnih zagonov.

Označevanje glede na Git commit

V werf je prav tako prisotna strategija označevanja, povezana z Git commit.

Git commit je identifikator vsebine Git repozitorija in je odvisen od zgodovine sprememb datotek v Git repozitoriju, zato se zdi smiselno, da ga uporabimo za označevanje slik v Docker Registry.

Vendar pa označevanje glede na Git commit ima enake pomanjkljivosti kot označevanje glede na Git veje ali Git oznake:

  • Lahko je bil ustvarjen prazen commit, ki ne spreminja datotek, medtem ko bo Docker oznaka slike spremenjena.
  • Lahko je bil ustvarjen merge commit, ki ne spreminja datotek, medtem ko bo Docker oznaka slike spremenjena.
  • Lahko je bil ustvarjen commit, ki spreminja tiste datoteke v Git, ki niso vključene v sliko, medtem ko bo Docker oznaka slike ponovno spremenjena.

Označevanje po imenu Git veje ne odraža različice slike

Obstaja še en problem, povezan s strategijo označevanja po Git vejah.

Označevanje po imenu veje deluje, dokler se commiti te veje zaporedoma zbirajo v kronološkem vrstnem redu.

Če trenutni uporabnik v shemi naloži ponovno gradnjo starega komita, povezanega z nekom veščino, bo werf prepisal sliko s pripadajočo Docker oznako z novo različico slike za star komit. Uporabniki te oznake za uvedbo bodo od tega trenutka naprej tvegali, da bodo med ponovnim zagonjem podov prenesli drugo različico slike, kar bo povzročilo, da bo naša aplikacija izgubila povezavo s CI-sistemom in se razdružila.

Poleg tega, pri zaporednih push različnih komitov v eno vejo z malo časa med njimi, lahko starejši komit zgradi kasneje kot novejši: starejša različica slike lahko prepiše novejšo pod oznako Git-veje. Takšne težave lahko reši CI/CD sistem (na primer, v GitLab CI se za serijo komitov sproži pipeline za zadnji). Vendar to ne podpira vsak sistem, zato bi moral obstajati bolj zanesljiv način za preprečevanje te temeljne težave.

Kaj je označevanje na podlagi vsebine?

Torej, kaj sploh je označevanje na podlagi vsebine — označevanje slik glede na vsebino.

Za ustvarjanje Docker oznak se ne uporabljajo primitivi Gita (Git-vej, Git-oznaka...), ampak kontrolna suma, povezana z:

  • vsebino slike. Identifikator-oznaka slike odraža njeno vsebino. Pri ustvarjanju nove različice ta identifikator ne bo spremenjen, če v sliki niso bile spremenjene datoteke;
  • zgodovino ustvarjanja te slike v Gitu. Obrazi, povezani z različnimi Git-vejami in različno zgodovino gradnje preko werf, bodo imeli različne oznake-identifikatorje.

Kot tak identifikator-oznaka deluje tako imenovana podpis stopenj slike.

Vsaka slika se sestoji iz niza stopenj: from, before-install, git-archive, install, imports-after-install, before-setup,… git-latest-patch itd. Vsaka stopnja ima identifikator, ki odraža njeno vsebino, — podpis stopnje (stage signature).

Končna slika, ki je sestavljena iz teh stopenj, je označena s tako imenovanim podpisom niza teh stopenj — stages signature, — ki je poenostavljajoč za vse stopnje slike.

Vsaka slika iz konfiguracije werf.yaml bo v splošnem imela svoj tak podpis in posledično Docker-oznako.

Podpis stopenj rešuje vse navedene težave:

  • Ustvarja se zavarovan proti praznim Git-komitom.
  • Ustvarja se zavarovan proti Git-komitom, ki spreminjajo datoteke, ki niso relevantne za sliko.
  • Ne povzroča težav pri prepisovanju aktualne različice slike pri ponovnem zagonu gradnje za stare Git-komite veje.

Sedaj je to priporočena strategija označevanja in se privzeto uporablja v werf za vse CI-sisteme.

Kako omogočiti in uporabljati v werf

Ustrezna možnost je bila dodana ekipi werf publish: --tag-by-stages-signature=true|false

V CI-sistemu strategijo označevanja določa ukaz werf ci-env. Prej je bil za to določen parameter werf ci-env --tagging-strategy=tag-or-branch. Zdaj, če navedete werf ci-env --tagging-strategy=stages-signature ali ne navedete te možnosti, bo werf privzeto uporabil strategijo označevanja stages-signature. Ukaz werf ci-env samodejno nastavi potrebne zastavice za ukaz werf build-and-publish (ali werf publish), zato dodatnih možnosti za te ukaze ni treba navajati.

Na primer, ukaz:

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

… lahko ustvari naslednje slike:

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

Tukaj 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d — to je podpis faze slike backend, a f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 — podpis faze slike frontend.

Pri uporabi posebnih funkcij werf_container_image in werf_container_env v predlogah Helm ni treba ničesar spreminjati: te funkcije bodo samodejno generirale pravilna imena slik.

Primer konfiguracije v CI-sistemu:

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

Več informacij o nastavitvi je na voljo v dokumentaciji:

Ukupno

  • Nova možnost werf publish --tag-by-stages-signature=true|false.
  • Nova vrednost možnosti werf ci-env --tagging-strategy=stages-signature|tag-or-branch (če ne navedete, bo privzeto stages-signature).
  • Če so prej uporabljali možnosti označevanja po Git-commitih (WERF_TAG_GIT_COMMIT ali možnost werf publish --tag-git-commit COMMIT), je nujno preklopiti na strategijo označevanja stages-signature.
  • Nove projekte je najbolje takoj preklopiti na novo shemo označevanja.
  • Stare projekte je pri prehodu na werf 1.1 zaželeno preklopiti na novo shemo označevanja, vendar stara tag-or-branch še vedno ostaja podprta.

Označevanje, ki temelji na vsebini, rešuje vse v članku obravnavane težave:

  • Odpornost imena Docker-oznake na prazne Git-commite.
  • Odpornost imena Docker-oznake na Git-commite, ki spreminjajo nerelevantne datoteke za sliko.
  • Ne vodi do problema s prepisovanjem aktualne verzije slike pri ponovnem zagonu graditev za stare Git-commit-e za Git-vejice.

Uživajte! In ne pozabite obiskati nas na GitHub, da ustvarite težavo ali poiščete že obstoječo, ji dodate glas, ustvarite PR ali samo opazujete razvoj projekta.

P.S.

Preberite tudi na našem blogu:

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster