Lansarea werf 1.1: îmbunătățiri în constructor astăzi și planuri de viitor

Lansarea werf 1.1: îmbunătățiri în constructor astăzi și planuri de viitor

werf — instrumentul nostru CLI GitOps cu cod deschis pentru construcția și livrarea aplicațiilor în Kubernetes. Așa cum am promis, lansarea versiunii v1.0 a marcat începutul adăugării de noi funcționalități în werf și revizuirii abordărilor folosite. Suntem acum încântați să prezentăm versiunea v1.1, care reprezintă un pas important în dezvoltare și o bază pentru viitor. builder-ului werf. Versiunea este disponibilă în prezent în canalul 1.1 ea.

Fundamentul versiunii este noua arhitectură a stocării etapelor și optimizarea funcționării ambelor builder-e (pentru Stapel și Dockerfile). Noua arhitectură de stocare deschide posibilități pentru implementarea construcțiilor distribuite de pe mai multe gazde și construcțiilor paralele pe o singură gazdă.

Optimizarea funcționării include eliminarea calculelor inutile în etapa de calculare a semnăturilor etapelor și modificarea mecanismelor de calculare a sumelor de control ale fișierelor pentru o eficiență mai mare. Această optimizare reduce timpul mediu de construcție al proiectului folosind werf. Iar construcțiile goale, când toate etapele există în cache stages-storage, sunt acum cu adevărat rapide. În cele mai multe cazuri, reluarea construcției va dura mai puțin de 1 secundă! Acest lucru se aplică și procedurilor de verificare a etapelor în timpul lucrului echipelor werf deploy și werf run.

De asemenea, în această versiune a fost introdusă o strategie de etichetare a imaginilor în funcție de conținut — content-based tagging, care acum este activată ca implicită și este singura recomandată.

Să analizăm mai în detaliu noile caracteristici cheie din werf v1.1 și în același timp să discutăm despre planurile de viitor.

Ce s-a schimbat în werf v1.1?

Un nou format de denumire a etapelor și un nou algoritm de selecție a etapelor din cache

O nouă regulă de generare a numelui etapei. Acum, fiecare construcție a unei etape generează un nume unic de etapă, care constă din 2 părți: semnătura (așa cum era în v1.0) plus un identificator temporal unic.

De exemplu, numele complet al imaginii etapei poate arăta astfel:

werf-stages-storage/myproject:d2c5ad3d2c9fcd9e57b50edd9cb26c32d156165eb355318cebc3412b-1582656767835

… sau, în general, astfel:

werf-stages-storage/PROJECT:SIGNATURE-TIMESTAMP_MILLISEC

Aici:

  • SIGNATURE — este semnătura etapei, care reprezintă identificatorul conținutului etapei și depinde de istoria modificărilor din Git, care au dus la acest conținut;
  • TIMESTAMP_MILLISEC — acesta este un identificator garantat unic al imaginii, care este generat în momentul construcției unei noi imagini.

Algoritmul de selecție a etapelor din cache se bazează pe verificarea relației între commit-urile Git:

  1. Werf calculează semnătura unei anumite etape.
  2. În stages-storage pot exista mai multe etape cu aceeași semnătură. Werf selectează toate etapele corespunzătoare semnăturii.
  3. Dacă etapa curentă este legată de Git (git-archive, etapă personalizată cu patch-uri Git: install, beforeSetup, setup; sau git-latest-patch), atunci werf selectează doar acele etape care sunt legate de un commit care este strămoșul commit-ului curent (pentru care este apelată construcția).
  4. Dintre etapele corespunzătoare rămase, se alege una — cea mai veche după data creării.

Etapa pentru diferite ramuri Git poate avea aceeași semnătură. Însă werf va preveni utilizarea cache-ului asociat diferitelor ramuri între aceste ramuri, chiar dacă semnăturile au coincis.

→ Documentație.

Un nou algoritm pentru crearea și salvarea etapelor în stocarea etapelor

Dacă în timpul selecției etapelor din cache werf nu găsește o etapă corespunzătoare, atunci este inițiat procesul de construcție a unei noi etape.

