
Artikulli shqyrton problematikën e pastrimit të imazheve që grumbullohen në regjistrat e kontejnerëve (Docker Registry dhe analogët e tij) në kontekstin e pipeline-ve moderne CI/CD për aplikacione cloud native, të shpërndara në Kubernetes. Paraqiten kritere kryesore të relevancës së imazheve dhe vështirësitë që rrjedhin prej tyre gjatë automatizimit të pastrimit, ruajtjes së hapësirës dhe përmbushjes së nevojave të ekipeve. Në fund, me shembuj nga një projekt konkret Open Source, do të tregojmë se si mund të kapërcehen këto sfida.
Hyrje
Numri i imazheve në regjistrin e kontejnerëve mund të rritet shpejt, duke zënë më shumë hapësirë në ruajtje dhe, për pasojë, duke rritur ndjeshëm koston e saj. Për të kontrolluar, kufizuar ose mbajtur një rritje të pranueshme të hapësirës që zë në registry, miratohet:
- të përdoren një numër fikse etiketash për imazhet;
- ndonjë mënyrë për të pastruar imazhet.
Kufizimi i parë ndonjëherë është i pranueshëm për ekipe të vogla. Nëse zhvilluesve u mjaftojnë etiketat e përhershme (latest, main, test, boris dhe të tilla), regjistri nuk do të fryhet në përmasa dhe për një periudhë të gjatë nuk do të mendoni fare për pastrimin. Të gjitha imazhet e pasaktësuara shuhen, dhe për pastrimin nuk mbetet asnjë punë (gjithçka bëhet nga mbledhësi i zakonshëm i mbeturinave).
MegjithatĂ«, ky qasje kufizon shumĂ« zhvillimin dhe Ă«shtĂ« rrallĂ« e aplikueshme pĂ«r CI/CD-tĂ« e projekteve moderne. NjĂ« pjesĂ« e pandashme e zhvillimit Ă«shtĂ« bĂ«rĂ« automatizimi, qĂ« lejon testimin, implementimin dhe shpĂ«rndarjen e funksionaliteteve tĂ« reja pĂ«r pĂ«rdoruesit shumĂ« mĂ« shpejt. PĂ«r shembull, nĂ« tĂ« gjitha projektet tona, me çdo komit automatikisht krijohet njĂ« pipeline CI. Aty krijohet imazhi, testohet, vendoset nĂ« kontejnerĂ«t e ndryshĂ«m Kubernetes pĂ«r debugim dhe kontroll tĂ« mbetur, dhe nĂ«se gjithçka shkon mirĂ« â ndryshimet arrijnĂ« deri te pĂ«rdoruesi pĂ«rfundimtar. Dhe kjo nuk Ă«shtĂ« mĂ« rocket science, por njĂ« gjĂ« e zakonshme pĂ«r shumĂ« - ndoshta edhe pĂ«r ju, qĂ« po e lexoni kĂ«tĂ« artikull.
Duke pasur parasysh qĂ« eliminimi i gabimeve dhe zhvillimi i funksionaliteteve tĂ« reja bĂ«het paralelisht, dhe lĂ«shimet mund tĂ« kryhen disa herĂ« nĂ« ditĂ«, Ă«shtĂ« e qartĂ« se procesi i zhvillimit shoqĂ«rohet me njĂ« numĂ«r tĂ« konsiderueshĂ«m komitĂ«sh, dhe kjo do tĂ« thotĂ« â numri i madh i imazheve nĂ« registry. Si rezultat, lind me urgjencĂ« çështja e organizimit tĂ« njĂ« pastrimi efektiv tĂ« registry-t, dmth, eliminimi i imazheve jo relevante.
Por si të përcaktojmë në të vërtetë, a është imazhi i rëndësishëm?
Kriteret e rëndësishmërisë së imazhit
Në shumicën dërrmuese të rasteve, kriteret kryesore do të jenë si më poshtë:
1. E para (mĂ« e dukshme dhe mĂ« kritike nga tĂ« gjitha) â janĂ« imazhet qĂ« nĂ« kĂ«tĂ« moment po pĂ«rdoren nĂ« Kubernetes. Eliminimi i kĂ«tyre imazheve mund tĂ« çojĂ« nĂ« kosto tĂ« rĂ«ndĂ«sishme pĂ«r shkak tĂ« ndĂ«rprerjes sĂ« prodhimit (pĂ«r shembull, imazhet mund tĂ« nevojiten pĂ«r replikim) ose tĂ« minojĂ« pĂ«rpjekjet e ekipit qĂ« merret me debugimin nĂ« ndonjĂ« nga sektorĂ«t. (PĂ«r kĂ«tĂ« arsye, ne madje krijuam njĂ« , qĂ« monitoron mungesĂ«n e imazheve tĂ« tilla nĂ« çdo klaster Kubernetes.)
2. E dyta (mĂ« pak e dukshme, por gjithashtu shumĂ« e rĂ«ndĂ«sishme dhe pĂ«rsĂ«ri lidhur me operimin) â imazhet qĂ« nevojiten pĂ«r kthim mbrapa nĂ« rast se zbulohet ndonjĂ« problem serioz nĂ« versionin aktual. PĂ«r shembull, nĂ« rastin e Helm, kĂ«to janĂ« imazhet qĂ« pĂ«rdoren nĂ« versionet e ruajtura tĂ« lĂ«shimit. (PĂ«r notĂ«, me default nĂ« Helm ka njĂ« limit prej 256 rishikimesh, por ndoshta askush nuk ka nevojĂ« realisht pĂ«r ruajtjen e tillave njĂ« numri tĂ« tillĂ« tĂ« madh versionesh?..) Ajo qĂ« ne, pĂ«r shembull, i ruajmĂ« versionet Ă«shtĂ« pĂ«r t'i pĂ«rdorur mĂ« vonĂ«, dmth. "tĂ« kthehemi" nĂ« to nĂ« rast nevoje.
3. TĂ« tretin â nevojat e zhvilluesve: tĂ« gjitha imazhet qĂ« lidhen me punĂ«t e tyre tĂ« tanishme. PĂ«r shembull, nĂ«se po shqyrtojmĂ« PR, ka kuptim tĂ« lĂ«shohet njĂ« imazh qĂ« pĂ«rkon me commitin mĂ« tĂ« fundit dhe, le tĂ« themi, commitin e mĂ«parshĂ«m: kĂ«shtu zhvilluesi do tĂ« mund tĂ« kthehet shpejt nĂ« çdo detyrĂ« dhe tĂ« punojĂ« me ndryshimet e fundit.
4. TĂ« katĂ«rtin â imazhet qĂ« pĂ«rkojnĂ« me versionet e aplikacionit tonĂ«, dmth. janĂ« produkti pĂ«rfundimtar: v1.0.0, 20.04.01, sierra etj.
NB: Kritere që janë përcaktuar këtu janë formuluar në bazë të përvojës së bashkëpunimit me njëzetra ekipe zhvilluesish nga kompani të ndryshme. Megjithatë, natyrisht, në varësi të veçantive në proceset e zhvillimit dhe infrastrukturës së përdorur (p.sh., nëse Kubernetes nuk përdoret), këto kritere mund të ndryshojnë.
Përputhshmëria me kriteret dhe zgjidhjet ekzistuese
Shërbimet e njohura me registry të kontejnerëve, zakonisht ofrojnë politikat e tyre për pastrimin e imazheve: në to mund të përcaktoni kushtet në të cilat një etiketë largohet nga registry. Megjithatë, mundësitë e këtyre kushteve kufizohen deri në parametra të tillë si emrat, koha e krijimit dhe numri i etiketave*.
* Varet nga implementimet specifike tĂ« registry tĂ« kontejnerĂ«ve. Ne shqyrtuam mundĂ«sitĂ« e zgjidhjeve tĂ« mĂ«poshtme: Azure CR, Docker Hub, ECR, GCR, GitHub Packages, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io â nĂ« gjendje deri nĂ« shtator 2020.
Ky set parametrash Ă«shtĂ« mjaft i mjaftueshĂ«m pĂ«r tĂ« pĂ«rmbushur kriterin e katĂ«rt â qĂ« do tĂ« thotĂ« tĂ« zgjedhĂ«sh imazhe qĂ« pĂ«rputhen me versionet. MegjithatĂ«, pĂ«r tĂ« gjitha kriteret e tjera, duhet tĂ« zgjidhni njĂ« zgjidhje kompromisi (njĂ« politikĂ« mĂ« tĂ« ashpĂ«r ose, pĂ«rkundrazi, mĂ« lehtĂ«suese) â varĂ«sisht nga pritshmĂ«ritĂ« dhe mundĂ«sitĂ« financiare.
PĂ«r shembull, kriteri i tretĂ« â i lidhur me nevojat e zhvilluesve â mund tĂ« zgjidhet pĂ«rmes organizimit tĂ« proceseve brenda ekipeve: emĂ«rtimi specifik i imazheve, mbajtja e listave tĂ« lejuara dhe marrĂ«veshjet e brendshme. Por, nĂ« fund tĂ« fundit, Ă«shtĂ« e nevojshme ta automatizoni atĂ«. Dhe nĂ«se mundĂ«sitĂ« e zgjidhjeve tĂ« gatshme nuk mjaftojnĂ«, duhet tĂ« bĂ«ni diçka tĂ« vetme.
Situata me dy kriteret e para Ă«shtĂ« e ngjashme: ato nuk mund tĂ« pĂ«rmbushen pa marrĂ« tĂ« dhĂ«na nga njĂ« sistem tĂ« jashtĂ«m â ai qĂ« zhvillohet aplikacioneve (nĂ« rastin tonĂ«, kjo Ă«shtĂ« Kubernetes).
Ilustrimi i fluksit të punës në Git
Supozoni se punoni përafërsisht sipas kësaj skeme në Git:

Ikona me kokë në diagram tregon imazhet e konteinerëve, të cilat janë aktualisht të vendosura në Kubernetes për disa përdorues (përdoruesit e fundit, testuesit, menaxherët etj.) ose përdoren nga zhvilluesit për debug dhe qëllime të ngjashme.
ĂfarĂ« do tĂ« ndodhĂ« nĂ«se politikat e pastrimit lejojnĂ« qĂ« tĂ« lihen (nuk fshihen) imazhe vetĂ«m pĂ«r emrat e etiketave tĂ« caktuara?

Sikur një skenar i tillë nuk do të gëzonte askënd.
ĂfarĂ« do tĂ« ndryshojĂ« nĂ«se politikat lejojnĂ« tĂ« mos fshihen imazhet pĂ«r njĂ« interval tĂ« caktuar kohor / numrin e komiteteve mĂ« tĂ« fundit?

Rezultati Ă«shtĂ« pĂ«rmirĂ«suar ndjeshĂ«m, megjithatĂ«, ende Ă«shtĂ« larg idealit. Sepse kemi ende zhvillues qĂ« kanĂ« nevojĂ« pĂ«r imazhe nĂ« regjistrin (ose madje tĂ« vendosura nĂ« K8s) pĂ«r debug tĂ« gabimeveâŠ
Duke përmbledhur situatën aktuale në treg: funksionet e disponueshme në regjistrat e konteinerëve nuk ofrojnë fleksibilitet të mjaftueshëm gjatë pastrimit, dhe shkaku kryesor është nuk ka mundësi për të bashkëvepruar me botën e jashtme. Kështu që ekipet që kanë nevojë për një fleksibilitet të tillë, janë të detyruara të implementojnë vetë fshirjen e imazheve "jashtë", duke përdorur API-në e Docker Registry (ose API-në native të implementimit përkatës).
Megjithatë, ne kërkonim një zgjidhje universale që do të automatizonte procesin e pastrimit të imazheve për grupe të ndryshme, duke përdorur regjistra të ndryshëm...
Rruga jonë drejt një pastrimi universale të imazheve
Pse ka një nevojë të tillë? Kjo ndodh sepse ne nuk jemi vetëm një grup zhvilluesish, por një ekip që shërben menjëherë për shumë grupe, duke ndihmuar në zgjidhjen e pyetjeve CI/CD në mënyrë gjithëpërfshirëse. Dhe mjeti ynë kryesor teknik për këtë është një mjet Open Source. . Karakteristika e tij është se ai nuk kryen një funksion të vetëm, por shoqëron proceset e dorëzimit të vazhdueshëm në të gjitha etapet: nga ndërtimi deri në implementim.
Dërgimi në regjistrin* e imazheve (menjëherë pas ndërtimit të tyre) është një funksion i dukshëm i këtij mjeti. Dhe nëse imazhet ruhen atje, atëherë - nëse depoja juaj nuk është e pafund - duhet të merrni përgjegjësi edhe për pastrimin e mëtejshëm të tyre. Më tej do të tregojmë se si arritëm të kemi sukses në këtë, duke përmbushur të gjithë kriteret e caktuara.
* Edhe pse regjistrat vetë mund të jenë të ndryshëm (Docker Registry, GitLab Container Registry, Harbor etj.), përdoruesit e tyre përballen me të njëjtat probleme. Një zgjidhje universale në rastin tonë nuk varet nga implementimi i regjistrit, pasi ekzekutohet jashtë vetë regjistrave dhe ofron të njëjtin sjellje për të gjithë.
Megjithatë, ne përdorim werf si një shembull të implementimit, shpresojmë që qasjet e përdorura do të jenë të dobishme edhe për ekipet e tjera që përballen me vështirësi të ngjashme.
KĂ«shtu, ne u morĂ«m me implementimin e njĂ« mekanizmi pĂ«r pastrimin e imazheve â nĂ« vend tĂ« mundĂ«sive qĂ« janĂ« tashmĂ« tĂ« ndĂ«rtuara nĂ« regjistrat pĂ«r kontejnerĂ«t. Hapi i parĂ« ishte pĂ«rdorimi i API-t tĂ« Docker Registry pĂ«r tĂ« krijuar ato politika primitive mbi numrin e etiketimeve dhe kohĂ«n e krijimit tĂ« tyre (tĂ« pĂ«rmendura mĂ« parĂ«). Ata morĂ«n njĂ« listĂ« lejesh tĂ« bazuar nĂ« imazhet qĂ« pĂ«rdoren nĂ« infrastrukturĂ«n e vendosur, pra, Kubernetes. PĂ«r kĂ«tĂ« tĂ« fundit, ishte e mjaftueshme qĂ« pĂ«rmes API-t tĂ« Kubernetes tĂ« kalonim pĂ«rmes tĂ« gjitha burimeve tĂ« vendosura dhe tĂ« merrnim njĂ« listĂ« me vlera. image.
Ky zgjidhje triviale zgjidhi problemin mĂ« kritik (kriteri nr. 1), por ishte vetĂ«m fillimi i rrugĂ«timit tonĂ« pĂ«r pĂ«rmirĂ«simin e mekanizmit tĂ« pastrimit. Hapi tjetĂ«r â dhe shumĂ« mĂ« interesant â ishte zgjidhja pĂ«r tĂ« lidhur imazhet e publikuara me historinĂ« e Git.
Skemat e etiketimit
Për të filluar, ne zgjodhëm një qasje ku imazhi përfundimtar duhet të ruajë informacionin e nevojshëm për pastrimin, dhe ndërtuam procesin mbi skemat e etiketimit. Gjatë publikimit të imazhit, përdoruesi zgjidhte një opsion të caktuar etiketimi (git-branch, git-commit ose git-tag) dhe përdorte vlerën përkatëse. Në sistemet CI, vendosja e këtyre vlerave bëhej automatikisht në përputhje me variablat e mjedisit. Në thelb imazhi përfundimtar lidhej me një primitiv të caktuar Git, duke ruajtur të dhënat e nevojshme për pastrimin në etiketa.
Në kuadër të kësaj qasje u krijua një grup politikash që lejonin përdorimin e Git si burimi i vetëm i së vërtetës:
- Kur një degë/tag hiqej në Git, imazhet e lidhura në regjistrat fshiheshin automatikisht.
- Numri i imazheve të lidhur me etiketat dhe angazhimet Git mund të rregullohet nëpërmjet numrit të etiketave të përdorura në skemën e zgjedhur dhe kohës së krijimit të angazhimit të lidhur.
Në përgjithësi, realizimi i arritur plotësonte nevojat tona, por së shpejti na priste një sfidë e re. Ajo që ndodhi ishte se gjatë kohës së përdorimit të skemave të etiketimit sipas principeve të Git, u përballëm me një sërë dobësish. (Duke qenë se përshkrimi i tyre është jashtë temës së këtij artikulli, të gjithë të interesuarit mund të informohen për detajet .) Prandaj, pasi morëm vendimin për të kaluar në një qasje më efikase të etiketimit (etiketimi i bazuar në përmbajtje), na duhej të rishikonim gjithashtu realizimin e pastrimit të imazheve.
Algoritmi i ri
Pse? Në etiketimin e bazuar në përmbajtje, çdo etiketë mund të përmbushë shumë angazhime në Git. Në pastrimin e imazheve nuk mund të bazohemi më vetëm në angazhimin në të cilin etiketa e re u shtua në regjistër.
Për algoritmin e ri të pastrimit, u vendos të largohemi nga skemat e etiketimit dhe të strukturojmë procesin në metaimazhe, secili prej të cilëve ruan lidhjen e:
- komitit, në të cilin u publikua (nuk ka rëndësi nëse u shtua, ndryshua ose mbeti i njëjtë imazhi në regjistrin e konteinerëve);
- dhe identifikuesit tonë të brendshëm, të cilit i përket imazhi i ndërtuar.
Me fjalë të tjera, është siguruar lidhja e etiketave të publikuara me komitetet në Git.
Konfigurimi përfundimtar dhe algoritmi i përgjithshëm
PĂ«rdoruesit nĂ« konfigurimin e pastrimit tani kanĂ« nĂ« dispozicion politika, sipas tĂ« cilave bĂ«het pĂ«rzgjedhja e imazheve tĂ« aktualizuara. Ădo politikĂ« e tillĂ« pĂ«rcaktohet nga:
- një grup referencesh, pra etiketa Git ose degë Git, që përdoren gjatë skanimit;
- dhe një kufi për imazhet në kërkim për çdo referencë nga grupi.
PĂ«r ilustrim â ja si e kanĂ« marrĂ« formĂ«n konfigurimet e politikave nĂ« mĂ«nyrĂ« nokle:
pastrimi:
mbajPolitika:
- referencat:
etiketë: \/.*\/\
kufiri:
i fundit: 10
- referencat:
dega: \/.*\/\
kufiri:
i fundit: 10
në: 168h
operatori: Dhe
imazhetPërReferencë:
i fundit: 2
në: 168h
operatori: Dhe
- referencat:
dega: \/^(main|staging|production)$\/\
imazhetPërReferencë:
i fundit: 10
Kjo konfigurim përmban tri politika, të cilat përputhen me rregullat e mëposhtme:
- Të ruhet imazhi për 10 etiketat Git të fundit (sipas datës së krijimit të etiketës).
- Ruaj deri në 2 imazhe të publikuara në javën e fundit, për deri në 10 degë me aktivitet në javën e fundit.
- Ruaj deri në 10 imazhe për degët
main,stagingdheproduction.
Algoritmi përfundimtar përbëhet nga hapat e mëposhtëm:
- Marrja e manifestimeve nga container registry.
- Përjashtimi i imazheve që përdoren në Kubernetes, pasi ato tashmë i kemi përzgjedhur duke marrë informacione nga K8s API.
- Skano historinë Git dhe përjashto imazhet sipas politikave të caktuara.
- Fshij imazhet e mbetura.
Duke iu kthyer ilustërimit tonë, ja çfarë ndodh me werf:

MegjithatĂ«, edhe nĂ«se nuk pĂ«rdorni werf, njĂ« qasje e ngjashme pĂ«r pastrimin e avancuar tĂ« imazheve â nĂ« njĂ« formĂ« apo tjetĂ«r (duke pĂ«rputhur me qasjen preferenciale pĂ«r etiketimin e imazheve) â mund tĂ« aplikohet edhe nĂ« sisteme ose mjete tĂ« tjera. Mjafton tĂ« mbani parasysh problemet qĂ« lindin dhe tĂ« gjeni mundĂ«sitĂ« nĂ« stakun tuaj qĂ« lejojnĂ« implementimin e zgjidhjes sĂ« tyre nĂ« mĂ«nyrĂ« sa mĂ« tĂ« qetĂ«. ShpresojmĂ« se rruga qĂ« kemi ndjekur do t'ju ndihmojĂ« tĂ« shikoni edhe rastin tuaj tĂ« veçantĂ« me detaje dhe mendime tĂ« reja.
Përfundimi
- Herët a vonë, shumica e ekipeve përballen me problemin e mbushjes së registry.
- Kur kërkoni zgjidhje, është thelbësore të përcaktoni kriteret e rëndësishmërisë së imazheve.
- Mjetet e ofruara nga shërbimet e njohura të regjistrimit të kontejnerëve lejojnë një pastrim shumë të thjeshtë, i cili nuk merr parasysh "botën e jashtme": imazhet që përdoren në Kubernetes dhe karakteristikat e proceseve të punës në ekip.
- Një algoritëm fleksibël dhe efikas duhet të ketë një kuptim të procesit CI/CD, duke operuar jo vetëm me të dhënat e imazheve Docker.
P.S.
Lexoni gjithashtu në blogun tonë:
- «»;
- «»;
- «»;
- «».
Burimi: habr.com
