It probleem fan 'tûke' skjinmeitsjen fan kontenerbylden en de oplossing dêrfan yn werf

It probleem fan 'tûke' skjinmeitsjen fan kontenerbylden en de oplossing dêrfan yn werf

It artikel besprekt de problemen fan it skjinmeitsjen fan ôfbyldings dy't sammelje yn kontenerregistraasjes (Docker Registry en har analogen) yn 'e realiteiten fan moderne CI / CD-pipelines foar wolk-native applikaasjes levere oan Kubernetes. De wichtichste kritearia foar de relevânsje fan bylden en de resultearjende swierrichheden by it automatisearjen fan skjinmeitsjen, besparje romte en foldwaan oan de behoeften fan teams wurde jûn. As lêste, mei it foarbyld fan in spesifyk Open Source-projekt, sille wy jo fertelle hoe't dizze swierrichheden kinne wurde oerwûn.

Ynlieding

It oantal ôfbyldings yn in kontenerregister kin rap groeie, mear opslachromte ynnimme en sa de kosten signifikant ferheegje. Om akseptabel groei fan romte beset yn it register te kontrolearjen, te beheinen of te behâlden, wurdt it akseptearre:

  1. brûk in fêst oantal tags foar ôfbyldings;
  2. skjin de ôfbyldings op ien of oare manier.


De earste beheining is soms akseptabel foar lytse teams. As ûntwikkelders genôch permaninte tags hawwe (latest, main, test, boris ensfh.), sil it register net yn grutte swolle en foar in lange tiid hoege jo hielendal net te tinken oer it skjinmeitsjen. Ommers, alle irrelevante bylden wurde wiske, en der is gewoan gjin wurk mear foar skjinmeitsjen (alles wurdt dien troch in gewoane garbage collector).

Dizze oanpak beheint ûntwikkeling lykwols sterk en is selden fan tapassing op moderne CI / CD-projekten. In yntegraal ûnderdiel fan 'e ûntwikkeling wie automatisearring, wêrmei jo nije funksjonaliteit te testen, ynsette en leverje oan brûkers folle flugger. Bygelyks, yn al ús projekten wurdt automatysk in CI-pipeline makke mei elke commit. Dêryn wurdt de ôfbylding gearstald, hifke, útrôle nei ferskate Kubernetes-sirkels foar debuggen en oerbleaune kontrôles, en as alles goed is, berikke de wizigingen de einbrûker. En dit is net mear raketwittenskip, mar in deistich barren foar in protte - nei alle gedachten foar jo, om't jo dit artikel lêze.

Sûnt it reparearjen fan bugs en it ûntwikkeljen fan nije funksjonaliteit parallel wurdt útfierd, en releases ferskate kearen deis kinne wurde útfierd, is it dúdlik dat it ûntwikkelingsproses wurdt begelaat troch in signifikant oantal commits, wat betsjut in grut oantal ôfbyldings yn it register. Dêrtroch ûntstiet de kwestje fan it organisearjen fan effektive reiniging fan it register, d.w.s. irrelevante ôfbyldings fuortsmite.

Mar hoe kinne jo sels bepale oft in ôfbylding relevant is?

Kritearia foar de relevânsje fan it byld

Yn 'e measte gefallen sille de wichtichste kritearia wêze:

1. De earste (de meast foar de hân lizzende en meast krityske fan alle) is de bylden dy't op it stuit brûkt yn Kubernetes. It fuortsmiten fan dizze ôfbyldings kin resultearje yn signifikante produksje downtime kosten (bygelyks, de ôfbyldings kinne nedich wêze foar replikaasje) of negearje de ynspannings fan it team debuggen op ien fan 'e loops. (Om dizze reden hawwe wy sels in spesjaal makke Prometheus eksporteur, dy't it ûntbrekken fan sokke ôfbyldings yn elke Kubernetes-kluster byhâldt.)

2. Twadde (minder fanselssprekkend, mar ek tige wichtich en wer relatearret oan eksploitaasje) - bylden dy't fereaske foar weromdraaien yn gefal fan opspoaren fan serieuze problemen yn de hjoeddeiske ferzje. Bygelyks, yn it gefal fan Helm, binne dit ôfbyldings dy't brûkt wurde yn bewarre ferzjes fan 'e release. (Trouwens, standert yn Helm is de limyt 256 ferzjes, mar it is net wierskynlik dat immen echt moat bewarje sa'n a in grut tal ferzjes?..) Wy slaan ommers benammen ferzjes op, sadat wy se letter brûke kinne, d.w.s. "roll werom" nei harren as it nedich is.

3. Tredde - developer behoeften: Alle ôfbyldings dy't relatearre binne oan har hjoeddeistige wurk. As wy bygelyks in PR beskôgje, dan makket it sin om in ôfbylding te litten dy't oerienkomt mei de lêste commit en, sizze, de foarige commit: op dizze manier kin de ûntwikkelder fluch weromgean nei elke taak en wurkje mei de lêste feroarings.

4. Fjirde - bylden dy't oerienkomme mei de ferzjes fan ús applikaasje, d.w.s. binne it úteinlike produkt: v1.0.0, 20.04.01/XNUMX/XNUMX, sierra, etc.

NB: De hjir definieare kritearia binne formulearre op basis fan ûnderfining yn ynteraksje mei tsientallen ûntwikkelingsteams fan ferskate bedriuwen. Lykwols, fansels, ôfhinklik fan de spesifikaasjes yn de ûntwikkeling prosessen en de brûkte ynfrastruktuer (bygelyks, Kubernetes wurdt net brûkt), dizze kritearia kinne ferskille.

Kwalifikaasje en besteande oplossingen

Populêre tsjinsten mei kontenerregistraasjes biede yn 'e regel har eigen belied foar skjinmeitsjen fan ôfbyldings: yn har kinne jo de betingsten definiearje wêryn in tag út it register wurdt fuortsmiten. Dizze betingsten wurde lykwols beheind troch parameters lykas nammen, oanmeitsjen tiid, en oantal tags *.

* Hinget ôf fan spesifike ymplemintaasje fan kontenerregister. Wy hawwe de mooglikheden fan 'e folgjende oplossingen beskôge: Azure CR, Docker Hub, ECR, GCR, GitHub-pakketten, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io - mei yngong fan septimber'2020.

Dizze set parameters is genôch om te foldwaan oan it fjirde kritearium - dat is, om ôfbyldings te selektearjen dy't oerienkomme mei de ferzjes. Foar alle oare kritearia moat men lykwols kieze foar in soarte fan kompromisoplossing (in hurder of, oarsom, soepeler belied) - ôfhinklik fan ferwachtings en finansjele mooglikheden.

Bygelyks, it tredde kritearium - relatearre oan de behoeften fan ûntwikkelders - kin oplost wurde troch it organisearjen fan prosessen binnen teams: spesifike nammejouwing fan ôfbyldings, byhâlden fan spesjale tastimminglisten en ynterne ôfspraken. Mar úteinlik moat it noch automatisearre wurde. En as de mooglikheden fan klearmakke oplossingen net genôch binne, moatte jo wat fan jo eigen dwaan.

De situaasje mei de earste twa kritearia is fergelykber: se kinne net tefreden wurde sûnder gegevens te ûntfangen fan in ekstern systeem - it iene wêr't applikaasjes wurde ynset (yn ús gefal, Kubernetes).

Yllustraasje fan workflow yn Git

Litte wy sizze dat jo soksawat wurkje yn Git:

It probleem fan 'tûke' skjinmeitsjen fan kontenerbylden en de oplossing dêrfan yn werf

It ikoan mei in kop yn it diagram jout kontenerôfbyldings oan dy't op it stuit yn Kubernetes ynset wurde foar alle brûkers (ein brûkers, testers, managers, ensfh.) Of wurde brûkt troch ûntwikkelders foar debuggen en ferlykbere doelen.

Wat bart der as opromingsbelied allinich ôfbyldings behâlde kinne (net wiske) troch opjûne tagnammen?

It probleem fan 'tûke' skjinmeitsjen fan kontenerbylden en de oplossing dêrfan yn werf

Fansels sil sa'n senario gjinien bliid meitsje.

Wat sil feroarje as it belied tastiet dat ôfbyldings net wiske wurde? neffens in opjûne tiid ynterval / oantal lêste commits?

It probleem fan 'tûke' skjinmeitsjen fan kontenerbylden en de oplossing dêrfan yn werf

It resultaat is folle better wurden, mar is noch lang net ideaal. Wy hawwe ommers noch ûntwikkelders dy't ôfbyldings nedich hawwe yn it register (of sels ynset yn K8's) om bugs te debuggen ...

Om de hjoeddeistige merksituaasje te gearfetsje: de funksjes beskikber yn kontenerregistraasjes biede net genôch fleksibiliteit by it skjinmeitsjen, en de wichtichste reden hjirfoar is gjin manier om ynteraksje mei de bûtenwrâld. It docht bliken dat teams dy't sa'n fleksibiliteit nedich binne twongen om selsstannich ôfbyldingsferwidering "fan bûten", mei de Docker Registry API (as de native API fan 'e oerienkommende ymplemintaasje) te ymplementearjen.

Wy sochten lykwols nei in universele oplossing dy't it opromjen fan ôfbyldings foar ferskate teams automatisearje soe mei ferskate registers ...

Us paad nei universele byldreiniging

Wêr komt dizze need wei? It feit is dat wy gjin aparte groep ûntwikkelders binne, mar in team dat in protte fan har tagelyk tsjinnet, en helpt om CI / CD-problemen wiidweidich op te lossen. En it wichtichste technyske ark foar dit is it Open Source-hulpprogramma werf. De eigenaardichheid dêrfan is dat it gjin inkele funksje útfiert, mar begeliedt trochgeande leveringsprosessen yn alle stadia: fan montage oant ynset.

It publisearjen fan ôfbyldings nei it register* (direkt nei't se boud binne) is in dúdlike funksje fan sa'n nut. En om't de ôfbyldings dêr wurde pleatst foar opslach, dan - as jo opslach net ûnbeheind is - jo moatte ferantwurdlik wêze foar har folgjende skjinmeitsjen. Hoe't wy yn dit súkses hawwe berikt, oan alle oantsjutte kritearia, sil fierder besprutsen wurde.

* Hoewol de registraasjes sels oars kinne wêze (Docker Registry, GitLab Container Registry, Harbor, ensfh.), hawwe har brûkers deselde problemen. De universele oplossing yn ús gefal is net ôfhinklik fan 'e útfiering fan it register, om't rint bûten de registers sels en biedt itselde gedrach foar elkenien.

Hoewol wy werf brûke as foarbyld fan ymplemintaasje, hoopje wy dat de brûkte oanpak nuttich is foar oare teams dy't mei ferlykbere swierrichheden te krijen hawwe.

Sa krigen wy it drok ekstern ymplemintaasje fan in meganisme foar it skjinmeitsjen fan ôfbyldings - ynstee fan dy mooglikheden dy't al binne ynboud yn registers foar konteners. De earste stap wie om de Docker Registry API te brûken om itselde primitive belied te meitsjen foar it oantal tags en de tiid fan har skepping (hjirboppe neamd). Taheakke oan harren tastean list basearre op ôfbyldings brûkt yn ynset ynfrastruktuer, d.w.s. Kubernetes. Foar de lêste wie it genôch om de Kubernetes API te brûken om troch alle ynset boarnen te iterearjen en in list mei wearden te krijen image.

Dizze triviale oplossing hat it meast krityske probleem oplost (kritearium nr. 1), mar wie allinich it begjin fan ús reis om it reinigingsmeganisme te ferbetterjen. De folgjende - en folle nijsgjirriger - stap wie it beslút assosjearje publisearre ôfbyldings mei Git-skiednis.

Tagging schemes

Om te begjinnen, hawwe wy keazen foar in oanpak wêryn de definitive ôfbylding moat opslaan de nedige ynformaasje foar skjinmeitsjen, en boude it proses op tagging schemes. By it publisearjen fan in ôfbylding selektearre de brûker in spesifike tagging-opsje (git-branch, git-commit of git-tag) en brûkte de oerienkommende wearde. Yn CI-systemen waarden dizze wearden automatysk ynsteld op basis fan omjouwingsfariabelen. Yn feite de definitive ôfbylding waard ferbûn mei in spesifike Git primitive, opslaan fan de nedige gegevens foar skjinmeitsjen yn etiketten.

Dizze oanpak resultearre yn in set fan belied wêrtroch Git koe wurde brûkt as de ienige boarne fan wierheid:

  • By it wiskjen fan in branch / tag yn Git, waarden de assosjearre ôfbyldings yn it register automatysk wiske.
  • It oantal ôfbyldings ferbûn mei Git-tags en commits koe wurde kontrolearre troch it oantal tags brûkt yn it selekteare skema en de tiid wêrop de assosjearre commit waard makke.

Oer it algemien foldie de resultearjende ymplemintaasje oan ús behoeften, mar in nije útdaging wachte ús al gau. It feit is dat by it brûken fan tagging-skema's basearre op Git-primitiven, wy in oantal tekoarten tsjinkamen. (Om't har beskriuwing bûten it berik fan dit artikel leit, kin elkenien harsels fertroud meitsje mei de details hjir.) Dêrom, nei't wy besletten hawwe om te wikseljen nei in effisjintere oanpak fan tagging (ynhâld-basearre tagging), moasten wy de ymplemintaasje fan ôfbyldingsreiniging opnij besjen.

Nije algoritme

Wêrom? Mei ynhâld-basearre tagging kin elke tag meardere commits foldwaan yn Git. By it skjinmeitsjen fan ôfbyldings kinne jo net mear oannimme allinnich fan 'e commit wêr't de nije tag waard tafoege oan it register.

Foar it nije skjinmakalgoritme waard besletten om fuort te gean fan taggingskema's en te bouwen meta-ôfbylding proses, wêrfan elk in bosk opslacht fan:

  • de commit wêrop de publikaasje is útfierd (it makket net út oft de ôfbylding is tafoege, feroare of itselde bleaun yn it kontenerregister);
  • en ús ynterne identifier dy't oerienkomt mei de gearstalde ôfbylding.

Mei oare wurden, it waard foarsjoen publisearre tags keppelje mei commits yn Git.

Finale konfiguraasje en algemiene algoritme

By it konfigurearjen fan skjinmeitsjen hawwe brûkers no tagong ta belied dat aktuele ôfbyldings selektearje. Elk sa'n belied is definiearre:

  • in protte ferwizings, d.w.s. Git-tags as Git-tûken dy't wurde brûkt by it scannen;
  • en de limyt fan sochte ôfbyldings foar elke referinsje út 'e set.

Om te yllustrearjen, dit is hoe't de standert beliedskonfiguraasje begon te sjen:

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

Dizze konfiguraasje befettet trije belied dy't foldogge oan de folgjende regels:

  1. Bewarje de ôfbylding foar de lêste 10 Git-tags (troch datum oanmeitsjen fan tags).
  2. Bewarje net mear as 2 ôfbyldings publisearre yn 'e lêste wike foar net mear as 10 diskusjes mei aktiviteit yn' e lêste wike.
  3. Bewarje 10 ôfbyldings foar tûken main, staging и production.

It definitive algoritme komt del op de folgjende stappen:

  • It opheljen fan manifesten út kontenerregister.
  • Utsein ôfbyldings brûkt yn Kubernetes, omdat Wy hawwe se al foarselekteare troch de K8s API te polljen.
  • Git-skiednis scannen en ôfbyldings útslute basearre op spesifisearre belied.
  • Fuortsmite oerbleaune ôfbyldings.

Werom nei ús yllustraasje, dit is wat bart mei werf:

It probleem fan 'tûke' skjinmeitsjen fan kontenerbylden en de oplossing dêrfan yn werf

Lykwols, sels as jo gjin werf brûke, kin in soartgelikense oanpak foar avansearre ôfbyldingsreiniging - yn ien of oare ymplemintaasje (neffens de foarkar oanpak fan ôfbyldingstagging) - tapast wurde op oare systemen/hulpprogramma's. Om dit te dwaan, is it genôch om de problemen te ûnthâlden dy't ûntsteane en dy kânsen te finen yn jo stapel wêrtroch jo har oplossing sa soepel mooglik kinne yntegrearje. Wy hoopje dat it paad dat wy hawwe reizge jo sil helpe te sjen nei jo bepaalde saak mei nije details en gedachten.

konklúzje

  • Ier of letter, de measte teams tsjinkomme it probleem fan registraasje oerstreaming.
  • By it sykjen nei oplossingen is it earst nedich om de kritearia foar de relevânsje fan it byld te bepalen.
  • De ark oanbean troch populêre kontenerregistraasjetsjinsten kinne jo in heul ienfâldige skjinmeitsjen organisearje dy't gjin rekken hâldt mei de "bûtenwrâld": de ôfbyldings dy't brûkt wurde yn Kubernetes en de eigenaardichheden fan 'e workflows fan it team.
  • In fleksibel en effisjint algoritme moat in begryp hawwe fan CI / CD-prosessen en operearje net allinich mei Docker-ôfbyldingsgegevens.

PS

Lês ek op ús blog:

Boarne: www.habr.com

Add a comment