Observați că mai multe procese (pe un singur sau mai multe gazde) pot începe construcția aceleași etape în aproximativ același timp. Werf folosește un algoritm de blocare optimistă stages-storage în momentul salvării imaginii proaspăt construite în stages-storage. Astfel, atunci când construcția unei noi etape este gata, werf blochează stages-storage și salvează acolo imaginea proaspăt construită doar în cazul în care nu există deja o imagine corespunzătoare (după semnătură și alte parametri — vezi noul algoritm pentru selecția etapelor din cache).

Imaginea proaspăt construită va avea cu siguranță un identificator unic după TIMESTAMP_MILLISEC (vezi noul format de denumire a etapelor). În cazul în care în stages-storage se va găsi o imagine corespunzătoare, werf va respinge imaginea proaspăt construită și va folosi imaginea din cache.

Cu alte cuvinte: primul proces care finalizează construirea imaginii (cel mai rapid) va avea dreptul să o salveze în stocarea etapelor (și apoi această singură imagine va fi folosită pentru toate construcțiile). Procesul lent de construcție nu va bloca niciodată un proces mai rapid de la salvarea rezultatelor construcției etapei curente și trecerea la construcția următoarei.

→ Documentație.

Performanța constructorului Dockerfile a fost îmbunătățită

În prezent, pipeline-ul etapelor pentru imaginea construită din Dockerfile constă într-o singură etapă — dockerfile. La calcularea semnăturii se consideră suma de control a fișierelor. context, care vor fi utilizate la construcție. Până la această îmbunătățire, werf parcurgea recursiv toate fișierele și obținea un checksum, sumând contextul și modul fiecărui fișier. Începând cu versiunile v1.1, werf poate utiliza checksum-urile calculate, stocate în repository-ul Git.

La baza algoritmului se află git ls-tree. Algoritmul ia în considerare înregistrările din .dockerignore și parcurge recursiv arborele fișierelor doar atunci când este necesar. Astfel, ne-am dezghemuit de citirea sistemului de fișiere, iar dependența algoritmului de dimensiunea context nu este semnificativă.

De asemenea, algoritmul verifică fișierele untracked și le include în checksum, dacă este necesar.

Performanța la importarea fișierelor a fost îmbunătățită

În versiunile werf v1.1, se folosește un server rsync la importarea fișierelor din artefacte și imagini. În trecut, importarea se realiza în două etape, utilizând montarea directorului din sistemul gazdă.

Performanța importurilor pe macOS nu mai este limitată de volumele Docker, iar importurile se realizează în același timp ca pe Linux și Windows.

Etichete bazate pe conținut

Werf v1.1 suportă așa-numita etichetare în funcție de conținutul imaginii — content-based tagging. Etichetele imaginilor Docker rezultate depind de conținutul acestor imagini.

Când rulați comanda werf publish --tags-by-stages-signature sau werf ci-env --tagging-strategy=stages-signature vor fi etichetate imaginile publicate, folosing așa-numita semnătură a etapelor imaginii. Fiecare imagine este etichetată cu propria semnătură a etapelor acelei imagini, care este calculată după aceleași reguli ca și semnătura regulată a fiecărei etape în parte, dar este un identificator general al imaginii.

Semnătura etapelor imaginii depinde de:

  1. conținutul acestei imagini;
  2. istoricul modificărilor în Git, care au dus la acest conținut.

În repository-ul Git există întotdeauna commituri goale care nu modifică conținutul fișierelor imaginii. De exemplu, commituri cu doar comentarii sau commituri de tip merge sau commituri care modifică acele fișiere din Git, care nu vor fi importate în imagine.

Utilizând etichetarea bazată pe conținut, se rezolvă problemele cauzate de repornirile inutile ale pod-urilor aplicației în Kubernetes din cauza schimbărilor numelui imaginii, chiar dacă conținutul imaginii nu s-a schimbat. Apropo, aceasta este una dintre cauzele care împiedică stocarea mai multor microservicii ale unei aplicații într-un singur repository Git.

De asemenea, etichetarea bazată pe conținut este o metodă mai fiabilă de etichetare decât etichetarea pe ramurile Git, deoarece conținutul imaginilor rezultate nu depinde de ordinea execuției pipeline-urilor în sistemul CI pentru construirea mai multor commit-uri din aceeași ramură.

