Ang problema ng "matalinong" paglilinis ng mga imahe ng lalagyan at ang solusyon nito sa werf

Ang problema ng "matalinong" paglilinis ng mga imahe ng lalagyan at ang solusyon nito sa werf

Tinatalakay ng artikulo ang mga problema sa paglilinis ng mga larawan na naipon sa mga registry ng container (Docker Registry at mga analogue nito) sa mga katotohanan ng modernong mga pipeline ng CI/CD para sa mga cloud native na application na inihatid sa Kubernetes. Ang pangunahing pamantayan para sa kaugnayan ng mga imahe at ang mga nagresultang kahirapan sa pag-automate ng paglilinis, pag-save ng espasyo at pagtugon sa mga pangangailangan ng mga koponan ay ibinigay. Sa wakas, gamit ang halimbawa ng isang partikular na proyekto ng Open Source, sasabihin namin sa iyo kung paano malalampasan ang mga paghihirap na ito.

Pagpapakilala

Ang bilang ng mga larawan sa isang container registry ay maaaring mabilis na lumago, na kumukuha ng mas maraming espasyo sa imbakan at sa gayon ay makabuluhang tumataas ang gastos nito. Upang kontrolin, limitahan o mapanatili ang katanggap-tanggap na paglaki ng espasyo na inookupahan sa pagpapatala, tinatanggap ito:

  1. gumamit ng isang nakapirming bilang ng mga tag para sa mga larawan;
  2. linisin ang mga imahe sa ilang paraan.


Ang unang limitasyon ay kung minsan ay katanggap-tanggap para sa maliliit na koponan. Kung ang mga developer ay may sapat na permanenteng tag (latest, main, test, boris atbp.), ang pagpapatala ay hindi bumukol sa laki at sa mahabang panahon ay hindi mo na kailangang mag-isip tungkol sa paglilinis nito. Pagkatapos ng lahat, ang lahat ng hindi nauugnay na mga imahe ay nabubura, at wala na lang trabaho para sa paglilinis (lahat ay ginagawa ng isang regular na kolektor ng basura).

Gayunpaman, lubos na nililimitahan ng diskarteng ito ang pag-unlad at bihirang naaangkop sa mga modernong proyekto ng CI/CD. Isang mahalagang bahagi ng pag-unlad ay automation, na nagbibigay-daan sa iyong subukan, i-deploy at maghatid ng bagong functionality sa mga user nang mas mabilis. Halimbawa, sa lahat ng aming mga proyekto, isang CI pipeline ang awtomatikong nagagawa sa bawat commit. Sa loob nito, ang imahe ay binuo, sinubukan, inilunsad sa iba't ibang mga Kubernetes circuit para sa pag-debug at natitirang mga pagsusuri, at kung ang lahat ay maayos, ang mga pagbabago ay umaabot sa end user. At hindi na ito rocket science, ngunit isang pang-araw-araw na pangyayari para sa marami - malamang para sa iyo, dahil binabasa mo ang artikulong ito.

Dahil ang pag-aayos ng mga bug at pagbuo ng bagong pag-andar ay isinasagawa nang magkatulad, at ang mga paglabas ay maaaring isagawa nang maraming beses sa isang araw, malinaw na ang proseso ng pag-unlad ay sinamahan ng isang makabuluhang bilang ng mga commit, na nangangahulugang isang malaking bilang ng mga imahe sa registry. Bilang isang resulta, ang isyu ng pag-aayos ng epektibong paglilinis ng pagpapatala ay lumitaw, i.e. pag-alis ng mga hindi nauugnay na larawan.

Ngunit paano mo matukoy kung may kaugnayan ang isang imahe?

Pamantayan para sa kaugnayan ng larawan

Sa karamihan ng mga kaso, ang pangunahing pamantayan ay:

1. Ang una (ang pinaka-halata at pinaka-kritikal sa lahat) ay ang mga larawan na kasalukuyang ginagamit sa Kubernetes. Ang pag-alis sa mga larawang ito ay maaaring magresulta sa makabuluhang mga gastos sa downtime ng produksyon (halimbawa, ang mga larawan ay maaaring kailanganin para sa pagkopya) o pabayaan ang mga pagsisikap ng pag-debug ng koponan sa alinman sa mga loop. (Dahil dito, gumawa pa kami ng isang espesyal Exporter ng Prometheus, na sumusubaybay sa kawalan ng mga naturang larawan sa anumang kumpol ng Kubernetes.)

2. Pangalawa (hindi gaanong halata, ngunit napakahalaga rin at muling nauugnay sa pagsasamantala) - mga larawang iyon kinakailangan para sa rollback sa kaso ng pagtuklas ng mga seryosong problema sa kasalukuyang bersyon. Halimbawa, sa kaso ng Helm, ito ay mga larawang ginagamit sa mga naka-save na bersyon ng release. (Sa pamamagitan ng paraan, bilang default sa Helm ang limitasyon ay 256 na mga rebisyon, ngunit malamang na walang sinuman ang talagang kailangang mag-save tulad ng isang isang malaking bilang ng mga bersyon?..) Pagkatapos ng lahat, kami, sa partikular, ay nag-iimbak ng mga bersyon upang magamit namin ang mga ito sa ibang pagkakataon, i.e. "ibalik" sa kanila kung kinakailangan.

3. Pangatlo - pangangailangan ng developer: Lahat ng mga larawan na nauugnay sa kanilang kasalukuyang gawain. Halimbawa, kung isasaalang-alang natin ang isang PR, makatuwirang mag-iwan ng larawan na tumutugma sa huling commit at, sabihin nating, ang nakaraang commit: sa ganitong paraan ang developer ay mabilis na makakabalik sa anumang gawain at magtrabaho kasama ang mga pinakabagong pagbabago.

4. Pang-apat - mga larawan na tumutugma sa mga bersyon ng aming application, ibig sabihin. ay ang huling produkto: v1.0.0, 20.04.01/XNUMX/XNUMX, sierra, atbp.

NB: Ang pamantayang tinukoy dito ay nabuo batay sa karanasan sa pakikipag-ugnayan sa dose-dosenang mga development team mula sa iba't ibang kumpanya. Gayunpaman, siyempre, depende sa mga detalye sa mga proseso ng pag-unlad at ang imprastraktura na ginamit (halimbawa, hindi ginagamit ang Kubernetes), maaaring magkaiba ang mga pamantayang ito.

Pagiging karapat-dapat at mga kasalukuyang solusyon

Ang mga sikat na serbisyo na may mga container registry, bilang panuntunan, ay nag-aalok ng sarili nilang mga patakaran sa paglilinis ng imahe: sa mga ito maaari mong tukuyin ang mga kundisyon kung saan ang isang tag ay tinanggal mula sa registry. Gayunpaman, nililimitahan ang mga kundisyong ito ng mga parameter gaya ng mga pangalan, oras ng paggawa, at bilang ng mga tag*.

* Depende sa mga partikular na pagpapatupad ng container registry. Isinaalang-alang namin ang mga posibilidad ng mga sumusunod na solusyon: Azure CR, Docker Hub, ECR, GCR, GitHub Packages, GitLab Container Registry, Harbour Registry, JFrog Artifactory, Quay.io - noong Setyembre'2020.

Ang hanay ng mga parameter na ito ay sapat na upang matugunan ang ikaapat na pamantayan - iyon ay, upang pumili ng mga larawan na tumutugma sa mga bersyon. Gayunpaman, para sa lahat ng iba pang pamantayan, kailangang pumili ng isang uri ng solusyon sa kompromiso (isang mas mahigpit o, kabaligtaran, mas maluwag na patakaran) - depende sa mga inaasahan at kakayahan sa pananalapi.

Halimbawa, ang ikatlong criterion - na nauugnay sa mga pangangailangan ng mga developer - ay maaaring malutas sa pamamagitan ng pag-aayos ng mga proseso sa loob ng mga koponan: partikular na pagpapangalan ng mga larawan, pagpapanatili ng mga espesyal na listahan ng payagan at panloob na mga kasunduan. Ngunit sa huli ay kailangan pa rin itong maging awtomatiko. At kung ang mga kakayahan ng mga handa na solusyon ay hindi sapat, kailangan mong gumawa ng isang bagay sa iyong sarili.

