Problém „inteligentného“ čistenia obrázkov kontajnerov a jeho riešenie vo werf

Problém „inteligentného“ čistenia obrázkov kontajnerov a jeho riešenie vo werf

Článok pojednáva o problémoch čistenia obrázkov, ktoré sa hromadia v kontajnerových registroch (Docker Registry a jeho analógy) v realite moderných CI/CD kanálov pre cloudové natívne aplikácie dodávané do Kubernetes. Uvádzajú sa hlavné kritériá relevantnosti obrázkov az toho vyplývajúce ťažkosti pri automatizácii čistenia, šetrení miesta a uspokojovaní potrieb tímov. Nakoniec vám na príklade konkrétneho Open Source projektu povieme, ako možno tieto ťažkosti prekonať.

Úvod

Počet obrázkov v registri kontajnerov môže rýchlo rásť, pričom zaberá viac úložného priestoru a tým výrazne zvyšuje jeho náklady. Na kontrolu, obmedzenie alebo udržanie prijateľného nárastu priestoru obsadeného v registri je akceptované:

  1. používať pevný počet značiek pre obrázky;
  2. obrázky nejakým spôsobom vyčistiť.


Prvé obmedzenie je niekedy prijateľné pre malé tímy. Ak majú vývojári dostatok trvalých značiek (latest, main, test, boris atď.), register sa nezväčší a dlho nebudete musieť myslieť na jeho čistenie. Koniec koncov, všetky nepodstatné obrázky sú vymazané a na čistenie jednoducho nezostane žiadna práca (všetko robí bežný zberač odpadu).

Tento prístup však značne obmedzuje vývoj a je zriedka použiteľný na moderné projekty CI/CD. Neoddeliteľnou súčasťou vývoja bolo automatizácia, ktorý vám umožňuje oveľa rýchlejšie testovať, nasadzovať a poskytovať používateľom nové funkcie. Napríklad vo všetkých našich projektoch sa pri každom odovzdaní automaticky vytvorí kanál CI. V ňom sa obraz zostaví, otestuje, zavedie do rôznych obvodov Kubernetes na ladenie a zostávajúce kontroly, a ak je všetko v poriadku, zmeny sa dostanú ku koncovému používateľovi. A to už nie je raketová veda, ale každodenný jav pre mnohých - s najväčšou pravdepodobnosťou pre vás, keďže čítate tento článok.

Keďže oprava chýb a vývoj novej funkcionality prebieha paralelne a vydania sa môžu vykonávať niekoľkokrát denne, je zrejmé, že proces vývoja sprevádza značný počet potvrdení, čo znamená veľké množstvo obrázkov v registri. V dôsledku toho vzniká otázka organizácie efektívneho čistenia registratúry, t.j. odstránenie irelevantných obrázkov.

Ako však zistíte, či je obrázok relevantný?

Kritériá relevantnosti obrázka

Vo veľkej väčšine prípadov budú hlavnými kritériami:

1. Prvým (najzrejmejším a najkritickejším zo všetkých) sú obrázky, ktoré v súčasnosti používané v Kubernetes. Odstránenie týchto obrazov môže viesť k značným nákladom na prestoje vo výrobe (napríklad obrazy môžu byť potrebné na replikáciu) alebo zmariť úsilie tímu pri ladení ktorejkoľvek zo slučiek. (Z tohto dôvodu sme dokonca urobili špeciálny Vývozcovia Prometheus, ktorý sleduje absenciu takýchto obrázkov v akomkoľvek klastri Kubernetes.)

2. Druhý (menej zjavný, ale tiež veľmi dôležitý a opäť súvisí s vykorisťovaním) – obrazy, ktoré potrebné na vrátenie v prípade zistenia vážnych problémov v aktuálnej verzii. Napríklad v prípade Helm ide o obrázky, ktoré sa používajú v uložených verziách vydania. (Mimochodom, štandardne je v Helme limit 256 revízií, ale je nepravdepodobné, že by niekto potreboval uložiť toto veľké množstvo verzií?..) Veď najmä verzie ukladáme, aby sme ich mohli použiť neskôr, t.j. v prípade potreby sa k nim „vrátiť späť“.