Este important: începând de acum stages-signature — acesta este strategia unică recomandată de etichetare. Aceasta va fi utilizată implicit în echipă werf ci-env (dacă nu se specifică explicit o altă schemă de etichetare).

→ Documentație. Această funcționalitate va avea, de asemenea, o publicație separată. ACTUALIZAT (3 aprilie): Articolul cu detalii publicată.

Niveluri de jurnalizare

Utilizatorul a primit oportunitatea de a controla ieșirea, de a stabili nivelul de jurnalizare și de a lucra cu informațiile de depanare. Au fost adăugate opțiuni --log-quiet, --log-verbose, --log-debug.

Implicit, ieșirea conține informații minimum:

Lansarea werf 1.1: îmbunătățiri în constructor astăzi și planuri de viitor

Atunci când se folosește ieșirea detaliată (--log-verbose) se poate urmări cum funcționează werf:

Lansarea werf 1.1: îmbunătățiri în constructor astăzi și planuri de viitor

Ieșirea detaliată (--log-debug), pe lângă informațiile de depanare werf, conține, de asemenea, jurnalele bibliotecilor utilizate. De exemplu, se poate observa cum are loc interacțiunea cu Docker Registry și se pot fixa locurile în care se cheltuie un timp semnificativ:

Lansarea werf 1.1: îmbunătățiri în constructor astăzi și planuri de viitor

Planuri ulterioare

Atenție! Funcționalitățile descrise mai departe, marcate cu v1.1 vor fi disponibile în această versiune, multe dintre ele — în curând. Actualizările vor veni prin actualizări automată atunci când se utilizează multiwerf. Aceste funcționalități nu afectează partea stabilă a funcțiilor v1.1, apariția lor nu va necesita intervenția manuală a utilizatorului în configurațiile existente.

Suport complet pentru diverse implementări Docker Registry (NOU)

  • Versiune: v1.1
  • Termene: martie
  • Issue

Scopul — utilizatorul să utilizeze o implementare arbitrară fără restricții atunci când folosește werf.

În prezent, am evidențiat următorul set de soluții pentru care ne propunem să garantăm suport complet:

  • Default (library/registry)*,
  • AWS ECR,
  • Azure*,
  • Docker Hub,
  • GCR*,
  • GitHub Packages,
  • GitLab Registry*,
  • Harbor*,
  • Quay.

Soluțiile marcate cu stea sunt cele care sunt deja complet suportate de werf. Pentru celelalte există suport, dar cu limitări.

Se pot evidenția două probleme principale:

  • Unele soluții nu suportă ștergerea etichetelor prin intermediul API-ului Docker Registry, ceea ce nu permite utilizatorilor să folosească curățarea automată implementată în werf. Acest lucru este valabil pentru AWS ECR, Docker Hub și GitHub Packages.
  • Unele soluții nu suportă, așa-numitele, repositoare imbricate (Docker Hub, GitHub Packages și Quay) sau le suportă, dar utilizatorul trebuie să le creeze manual, folosind UI sau API (AWS ECR).

Aceste și alte probleme intenționăm să le rezolvăm folosind API-urile native disponibile. Această sarcină include, de asemenea, testarea întregului ciclu de funcționare al werf pentru fiecare dintre ele.

Construirea distribuită a imaginilor (↑)

  • Versiune: v1.2 v1.1 (prioritatea pentru implementarea acestei funcționalități a fost crescută)
  • Termene: martie-aprilie martie
  • Issue

În prezent, werf v1.0 și v1.1 pot fi utilizate doar pe un singur gazdă dedicată pentru operațiuni de construire și publicare a imaginilor și desfășurarea aplicațiilor în Kubernetes.

Pentru a deschide posibilitățile lucrului distribuit cu werf, când construirea și desfășurarea aplicațiilor în Kubernetes sunt inițiate pe mai multe gazde arbitrare și aceste gazde nu își păstrează starea între construcții (runneri temporari), werf trebuie să implementeze funcționalitatea de a utiliza Docker Registry ca depozit pentru etape.

Anterior, când proiectul werf era denumit dapp, exista această funcționalitate. Totuși, ne-am confruntat cu o serie de probleme care trebuie luate în considerare pentru implementarea acestei funcții în werf.