Ang sitwasyon sa unang dalawang pamantayan ay magkatulad: hindi sila masisiyahan nang hindi nakakatanggap ng data mula sa isang panlabas na sistema - ang isa kung saan ang mga application ay na-deploy (sa aming kaso, Kubernetes).

Ilustrasyon ng daloy ng trabaho sa Git

Sabihin nating gumagawa ka ng ganito sa Git:

Ang problema ng "matalinong" paglilinis ng mga imahe ng lalagyan at ang solusyon nito sa werf

Ang icon na may ulo sa diagram ay nagpapahiwatig ng mga larawan ng container na kasalukuyang naka-deploy sa Kubernetes para sa sinumang user (mga end user, tester, manager, atbp.) o ginagamit ng mga developer para sa pag-debug at mga katulad na layunin.

Ano ang mangyayari kung pinapayagan lang ng mga patakaran sa paglilinis na panatilihin ang mga larawan (hindi tatanggalin) sa pamamagitan ng ibinigay na mga pangalan ng tag?

Ang problema ng "matalinong" paglilinis ng mga imahe ng lalagyan at ang solusyon nito sa werf

Obvious naman na ang ganitong senaryo ay hindi magpapasaya sa sinuman.

Ano ang magbabago kung pinapayagan ng mga patakaran na hindi matanggal ang mga larawan? ayon sa ibinigay na agwat ng oras / bilang ng mga huling commit?

Ang problema ng "matalinong" paglilinis ng mga imahe ng lalagyan at ang solusyon nito sa werf

Ang resulta ay naging mas mahusay, ngunit malayo pa rin sa perpekto. Pagkatapos ng lahat, mayroon pa rin kaming mga developer na nangangailangan ng mga larawan sa registry (o kahit na na-deploy sa K8s) upang i-debug ang mga bug...

Upang ibuod ang kasalukuyang sitwasyon sa merkado: ang mga function na magagamit sa mga rehistro ng container ay hindi nag-aalok ng sapat na kakayahang umangkop kapag naglilinis, at ang pangunahing dahilan para dito ay walang paraan upang makipag-ugnayan sa labas ng mundo. Lumalabas na ang mga koponan na nangangailangan ng gayong kakayahang umangkop ay napipilitang independiyenteng ipatupad ang pagtanggal ng larawan "mula sa labas", gamit ang Docker Registry API (o ang katutubong API ng kaukulang pagpapatupad).

Gayunpaman, naghahanap kami ng isang unibersal na solusyon na mag-o-automate ng paglilinis ng imahe para sa iba't ibang mga koponan gamit ang iba't ibang mga rehistro...

Ang aming landas sa pangkalahatang paglilinis ng imahe

Saan nanggagaling ang pangangailangang ito? Ang katotohanan ay hindi kami isang hiwalay na grupo ng mga developer, ngunit isang team na nagsisilbi sa marami sa kanila nang sabay-sabay, na tumutulong sa komprehensibong paglutas ng mga isyu sa CI/CD. At ang pangunahing teknikal na tool para dito ay ang Open Source utility werf. Ang kakaiba nito ay hindi ito gumaganap ng isang solong function, ngunit sinasamahan ang patuloy na mga proseso ng paghahatid sa lahat ng mga yugto: mula sa pagpupulong hanggang sa pag-deploy.

Ang pag-publish ng mga larawan sa registry* (kaagad pagkatapos na maitayo ang mga ito) ay isang halatang function ng naturang utility. At dahil ang mga imahe ay inilalagay doon para sa imbakan, kung gayon - kung ang iyong imbakan ay hindi limitado - kailangan mong maging responsable para sa kanilang kasunod na paglilinis. Kung paano namin nakamit ang tagumpay dito, na natutugunan ang lahat ng tinukoy na pamantayan, ay tatalakayin pa.

* Bagama't ang mga rehistro mismo ay maaaring magkaiba (Docker Registry, GitLab Container Registry, Harbor, atbp.), ang kanilang mga user ay nahaharap sa parehong mga problema. Ang unibersal na solusyon sa aming kaso ay hindi nakasalalay sa pagpapatupad ng pagpapatala, dahil tumatakbo sa labas ng mga rehistro mismo at nag-aalok ng parehong pag-uugali para sa lahat.

Bagama't ginagamit namin ang werf bilang isang halimbawa ng pagpapatupad, umaasa kami na ang mga diskarte na ginamit ay magiging kapaki-pakinabang sa iba pang mga koponan na nahaharap sa mga katulad na paghihirap.

Kaya naging abala kami panlabas pagpapatupad ng isang mekanismo para sa paglilinis ng mga imahe - sa halip na ang mga kakayahan na iyon na naka-built na sa mga rehistro para sa mga lalagyan. Ang unang hakbang ay ang paggamit ng Docker Registry API upang lumikha ng parehong primitive na mga patakaran para sa bilang ng mga tag at ang oras ng paggawa ng mga ito (nabanggit sa itaas). Idinagdag sa kanila payagan ang listahan batay sa mga larawang ginamit sa naka-deploy na imprastraktura, ibig sabihin. Kubernetes. Para sa huli, sapat na ang paggamit ng Kubernetes API para umulit sa lahat ng naka-deploy na mapagkukunan at makakuha ng listahan ng mga halaga image.

Nalutas ng walang kuwentang solusyon na ito ang pinaka-kritikal na problema (criterion No. 1), ngunit simula pa lang ng aming paglalakbay upang mapabuti ang mekanismo ng paglilinis. Ang susunod - at mas kawili-wiling - hakbang ay ang desisyon iugnay ang mga nai-publish na larawan sa kasaysayan ng Git.

Mga scheme ng pag-tag

Upang magsimula, pumili kami ng isang diskarte kung saan ang huling larawan ay dapat mag-imbak ng kinakailangang impormasyon para sa paglilinis, at binuo ang proseso sa mga scheme ng pag-tag. Kapag nag-publish ng larawan, pumili ang user ng isang partikular na opsyon sa pag-tag (git-branch, git-commit o git-tag) at ginamit ang katumbas na halaga. Sa mga sistema ng CI, ang mga halagang ito ay awtomatikong itinakda batay sa mga variable ng kapaligiran. Sa totoo lang ang huling imahe ay nauugnay sa isang partikular na primitive ng Git, pag-iimbak ng kinakailangang data para sa paglilinis sa mga label.

Ang diskarte na ito ay nagresulta sa isang hanay ng mga patakaran na nagpapahintulot sa Git na magamit bilang isang mapagkukunan ng katotohanan:

  • Kapag nag-delete ng branch/tag sa Git, awtomatikong na-delete ang mga nauugnay na larawan sa registry.
  • Ang bilang ng mga larawang nauugnay sa mga Git tag at commit ay maaaring kontrolin ng bilang ng mga tag na ginamit sa napiling schema at ang oras kung kailan ginawa ang nauugnay na commit.

Sa pangkalahatan, natugunan ng resultang pagpapatupad ang aming mga pangangailangan, ngunit isang bagong hamon ang naghihintay sa amin sa lalong madaling panahon. Ang katotohanan ay habang gumagamit ng mga scheme ng pag-tag batay sa mga primitive ng Git, nakatagpo kami ng ilang mga pagkukulang. (Dahil ang kanilang paglalarawan ay lampas sa saklaw ng artikulong ito, lahat ay maaaring maging pamilyar sa mga detalye dito.) Samakatuwid, nang magpasya kaming lumipat sa isang mas mahusay na diskarte sa pag-tag (pag-tag na nakabatay sa nilalaman), kinailangan naming muling isaalang-alang ang pagpapatupad ng paglilinis ng larawan.

Bagong algorithm

Bakit? Gamit ang pag-tag na nakabatay sa nilalaman, ang bawat tag ay maaaring matugunan ang maramihang mga commit sa Git. Kapag naglilinis ng mga larawan, hindi ka na maaaring mag-assume lamang mula sa commit kung saan idinagdag ang bagong tag sa registry.

Para sa bagong algorithm ng paglilinis, napagpasyahan na lumayo sa mga scheme ng pag-tag at bumuo proseso ng meta-imahe, na ang bawat isa ay nag-iimbak ng isang grupo ng:

  • ang commit kung saan isinagawa ang publikasyon (hindi mahalaga kung ang imahe ay idinagdag, binago o nanatiling pareho sa pagpapatala ng lalagyan);
  • at ang aming panloob na identifier na naaayon sa naka-assemble na larawan.

Sa madaling salita, ito ay ibinigay pag-link ng mga na-publish na tag sa mga commit sa Git.

Panghuling pagsasaayos at pangkalahatang algorithm

Kapag nagko-configure ng paglilinis, mayroon na ngayong access ang mga user sa mga patakarang pumipili ng mga kasalukuyang larawan. Ang bawat naturang patakaran ay tinukoy:

  • maraming sanggunian, i.e. Mga Git tag o Git branch na ginagamit sa pag-scan;
  • at ang limitasyon ng mga hinanap na larawan para sa bawat reference mula sa set.

Upang ilarawan, ito ang naging hitsura ng default na configuration ng patakaran:

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

Naglalaman ang configuration na ito ng tatlong patakaran na sumusunod sa mga sumusunod na panuntunan:

  1. I-save ang larawan para sa huling 10 Git tag (ayon sa petsa ng paggawa ng tag).
  2. Mag-save ng hindi hihigit sa 2 larawang na-publish noong nakaraang linggo para sa hindi hihigit sa 10 thread na may aktibidad sa nakaraang linggo.
  3. Mag-save ng 10 larawan para sa mga sangay main, staging ΠΈ production.

Ang huling algorithm ay bumagsak sa mga sumusunod na hakbang:

  • Kinukuha ang mga manifest mula sa container registry.
  • Hindi kasama ang mga larawang ginamit sa Kubernetes, dahil Napili na namin ang mga ito sa pamamagitan ng pagboto sa K8s API.
  • Pag-scan sa kasaysayan ng Git at pagbubukod ng mga larawan batay sa mga tinukoy na patakaran.
  • Pag-alis ng mga natitirang larawan.

Pagbabalik sa aming ilustrasyon, ito ang nangyayari sa werf:

Ang problema ng "matalinong" paglilinis ng mga imahe ng lalagyan at ang solusyon nito sa werf

Gayunpaman, kahit na hindi ka gumagamit ng werf, ang isang katulad na diskarte sa advanced na paglilinis ng imahe - sa isang pagpapatupad o iba pa (ayon sa ginustong diskarte sa pag-tag ng imahe) - ay maaaring ilapat sa iba pang mga system/utility. Upang gawin ito, sapat na upang matandaan ang mga problema na lumitaw at hanapin ang mga pagkakataong iyon sa iyong stack na nagbibigay-daan sa iyo upang maisama ang kanilang solusyon nang maayos hangga't maaari. Umaasa kami na ang landas na aming tinahak ay makakatulong sa iyo na tingnan ang iyong partikular na kaso na may mga bagong detalye at kaisipan.

Konklusyon

  • Maaga o huli, karamihan sa mga koponan ay nakatagpo ng problema ng pag-apaw ng pagpapatala.
  • Kapag naghahanap ng mga solusyon, kailangan munang matukoy ang pamantayan para sa kaugnayan ng imahe.
  • Ang mga tool na inaalok ng mga sikat na serbisyo sa pagpapatala ng container ay nagbibigay-daan sa iyo upang ayusin ang isang napakasimpleng paglilinis na hindi isinasaalang-alang ang "labas na mundo": ang mga larawang ginamit sa Kubernetes at ang mga kakaiba ng mga daloy ng trabaho ng koponan.
  • Ang isang flexible at mahusay na algorithm ay dapat magkaroon ng pag-unawa sa mga proseso ng CI/CD at gumana hindi lamang sa data ng imahe ng Docker.

PS

Basahin din sa aming blog:

Pinagmulan: www.habr.com

Magdagdag ng komento