3. Tretia - vývojárske potreby: Všetky obrázky, ktoré súvisia s ich aktuálnou prácou. Napríklad, ak uvažujeme o PR, potom má zmysel ponechať obrázok zodpovedajúci poslednému odovzdaniu a povedzme predchádzajúcemu odovzdaniu: vývojár sa tak môže rýchlo vrátiť k akejkoľvek úlohe a pracovať s najnovšími zmenami.

4. Štvrtý - obrázky, ktoré zodpovedajú verziám našej aplikácie, t.j. sú konečným produktom: v1.0.0, 20.04.01/XNUMX/XNUMX, sierra atď.

Poznámka: Kritériá definované tu boli formulované na základe skúseností z interakcie s desiatkami vývojových tímov z rôznych spoločností. Tieto kritériá sa však, samozrejme, môžu líšiť v závislosti od špecifík vo vývojových procesoch a použitej infraštruktúry (napríklad nepoužíva sa Kubernetes).

Spôsobilosť a existujúce riešenia

Populárne služby s kontajnerovými registrami spravidla ponúkajú svoje vlastné zásady čistenia obrázkov: v nich môžete definovať podmienky, za ktorých sa značka odstráni z registra. Tieto podmienky sú však obmedzené parametrami, ako sú názvy, čas vytvorenia a počet značiek*.

* Závisí od konkrétnych implementácií registra kontajnerov. Zvažovali sme možnosti nasledujúcich riešení: Azure CR, Docker Hub, ECR, GCR, GitHub Packages, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io - od septembra 2020.

Tento súbor parametrov úplne postačuje na splnenie štvrtého kritéria - teda výber obrázkov, ktoré zodpovedajú verziám. Pre všetky ostatné kritériá však treba zvoliť nejaké kompromisné riešenie (tvrdšiu alebo naopak miernejšiu politiku) – v závislosti od očakávaní a finančných možností.

Napríklad tretie kritérium – súvisiace s potrebami vývojárov – možno vyriešiť organizovaním procesov v rámci tímov: špecifické pomenovanie obrázkov, udržiavanie špeciálnych zoznamov povolení a interné dohody. V konečnom dôsledku to však stále treba automatizovať. A ak možnosti hotových riešení nestačia, musíte urobiť niečo vlastné.

Situácia s prvými dvoma kritériami je podobná: nemožno ich uspokojiť bez prijímania údajov z externého systému – toho, kde sú nasadené aplikácie (v našom prípade Kubernetes).

Ilustrácia pracovného toku v Git

Povedzme, že v Gite pracujete na niečom takomto:

Problém „inteligentného“ čistenia obrázkov kontajnerov a jeho riešenie vo werf

Ikona s hlavičkou v diagrame označuje obrázky kontajnerov, ktoré sú momentálne nasadené v Kubernetes pre ľubovoľných používateľov (koncoví používatelia, testeri, manažéri atď.) alebo ich používajú vývojári na ladenie a podobné účely.

Čo sa stane, ak zásady vyčistenia umožňujú iba uchovanie (nie odstránenie) obrázkov podľa názvov značiek?

Problém „inteligentného“ čistenia obrázkov kontajnerov a jeho riešenie vo werf

Je zrejmé, že takýto scenár nikoho nepoteší.

Čo sa zmení, ak pravidlá povolia, aby sa obrázky neodstránili? podľa daného časového intervalu / počtu posledných odovzdaní?

Problém „inteligentného“ čistenia obrázkov kontajnerov a jeho riešenie vo werf

Výsledok sa stal oveľa lepším, ale stále je ďaleko od ideálu. Koniec koncov, stále máme vývojárov, ktorí potrebujú obrázky v registri (alebo dokonca nasadené v K8) na ladenie chýb...

Ak zhrnieme súčasnú situáciu na trhu: funkcie dostupné v registroch kontajnerov neponúkajú dostatočnú flexibilitu pri čistení a hlavným dôvodom je žiadny spôsob interakcie s vonkajším svetom. Ukazuje sa, že tímy, ktoré vyžadujú takúto flexibilitu, sú nútené nezávisle implementovať odstraňovanie obrázkov „zvonku“ pomocou rozhrania Docker Registry API (alebo natívneho rozhrania API zodpovedajúcej implementácie).

Hľadali sme však univerzálne riešenie, ktoré by automatizovalo čistenie obrázkov pre rôzne tímy pomocou rôznych registrov...

Naša cesta k univerzálnemu čisteniu obrazu

Odkiaľ pochádza táto potreba? Faktom je, že nie sme samostatná skupina vývojárov, ale tím, ktorý slúži mnohým z nich naraz a pomáha komplexne riešiť problémy CI/CD. A hlavným technickým nástrojom na to je utilita Open Source werf. Jeho zvláštnosťou je, že nevykonáva jedinú funkciu, ale sprevádza nepretržité procesy dodávania vo všetkých fázach: od montáže až po nasadenie.

Publikovanie obrázkov do registra* (ihneď po ich vytvorení) je samozrejmou funkciou takejto pomôcky. A keďže sú tam obrázky umiestnené na uskladnenie, tak – ak vaše úložisko nie je neobmedzené – musíte byť zodpovední za ich následné čistenie. O tom, ako sme v tom dosiahli úspech pri splnení všetkých špecifikovaných kritérií, sa bude diskutovať ďalej.

* Hoci samotné registre môžu byť odlišné (Docker Registry, GitLab Container Registry, Harbor atď.), ich používatelia čelia rovnakým problémom. Univerzálne riešenie v našom prípade nezávisí od implementácie registra, pretože beží mimo samotných registrov a ponúka rovnaké správanie pre všetkých.

Aj keď ako príklad implementácie používame werf, dúfame, že použité prístupy budú užitočné pre ďalšie tímy, ktoré čelia podobným ťažkostiam.

Tak sme sa zamestnali externý implementácia mechanizmu na čistenie obrázkov - namiesto tých schopností, ktoré sú už zabudované v registroch pre kontajnery. Prvým krokom bolo použitie Docker Registry API na vytvorenie rovnakých primitívnych politík pre počet značiek a čas ich vytvorenia (spomenuté vyššie). Pridané k nim zoznam povolených na základe obrázkov používaných v nasadenej infraštruktúre, t.j. Kubernetes. V druhom prípade stačilo použiť Kubernetes API na iteráciu všetkých nasadených zdrojov a získanie zoznamu hodnôt image.

Toto triviálne riešenie vyriešilo najkritickejší problém (kritérium č. 1), ale bolo len začiatkom našej cesty k zlepšeniu čistiaceho mechanizmu. Ďalším – a oveľa zaujímavejším – krokom bolo rozhodnutie spájať publikované obrázky s históriou Git.

Schémy označovania

Na začiatok sme zvolili prístup, v ktorom by mal konečný obrázok uchovávať potrebné informácie na čistenie, a proces sme postavili na schémach označovania. Pri publikovaní obrázka používateľ vybral konkrétnu možnosť označovania (git-branch, git-commit alebo git-tag) a použila zodpovedajúcu hodnotu. V systémoch CI boli tieto hodnoty nastavené automaticky na základe premenných prostredia. v skutočnosti konečný obrázok bol spojený s konkrétnym primitívom Git, uloženie potrebných údajov na čistenie do štítkov.

Tento prístup vyústil do súboru zásad, ktoré umožnili použiť Git ako jediný zdroj pravdy:

  • Pri odstraňovaní vetvy/značky v systéme Git sa automaticky odstránili priradené obrázky v registri.
  • Počet obrázkov priradených k značkám a potvrdeniam Git možno riadiť počtom značiek použitých vo vybranej schéme a časom, v ktorom bolo priradené potvrdenie vytvorené.

Celkovo výsledná implementácia uspokojila naše potreby, no čoskoro nás čakala nová výzva. Faktom je, že pri používaní schém označovania založených na Git primitívoch sme narazili na množstvo nedostatkov. (Keďže ich popis presahuje rámec tohto článku, každý sa môže oboznámiť s podrobnosťami tu.) Preto, keď sme sa rozhodli prejsť na efektívnejší prístup k značkovaniu (označovanie založené na obsahu), museli sme prehodnotiť implementáciu čistenia obrazu.

Nový algoritmus

prečo? Pomocou značkovania založeného na obsahu môže každá značka uspokojiť viacero potvrdení v systéme Git. Pri čistení obrázkov už nemôžete predpokladať iba z odovzdania, kde bola nová značka pridaná do registra.

Pre nový čistiaci algoritmus bolo rozhodnuté opustiť schémy označovania a zostaviť meta-obrazový proces, z ktorých každá obsahuje množstvo:

  • odovzdanie, na ktorom bola publikácia vykonaná (nezáleží na tom, či bol obrázok pridaný, zmenený alebo zostal rovnaký v registri kontajnerov);
  • a náš vnútorný identifikátor zodpovedajúci zostavenému obrázku.

Inými slovami, bolo poskytnuté prepojenie publikovaných značiek s commitmi v Git.

Konečná konfigurácia a všeobecný algoritmus

Pri konfigurácii čistenia majú teraz používatelia prístup k pravidlám, ktoré vyberajú aktuálne obrázky. Každá takáto politika je definovaná:

  • veľa referencií, t.j. Git tagy alebo Git vetvy, ktoré sa používajú počas skenovania;
  • a limit vyhľadaných obrázkov pre každý odkaz zo sady.

Pre ilustráciu, takto začala predvolená konfigurácia politiky vyzerať:

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

Táto konfigurácia obsahuje tri zásady, ktoré sú v súlade s nasledujúcimi pravidlami:

  1. Uložte obrázok pre posledných 10 značiek Git (podľa dátumu vytvorenia značky).
  2. Neukladajte viac ako 2 obrázky zverejnené za posledný týždeň pre maximálne 10 vlákien s aktivitou za posledný týždeň.
  3. Uložte 10 obrázkov pre pobočky main, staging и production.

Konečný algoritmus sa scvrkáva na nasledujúce kroky:

  • Načítavanie manifestov z registra kontajnerov.
  • S výnimkou obrázkov používaných v Kubernetes, pretože Už sme ich vopred vybrali prostredníctvom prieskumu K8s API.
  • Skenovanie histórie Git a vylúčenie obrázkov na základe špecifikovaných zásad.
  • Odstránenie zostávajúcich obrázkov.

Vráťme sa k našej ilustrácii, toto sa stane s werf:

Problém „inteligentného“ čistenia obrázkov kontajnerov a jeho riešenie vo werf

Avšak aj keď nepoužívate werf, podobný prístup k pokročilému čisteniu obrázkov – v tej či onej implementácii (podľa preferovaného prístupu k označovaniu obrázkov) – možno použiť aj na iné systémy/nástroje. Aby ste to dosiahli, stačí si zapamätať problémy, ktoré sa vyskytnú, a nájsť vo svojom zásobníku príležitosti, ktoré vám umožnia čo najhladšie integrovať ich riešenie. Dúfame, že cesta, ktorou sme prešli, vám pomôže pozrieť sa na váš konkrétny prípad s novými detailmi a myšlienkami.

Záver

  • Skôr či neskôr sa väčšina tímov stretne s problémom pretečenia registra.
  • Pri hľadaní riešení je najprv potrebné určiť kritériá relevantnosti obrázka.
  • Nástroje, ktoré ponúkajú obľúbené služby registra kontajnerov, vám umožňujú zorganizovať veľmi jednoduché čistenie, ktoré nezohľadňuje „vonkajší svet“: obrázky používané v Kubernetes a zvláštnosti pracovných postupov tímu.
  • Flexibilný a efektívny algoritmus musí rozumieť procesom CI/CD a pracovať nielen s obrazovými dátami Docker.

PS

Prečítajte si aj na našom blogu:

Zdroj: hab.com

Pridať komentár