Notă. Această posibilitate nu preconizează funcționarea constructorului în interiorul pod-urilor Kubernetes, deoarece pentru aceasta este necesar să eliminăm dependența de serverul Docker local (în pod-ul Kubernetes nu există acces la serverul Docker local, deoarece procesul în sine este lansat într-un container, iar funcționarea cu serverul Docker prin rețea nu este suportată de werf și nu va fi suportată). Suportul pentru funcționarea în Kubernetes va fi implementat separat.

Suport oficial pentru GitHub Actions (NOU)

  • Versiune: v1.1
  • Termene: martie
  • Issue

Include documentația werf (secțiunile reference și ghid), precum și un GitHub Action oficial pentru lucru cu werf.

De asemenea, va permite utilizarea werf pe runneri efemeri.

Mecanica interacțiunii utilizatorului cu sistemul CI se va baza pe atribuirea de label-uri pull-request-urilor pentru a iniția anumite acțiuni de construire/implementare a aplicației.

Dezvoltarea locală și desfășurarea aplicațiilor cu werf (↓)

  • Versiune: v1.1
  • Termene: ianuarie-februarie aprilie
  • Issue

Principala obiectivă este de a obține o configurație unificată pentru desfășurarea aplicațiilor atât local, cât și în producție, fără acțiuni complicate, «out of the box».

De la werf, se cere, de asemenea, un mod de lucru în care să fie comod să editezi codul aplicației și să obții feedback instantaneu de la aplicația funcțională pentru debugging.

Noul algoritm de curățare (NOU)

  • Versiune: v1.1
  • Termene: aprilie
  • Issue

În versiunea curentă werf v1.1, procedura cleanup nu prevede curățarea imaginilor pentru schema de etichetare pe baza conținutului (content-based tagging) - aceste imagini se vor acumula.

De asemenea, în versiunea curentă werf (v1.0 și v1.1) se folosesc politici diferite de curățare pentru imaginile publicate pe schemele de etichetare: ramură Git, etichetă Git sau commit Git.

S-a conceput un nou algoritm unificat pentru toate schemele de etichetare pentru curățarea imaginilor pe baza istoricului commit-urilor în Git:

  • A păstra nu mai mult de N1 imagini, asociate cu ultimele N2 commit-uri pentru fiecare din git HEAD (ramuri și etichete).
  • A păstra nu mai mult de N1 imagini-stadii, asociate cu ultimele N2 commit-uri pentru fiecare din git HEAD (ramuri și etichete).
  • A păstra toate imaginile care sunt folosite în resursele cluster-ului Kubernetes (se scanează toate contexturile kube din fișierul de configurare și namespace-urile; se poate limita acest comportament prin opțiuni speciale).
  • A păstra toate imaginile care sunt folosite în manifeștele de configurare a resurselor, salvate în versiunile Helm.
  • O imagine poate fi eliminată dacă nu este asociată cu niciun HEAD din git (de exemplu, pentru că HEAD-ul corespunzător a fost șters) și nu este folosită în niciunul dintre manifeștele din cluster-ul Kubernetes și în versiunile Helm.

Construirea paralelă a imaginilor (↓)

  • Versiune: v1.1
  • Termene: ianuarie-februarie aprilie*

Versiunea curentă werf construiește imaginile și artefactele descrise în werf.yaml, succesiune. Este necesar să se paralelizeze procesul de construcție al stadiilor independente de imagini și artefacte, precum și să se asigure o ieșire comodă și informativă.

* Notă: termenul a fost mutat din cauza creșterii priorității pentru implementarea construcției distribuite, care va adăuga mai multe capabilități pentru scalarea orizontală, precum și utilizarea werf cu GitHub Actions. Totuși, construcția paralelă este următorul pas de optimizare, oferind scalabilitate verticală în construirea unui singur proiect.

Tranziția la Helm 3 (↓)

  • Versiunea: v1.2
  • Termene: februarie-martie mai*

Include tranziția la o nouă bază de cod Helm 3 și un mod verificat și comod de migrare a instalațiilor existente.

* Notă: trecerea la Helm 3 nu va adăuga funcționalități semnificative în werf, deoarece toate caracteristicile cheie ale Helm 3 (3-way-merge și absența tiller) sunt deja implementate în werf. Mai mult, werf are funcționalități suplimentare pe lângă cele menționate. Totuși, această trecere rămâne în planurile noastre și va fi realizată.

