Etichetarea bazată pe conținut în colectorul werf: de ce și cum funcționează?

Etichetarea bazată pe conținut în colectorul werf: de ce și cum funcționează?

werf este utilitarul nostru open source GitOps CLI pentru construirea și livrarea de aplicații către Kubernetes. ÎN lansarea v1.1 a fost introdusă o nouă caracteristică în colectorul de imagini: etichetarea imaginilor după conținut sau etichetarea bazată pe conținut. Până acum, schema de etichetare tipică în werf implica etichetarea imaginilor Docker după eticheta Git, ramură Git sau commit Git. Dar toate aceste scheme au dezavantaje care sunt rezolvate complet prin noua strategie de etichetare. Detalii despre el și de ce este atât de bun sunt sub tăietură.

Lansarea unui set de microservicii dintr-un singur depozit Git

Adesea apare o situație când o aplicație este împărțită în multe servicii mai mult sau mai puțin independente. Lansările acestor servicii pot avea loc independent: unul sau mai multe servicii pot fi lansate simultan, în timp ce restul trebuie să continue să funcționeze fără nicio modificare. Dar din punctul de vedere al stocării codului și al managementului de proiect, este mai convenabil să păstrezi astfel de servicii de aplicații într-un singur depozit.

Există situații în care serviciile sunt cu adevărat independente și nu sunt asociate cu o singură aplicație. În acest caz, acestea vor fi amplasate în proiecte separate, iar lansarea lor va fi realizată prin procese CI/CD separate în fiecare dintre proiecte.

Cu toate acestea, în realitate, dezvoltatorii împart adesea o singură aplicație în mai multe microservicii, dar crearea unui depozit și a unui proiect separat pentru fiecare... este o exagerare clară. Această situație va fi discutată în continuare: mai multe astfel de microservicii sunt situate într-un singur depozit de proiect și lansările au loc printr-un singur proces în CI/CD.

Etichetarea după ramura Git și eticheta Git

Să presupunem că este utilizată cea mai comună strategie de etichetare - etichetă sau ramură. Pentru ramurile Git, imaginile sunt etichetate cu numele ramurii, pentru o ramură la un moment dat există o singură imagine publicată cu numele acelei ramuri. Pentru etichetele Git, imaginile sunt etichetate în funcție de numele etichetei.

Când este creată o nouă etichetă Git, de exemplu, când este lansată o nouă versiune, o nouă etichetă Docker va fi creată pentru toate imaginile proiectului din Registrul Docker:

  • 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

Aceste noi nume de imagini sunt transmise prin șabloanele Helm către configurația Kubernetes. La începerea implementării cu comanda werf deploy câmpul este în curs de actualizare image în manifestările de resurse Kubernetes și repornirea resurselor corespunzătoare din cauza numelui modificat al imaginii.

problemă: în cazul în care, de fapt, conținutul imaginii nu s-a schimbat de la lansarea anterioară (eticheta Git), ci doar eticheta Docker, acest lucru se întâmplă exces repornirea acestei aplicații și, în consecință, este posibilă o perioadă de nefuncționare. Deși nu a existat niciun motiv real pentru a efectua această repornire.

Ca urmare, cu schema actuală de etichetare, este necesar să se îngrădească mai multe depozite Git separate și apare problema organizării lansării acestor mai multe depozite. În general, o astfel de schemă se dovedește a fi supraîncărcată și complexă. Este mai bine să combinați multe servicii într-un singur depozit și să creați etichete Docker, astfel încât să nu existe reporniri inutile.

Etichetare prin Git commit

werf are, de asemenea, o strategie de etichetare asociată cu comiterile Git.

Git-commit este un identificator pentru conținutul unui depozit Git și depinde de istoricul de editare al fișierelor din depozitul Git, așa că pare logic să îl folosiți pentru etichetarea imaginilor în Registrul Docker.

Cu toate acestea, etichetarea prin Git commit are aceleași dezavantaje ca etichetarea prin ramuri Git sau etichetele Git:

  • Ar putea fi creat un commit gol care nu modifică niciun fișier, dar eticheta Docker a imaginii va fi schimbată.
  • Ar putea fi creat un commit de îmbinare care nu modifică fișierele, dar eticheta Docker a imaginii va fi schimbată.
  • S-ar putea face un commit care modifică acele fișiere din Git care nu sunt importate în imagine, iar eticheta Docker a imaginii va fi schimbată din nou.

Etichetarea numelui sucursalei Git nu reflectă versiunea imaginii

Există o altă problemă asociată cu strategia de etichetare pentru ramurile Git.

Etichetarea după numele de ramură funcționează atâta timp cât commit-urile de pe acea ramură sunt colectate secvenţial în ordine cronologică.

Dacă în schema curentă utilizatorul începe să reconstruiască un vechi commit asociat cu o anumită ramură, atunci werf va rescrie imaginea folosind eticheta Docker corespunzătoare cu o versiune nou construită a imaginii pentru vechiul commit. Implementările care utilizează această etichetă de acum înainte riscă să tragă o versiune diferită a imaginii la repornirea podurilor, drept urmare aplicația noastră va pierde conexiunea cu sistemul CI și va deveni desincronizată.

În plus, cu împingeri succesive într-o ramură cu o perioadă scurtă de timp între ele, vechiul commit poate fi compilat mai târziu decât cel mai nou: versiunea veche a imaginii o va suprascrie pe cea nouă utilizând eticheta Git branch. Astfel de probleme pot fi rezolvate printr-un sistem CI/CD (de exemplu, în GitLab CI, pipeline-ul acestuia din urmă este lansat pentru o serie de comiteri). Cu toate acestea, nu toate sistemele acceptă acest lucru și trebuie să existe o modalitate mai fiabilă de a preveni o astfel de problemă fundamentală.

Ce este etichetarea bazată pe conținut?

Deci, ce este etichetarea bazată pe conținut - etichetarea imaginilor după conținut.

Pentru a crea etichete Docker, nu sunt folosite primitivele Git (ramură Git, etichetă Git...), ci o sumă de control asociată cu:

  • continutul imaginii. Eticheta ID imagine reflectă conținutul acesteia. La construirea unei noi versiuni, acest identificator nu se va schimba dacă fișierele din imagine nu s-au schimbat;
  • istoricul creării acestei imagini în Git. Imaginile asociate cu diferite ramuri Git și diferite istorice de construcție prin werf vor avea etichete de identificare diferite.

O astfel de etichetă de identificare este așa-numita semnătura etapă a imaginii.

Fiecare imagine constă dintr-un set de etape: from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patch etc. Fiecare etapă are un identificator care reflectă conținutul său − semnătură de scenă (semnătură de scenă).

Imaginea finală, constând din aceste etape, este etichetată cu așa-numita semnătură a setului acestor etape - semnătura etapelor, - care este generalizant pentru toate etapele imaginii.

Pentru fiecare imagine din configurație werf.yaml în cazul general, va exista propria semnătură și, în consecință, o etichetă Docker.

Semnătura scenei rezolvă toate aceste probleme:

  • Rezistent la comiterile Git goale.
  • Rezistent la Git comite care modifică fișierele care nu sunt relevante pentru imagine.
  • Nu duce la problema revizuirii versiunii curente a imaginii la repornirea build-urilor pentru vechile comiteri Git ale unei ramuri.

Aceasta este acum strategia de etichetare recomandată și este implicită în werf pentru toate sistemele CI.

Cum să activați și să utilizați în werf

Comanda are acum o opțiune corespunzătoare werf publish: --tag-by-stages-signature=true|false

Într-un sistem CI, strategia de etichetare este specificată de comandă werf ci-env. Anterior, parametrul a fost definit pentru acesta werf ci-env --tagging-strategy=tag-or-branch. Acum, dacă specificați werf ci-env --tagging-strategy=stages-signature sau nu specificați această opțiune, werf va folosi strategia de etichetare în mod implicit stages-signature. Echipă werf ci-env va seta automat steagurile necesare pentru comandă werf build-and-publish (Sau, werf publish), deci nu trebuie specificate opțiuni suplimentare pentru aceste comenzi.

De exemplu, comanda:

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

...poate crea următoarele imagini:

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

Aici 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d este o semnătură a etapelor imaginii backendȘi f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - semnătura etapelor de imagine frontend.

Când utilizați funcții speciale werf_container_image и werf_container_env Nu este nevoie să schimbați nimic în șabloanele Helm: aceste funcții vor genera automat numele corecte de imagine.

Exemplu de configurare într-un sistem CI:

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

Mai multe informații despre configurare sunt disponibile în documentație:

În total

  • Opțiune nouă werf publish --tag-by-stages-signature=true|false.
  • Noua valoare a optiunii werf ci-env --tagging-strategy=stages-signature|tag-or-branch (dacă nu este specificat, implicit va fi stages-signature).
  • Dacă ați folosit anterior opțiunile de etichetare pentru comiterile Git (WERF_TAG_GIT_COMMIT sau opțiune werf publish --tag-git-commit COMMIT), apoi asigurați-vă că treceți la strategia de etichetare etape-semnătură.
  • Este mai bine să comutați imediat proiectele noi la noua schemă de etichetare.
  • Când transferați la werf 1.1, este recomandabil să treceți proiectele vechi la noua schemă de etichetare, dar vechea etichetă sau ramură este încă susținută.

Etichetarea bazată pe conținut rezolvă toate problemele abordate în articol:

  • Rezistența numelui etichetei Docker la comiterile Git goale.
  • Reziliența numelui etichetei Docker la comiterea Git care modifică fișierele irelevante pentru imagine.
  • Nu duce la problema revizuirii versiunii curente a imaginii la repornirea build-urilor pentru vechile comiteri Git pentru ramurile Git.

Foloseste-l! Și nu uitați să ne vizitați la GitHubpentru a crea o problemă sau a găsi una existentă, a adăuga un plus, a crea un PR sau pur și simplu a urmări dezvoltarea proiectului.

PS

Citește și pe blogul nostru:

Sursa: www.habr.com

Adauga un comentariu