Problemet med "smart" rengøring af containerbilleder og dets løsning i werf

Problemet med "smart" rengøring af containerbilleder og dets løsning i werf

Artiklen diskuterer problemerne med at rense billeder, der akkumuleres i containerregistre (Docker Registry og dets analoger) i virkeligheden af ​​moderne CI/CD-pipelines til cloud-native applikationer leveret til Kubernetes. De vigtigste kriterier for relevansen af ​​billeder og de deraf følgende vanskeligheder med at automatisere rengøring, spare plads og opfylde teams behov er givet. Til sidst vil vi ved at bruge eksemplet på et specifikt Open Source-projekt fortælle dig, hvordan disse vanskeligheder kan overvindes.

Indledning

Antallet af billeder i et containerregister kan vokse hurtigt, optage mere lagerplads og dermed øge omkostningerne betydeligt. For at kontrollere, begrænse eller opretholde en acceptabel vækst af plads optaget i registreringsdatabasen accepteres det:

  1. brug et fast antal tags til billeder;
  2. rense billederne på en eller anden måde.


Den første begrænsning er nogle gange acceptabel for små hold. Hvis udviklerne har nok permanente tags (latest, main, test, boris osv.), vil registreringsdatabasen ikke svulme i størrelse, og i lang tid behøver du slet ikke at tænke på at rense det. Alle irrelevante billeder bliver jo slettet, og der er simpelthen ikke noget arbejde tilbage til rengøring (alt udføres af en almindelig skraldemand).

Men denne tilgang begrænser i høj grad udviklingen og er sjældent anvendelig til moderne CI/CD-projekter. En integreret del af udviklingen var automatisering, som giver dig mulighed for at teste, implementere og levere ny funktionalitet til brugerne meget hurtigere. For eksempel oprettes der automatisk en CI-pipeline i alle vores projekter med hver commit. I det er billedet samlet, testet, rullet ud til forskellige Kubernetes-kredsløb til fejlretning og resterende kontroller, og hvis alt er godt, når ændringerne slutbrugeren. Og dette er ikke længere raketvidenskab, men en dagligdags begivenhed for mange - højst sandsynligt for dig, siden du læser denne artikel.

Da reparation af fejl og udvikling af ny funktionalitet udføres parallelt, og udgivelser kan udføres flere gange dagligt, er det indlysende, at udviklingsprocessen er ledsaget af et betydeligt antal commits, hvilket betyder et stort antal billeder i registreringsdatabasen. Som følge heraf opstår spørgsmålet om at organisere en effektiv rengøring af registret, dvs. fjernelse af irrelevante billeder.

Men hvordan afgør man overhovedet, om et billede er relevant?

Kriterier for billedets relevans

I langt de fleste tilfælde vil hovedkriterierne være:

1. Den første (den mest åbenlyse og mest kritiske af alle) er billederne, der bruges i øjeblikket i Kubernetes. Fjernelse af disse billeder kan resultere i betydelige produktionsnedetidsomkostninger (for eksempel kan billederne være påkrævet til replikering) eller ophæve indsatsen fra teamets fejlsøgning på nogen af ​​sløjferne. (Af denne grund lavede vi endda en speciel Prometheus eksportører, som sporer fraværet af sådanne billeder i enhver Kubernetes-klynge.)

2. For det andet (mindre indlysende, men også meget vigtigt og igen relaterer til udnyttelse) - billeder, der påkrævet for tilbagerulning i tilfælde af opdagelse af alvorlige problemer i den nuværende version. For eksempel, i tilfældet med Helm, er disse billeder, der bruges i gemte versioner af udgivelsen. (Forresten, som standard i Helm er grænsen 256 revisioner, men det er usandsynligt, at nogen virkelig behøver at gemme sådan en et stort antal versioner?..) Vi gemmer jo især versioner, så vi kan bruge dem senere, dvs. "rulle tilbage" til dem, hvis det er nødvendigt.

3. Tredje - udviklerens behov: Alle billeder, der er relateret til deres nuværende arbejde. For eksempel, hvis vi overvejer en PR, så giver det mening at efterlade et billede svarende til den sidste commit og for eksempel den forrige commit: på denne måde kan udvikleren hurtigt vende tilbage til enhver opgave og arbejde med de seneste ændringer.

4. For det fjerde - billeder, der svarer til versionerne af vores applikation, dvs. er det endelige produkt: v1.0.0, 20.04.01/XNUMX/XNUMX, sierra osv.

NB: Kriterierne defineret her blev formuleret på baggrund af erfaringer fra interaktion med snesevis af udviklingsteams fra forskellige virksomheder. Men afhængigt af detaljerne i udviklingsprocesserne og den anvendte infrastruktur (f.eks. bruges Kubernetes ikke), kan disse kriterier dog variere.

Berettigelse og eksisterende løsninger

Populære tjenester med containerregistre tilbyder som regel deres egne billedoprydningspolitikker: I dem kan du definere betingelserne for, at et tag fjernes fra registreringsdatabasen. Disse betingelser er dog begrænset af parametre som navne, oprettelsestid og antal tags*.

* Afhænger af specifikke containerregistreringsimplementeringer. Vi overvejede mulighederne for følgende løsninger: Azure CR, Docker Hub, ECR, GCR, GitHub-pakker, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io - fra september'2020.

Dette sæt parametre er ganske nok til at opfylde det fjerde kriterium - det vil sige at vælge billeder, der svarer til versionerne. For alle andre kriterier skal man dog vælge en form for kompromisløsning (en hårdere eller omvendt mere lempelig politik) - afhængig af forventninger og økonomiske muligheder.

For eksempel kan det tredje kriterium - relateret til udviklernes behov - løses ved at organisere processer inden for teams: specifik navngivning af billeder, opretholdelse af særlige tilladelseslister og interne aftaler. Men i sidste ende skal det stadig automatiseres. Og hvis evnerne i færdige løsninger ikke rækker, må du gøre noget selv.

Situationen med de to første kriterier er den samme: De kan ikke opfyldes uden at modtage data fra et eksternt system - det, hvor applikationer er implementeret (i vores tilfælde Kubernetes).

Illustration af arbejdsgang i Git

Lad os sige, at du arbejder noget som dette i Git:

Problemet med "smart" rengøring af containerbilleder og dets løsning i werf

Ikonet med et hoved i diagrammet angiver containerbilleder, der i øjeblikket er implementeret i Kubernetes for alle brugere (slutbrugere, testere, administratorer osv.) eller bruges af udviklere til fejlretning og lignende formål.

Hvad sker der, hvis oprydningspolitikker kun tillader, at billeder bevares (ikke slettes) ved givne tagnavne?

Problemet med "smart" rengøring af containerbilleder og dets løsning i werf

Naturligvis vil et sådant scenario ikke gøre nogen glade.

Hvad vil ændre sig, hvis politikker tillader, at billeder ikke slettes? i henhold til et givet tidsinterval / antal sidste commits?

Problemet med "smart" rengøring af containerbilleder og dets løsning i werf

Resultatet er blevet meget bedre, men er stadig langt fra ideelt. Vi har trods alt stadig udviklere, der har brug for billeder i registreringsdatabasen (eller endda installeret i K8'er) for at fejlfinde fejl...

For at opsummere den aktuelle markedssituation: De tilgængelige funktioner i containerregistre tilbyder ikke tilstrækkelig fleksibilitet ved rengøring, og hovedårsagen til dette er ingen måde at interagere med omverdenen på. Det viser sig, at hold, der kræver en sådan fleksibilitet, er tvunget til selvstændigt at implementere billedsletning "udefra" ved hjælp af Docker Registry API (eller den native API for den tilsvarende implementering).

Vi ledte dog efter en universel løsning, der kunne automatisere billedoprydning for forskellige teams ved hjælp af forskellige registre...

Vores vej til universel billedrensning

Hvor kommer dette behov fra? Faktum er, at vi ikke er en særskilt gruppe af udviklere, men et team, der betjener mange af dem på én gang, og hjælper med at løse CI/CD-problemer omfattende. Og det vigtigste tekniske værktøj til dette er Open Source-værktøjet werf. Dens ejendommelighed er, at den ikke udfører en enkelt funktion, men ledsager kontinuerlige leveringsprocesser på alle stadier: fra montering til implementering.

At publicere billeder til registreringsdatabasen* (umiddelbart efter de er bygget) er en indlysende funktion af et sådant værktøj. Og da billederne er placeret der til opbevaring, så - hvis din opbevaring ikke er ubegrænset - skal du være ansvarlig for deres efterfølgende rengøring. Hvordan vi opnåede succes med dette, der opfylder alle de specificerede kriterier, vil blive diskuteret yderligere.

* Selvom registrene i sig selv kan være forskellige (Docker Registry, GitLab Container Registry, Harbor, osv.), står deres brugere over for de samme problemer. Den universelle løsning i vores tilfælde afhænger ikke af implementeringen af ​​registreringsdatabasen, fordi kører uden for selve registrene og tilbyder den samme adfærd for alle.

Selvom vi bruger werf som et eksempel på implementering, håber vi, at de anvendte tilgange vil være nyttige for andre teams, der står over for lignende vanskeligheder.

Så vi fik travlt ydre implementering af en mekanisme til at rense billeder - i stedet for de funktioner, der allerede er indbygget i registre til containere. Det første skridt var at bruge Docker Registry API til at skabe de samme primitive politikker for antallet af tags og tidspunktet for deres oprettelse (nævnt ovenfor). Tilføjet til dem Tillad liste baseret på billeder, der bruges i implementeret infrastruktur, dvs. Kubernetes. For sidstnævnte var det nok at bruge Kubernetes API til at iterere gennem alle installerede ressourcer og få en liste over værdier image.

Denne trivielle løsning løste det mest kritiske problem (kriterium nr. 1), men var kun begyndelsen på vores rejse for at forbedre rengøringsmekanismen. Det næste - og meget mere interessante - skridt var beslutningen knytte publicerede billeder til Git-historien.

Tagging ordninger

Til at begynde med valgte vi en tilgang, hvor det endelige billede skulle gemme den nødvendige information til rengøring, og byggede processen på tagging-skemaer. Ved udgivelse af et billede valgte brugeren en specifik taggingmulighed (git-branch, git-commit eller git-tag) og brugte den tilsvarende værdi. I CI-systemer blev disse værdier indstillet automatisk baseret på miljøvariabler. Faktisk det endelige billede var forbundet med en specifik Git-primitiv, lagring af de nødvendige data til rengøring i etiketter.

Denne tilgang resulterede i et sæt politikker, der tillod Git at blive brugt som den eneste kilde til sandhed:

  • Ved sletning af en gren/tag i Git blev de tilknyttede billeder i registreringsdatabasen automatisk slettet.
  • Antallet af billeder forbundet med Git tags og commits kunne styres af antallet af tags brugt i det valgte skema og det tidspunkt, hvor den tilknyttede commit blev oprettet.

Samlet set tilfredsstillede den resulterende implementering vores behov, men en ny udfordring ventede os snart. Faktum er, at mens vi brugte tagging-skemaer baseret på Git-primitiver, stødte vi på en række mangler. (Da deres beskrivelse er uden for rammerne af denne artikel, kan alle sætte sig ind i detaljerne her.) Derfor, efter at have besluttet at skifte til en mere effektiv tilgang til tagging (indholdsbaseret tagging), var vi nødt til at genoverveje implementeringen af ​​billedrensning.

Ny algoritme

Hvorfor? Med indholdsbaseret tagging kan hvert tag opfylde flere commits i Git. Når du renser billeder, kan du ikke længere antage kun fra den commit, hvor det nye tag blev tilføjet til registreringsdatabasen.

For den nye rengøringsalgoritme blev det besluttet at gå væk fra mærkningsordninger og bygge meta-image proces, som hver især gemmer en masse:

  • den forpligtelse, som publiceringen blev udført på (det er ligegyldigt, om billedet blev tilføjet, ændret eller forblev det samme i containerregistret);
  • og vores interne identifikator, der svarer til det samlede billede.

Det blev med andre ord leveret forbinder offentliggjorte tags med commits i Git.

Endelig konfiguration og generel algoritme

Ved konfiguration af rengøring har brugerne nu adgang til politikker, der vælger aktuelle billeder. Hver sådan politik er defineret:

  • mange referencer, dvs. Git-tags eller Git-grene, der bruges under scanning;
  • og grænsen for søgte billeder for hver reference fra sættet.

For at illustrere dette er, hvordan standardpolitikkonfigurationen begyndte at se ud:

cleanup:
  keepPolicies:
  - references:
      tag: /.*/
      limit:
        last: 10
  - references:
      branch: /.*/
      limit:
        last: 10
        in: 168h
        operator: And
    imagesPerReference:
      last: 2
      in: 168h
      operator: And
  - references:  
      branch: /^(main|staging|production)$/
    imagesPerReference:
      last: 10

Denne konfiguration indeholder tre politikker, der overholder følgende regler:

  1. Gem billedet for de sidste 10 Git-tags (efter tag-oprettelsesdato).
  2. Gem ikke mere end 2 billeder offentliggjort i den sidste uge for ikke mere end 10 tråde med aktivitet i den sidste uge.
  3. Gem 10 billeder til grene main, staging и production.

Den endelige algoritme koger ned til følgende trin:

  • Henter manifester fra containerregistret.
  • Udelukker billeder brugt i Kubernetes, fordi Vi har allerede valgt dem på forhånd ved at polle K8s API.
  • Scanner Git-historik og ekskluderer billeder baseret på specificerede politikker.
  • Fjerner resterende billeder.

For at vende tilbage til vores illustration, er dette, hvad der sker med werf:

Problemet med "smart" rengøring af containerbilleder og dets løsning i werf

Men selvom du ikke bruger werf, kan en lignende tilgang til avanceret billedrensning - i en eller anden implementering (i henhold til den foretrukne tilgang til billedmærkning) - anvendes på andre systemer/værktøjer. For at gøre dette er det nok at huske de problemer, der opstår, og finde de muligheder i din stak, der giver dig mulighed for at integrere deres løsning så glat som muligt. Vi håber, at den vej, vi har gået, vil hjælpe dig til at se på netop din sag med nye detaljer og tanker.

Konklusion

  • Før eller siden støder de fleste hold på problemet med registreringsoverløb.
  • Når du søger efter løsninger, er det først nødvendigt at bestemme kriterierne for billedets relevans.
  • Værktøjerne, der tilbydes af populære containerregistreringstjenester, giver dig mulighed for at organisere en meget enkel oprydning, der ikke tager højde for "verden udenfor": billederne, der bruges i Kubernetes og de særlige kendetegn ved teamets arbejdsgange.
  • En fleksibel og effektiv algoritme skal have forståelse for CI/CD-processer og ikke kun fungere med Docker-billeddata.

PS

Læs også på vores blog:

Kilde: www.habr.com

Tilføj en kommentar