Jsonnet pentru descrierea configurației Kubernetes (↓)

  • Versiunea: v1.2
  • Termene: ianuarie-februarie aprilie-mai

Werf va susține descrierea configurației pentru Kubernetes în format Jsonnet. În acest proces, werf va rămâne compatibil cu Helm și va exista opțiunea de alegere a formatului de descriere.

Cauza este faptul că șabloanele limbajului Go, conform opiniei multora, au un prag de intrare ridicat, iar claritatea codului acestor șabloane suferă de asemenea.

De asemenea, se ia în considerare posibilitatea implementării altor sisteme de descriere a configurației Kubernetes (de exemplu, Kustomize).

Lucrul în interiorul Kubernetes (↓)

  • Versiunea: v1.2
  • Termene: aprilie-mai mai-iunie

Obiectiv: a asigura construirea imaginilor și livrarea aplicației cu ajutorul runner-urilor în Kubernetes. Adică, construirea de noi imagini, publicarea acestora, curățarea și implementarea pot avea loc direct din pod-urile Kubernetes.

Pentru a implementa această funcționalitate, este necesară mai întâi capacitatea de construire distribuită a imaginilor (vezi punctul de mai sus).

Este, de asemenea, necesară suportul pentru modul de lucru al constructorului fără server Docker (adică, construcție de tip Kaniko sau construcție în userspace).

Werf va susține construirea în Kubernetes nu doar prin Dockerfile, ci și prin constructorul său Stapel cu recompilări incrementale și Ansible.

O mișcare către dezvoltarea deschisă

Ne păsa de comunitatea noastră (GitHub, Telegram) și dorim ca din ce în ce mai mulți oameni să ajute la îmbunătățirea werf, să înțeleagă în ce direcție ne îndreptăm și să participe la dezvoltare.

Recent a fost decisă trecerea la tablouri de proiecte GitHub pentru a deschide procesul de lucru al echipei noastre. Acum este posibil să vedem planurile imediate, precum și lucrările curente în următoarele direcții:

S-a realizat o muncă semnificativă cu problemele:

  • Au fost eliminate cele irelevante.
  • Cele existente au fost aduse într-un format uniform, cu un număr suficient de detalii și specificații.
  • Au fost adăugate probleme noi cu idei și sugestii.

Cum să activați versiunea v1.1

Versiunea este disponibilă în prezent în canalul 1.1 ea (în canalele stable și rock-solid versiunile vor apărea pe măsură ce se stabilizează, totuși ea în sine este deja suficient de stabilă pentru utilizare, deoarece a trecut prin canale alpha și beta). Se activează prin multiwerf în următorul mod:

source $(multiwerf use 1.1 ea)
werf COMMAND ...

Concluzie

Noua arhitectură de stocare a etapelor și optimizarea funcționării compilatorului pentru Stapel și Dockerfile deschid oportunități pentru implementarea compilărilor distribuite și paralele în werf. Aceste caracteristici vor apărea curând în aceeași versiune v1.1 și vor deveni disponibile automat prin mecanismul de actualizări automate (pentru utilizatori multiwerf).

În această versiune a fost adăugată o strategie de etichetare bazată pe conținutul imaginilor — content-based tagging, — care a devenit strategia implicită. De asemenea, a fost revizuit jurnalul principal al comenzilor: werf build, werf publish, werf deploy, werf dismiss, werf cleanup.

Următorul pas semnificativ va fi adăugarea compilărilor distribuite. Compilările distribuite au devenit o sarcină mai prioritară decât compilările paralele din versiunea v1.0, deoarece adaugă mai multă valoare werf: scalarea verticală a compilatorilor și suport pentru compilatoare efemere în diferite sisteme CI/CD, precum și posibilitatea de a oferi suport oficial pentru GitHub Actions. Prin urmare, termenul de realizare a compilărilor paralele a fost mutat. Cu toate acestea, lucrăm pentru a implementa rapid ambele funcționalități.

Rămâneți la curent cu noutățile! Și nu uitați să ne vizitați la GitHub, pentru a crea o problemă, a găsi una deja existentă și a pune un vot, a crea un PR sau pur și simplu pentru a observa evoluția proiectului.

P.S.

Citiți și în blogul nostru:

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster