{"id":96065,"date":"2020-10-07T13:42:09","date_gmt":"2020-10-07T11:42:09","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf"},"modified":"2020-10-07T13:42:09","modified_gmt":"2020-10-07T11:42:09","slug":"problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","title":{"rendered":"Problem z \"inteligentnym\" czyszczeniem obraz\u00f3w kontener\u00f3w oraz jego rozwi\u0105zanie w werf","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Problem z &quot;inteligentnym&quot; czyszczeniem obraz\u00f3w kontener\u00f3w oraz jego rozwi\u0105zanie w werf\" src=\"\/wp-content\/uploads\/2020\/10\/1410cea46bb8dcdc3ac06db11ed5a402.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nArtyku\u0142 omawia problematyk\u0119 usuwania obraz\u00f3w, kt\u00f3re gromadz\u0105 si\u0119 w rejestrach kontener\u00f3w (Docker Registry i jego odpowiednikach) w kontek\u015bcie nowoczesnych pipeline'\u00f3w CI\/CD dla aplikacji cloud native dostarczanych do Kubernetes. Przedstawiono g\u0142\u00f3wne kryteria aktualno\u015bci obraz\u00f3w oraz zwi\u0105zane z nimi trudno\u015bci przy automatyzacji czyszczenia, oszcz\u0119dzania miejsca i zaspokajania potrzeb zespo\u0142\u00f3w. Wreszcie, na przyk\u0142adzie konkretnego projektu Open Source przedstawimy, jak mo\u017cna przezwyci\u0119\u017cy\u0107 te trudno\u015bci.<\/p>\n<h2>Wprowadzenie<\/h2>\n<p>\nLiczba obraz\u00f3w w rejestrze kontener\u00f3w mo\u017ce szybko rosn\u0105\u0107, zajmuj\u0105c coraz wi\u0119cej miejsca w magazynie, a tym samym znacznie zwi\u0119kszaj\u0105c jego koszt. Aby kontrolowa\u0107, ogranicza\u0107 lub utrzymywa\u0107 akceptowalny wzrost zajmowanego miejsca w rejestrze, przyj\u0119to:<\/p>\n<ol>\n<li>u\u017cywa\u0107 sta\u0142ej liczby tag\u00f3w dla obraz\u00f3w;<\/li>\n<li>w jaki\u015b spos\u00f3b czy\u015bci\u0107 obrazy.<\/li>\n<\/ol>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nPierwsze ograniczenie jest czasami dopuszczalne dla ma\u0142ych zespo\u0142\u00f3w. Je\u015bli programi\u015bci wystarczaj\u0105co cz\u0119sto korzystaj\u0105 z sta\u0142ych tag\u00f3w (<code>latest<\/code>, <code>main<\/code>, <code>test<\/code>, <code>boris<\/code> itp.), rejestr nie b\u0119dzie si\u0119 powi\u0119ksza\u0142 w rozmiarze i przez d\u0142ugi czas mo\u017cna w og\u00f3le nie my\u015ble\u0107 o czyszczeniu. Wszystkie przestarza\u0142e obrazy s\u0105 nadpisywane, a do czyszczenia po prostu nie zostaje \u017cadna praca (wszystko robi standardowy zbieracz \u015bmieci).<\/p>\n<p>Jednak\u017ce takie podej\u015bcie znacznie ogranicza rozw\u00f3j i rzadko znajduje zastosowanie w CI\/CD nowoczesnych projekt\u00f3w. Niezb\u0119dnym elementem rozwoju sta\u0142a si\u0119 <strong>automatyzacja<\/strong>, kt\u00f3ra pozwala znacznie szybciej testowa\u0107, wdra\u017ca\u0107 i dostarcza\u0107 nowe funkcje u\u017cytkownikom. Na przyk\u0142ad, w naszych wszystkich projektach przy ka\u017cdym commitcie automatycznie tworzony jest pipeline CI. W nim zbierany jest obraz, testowany, wdra\u017cany do r\u00f3\u017cnych kontur\u00f3w Kubernetes do debugowania i pozosta\u0142ych kontroli, a je\u015bli wszystko dobrze \u2014 zmiany trafiaj\u0105 do ko\u0144cowego u\u017cytkownika. I to ju\u017c dawno przesta\u0142o by\u0107 rocket science, a sta\u0142o si\u0119 codzienno\u015bci\u0105 dla wielu \u2014 prawdopodobnie i dla Ciebie, skoro czytasz ten artyku\u0142.<\/p>\n<p>Poniewa\u017c eliminacja b\u0142\u0119d\u00f3w i rozw\u00f3j nowych funkcji odbywa si\u0119 r\u00f3wnolegle, a wydania mog\u0105 mie\u0107 miejsce kilka razy dziennie, oczywiste jest, \u017ce proces rozwoju towarzyszy znaczna liczba commit\u00f3w, a wi\u0119c \u2014 <strong>du\u017ca liczba obraz\u00f3w w rejestrze<\/strong>. W rezultacie, pilnie rodzi si\u0119 pytanie o organizacj\u0119 efektywnego czyszczenia rejestru, tzn. usuwania przestarza\u0142ych obraz\u00f3w.<\/p>\n<p>Jak w og\u00f3le okre\u015bli\u0107, czy obraz jest aktualny?<\/p>\n<h2>Kryteria aktualno\u015bci obrazu<\/h2>\n<p>\nW przewa\u017caj\u0105cej wi\u0119kszo\u015bci przypadk\u00f3w g\u0142\u00f3wne kryteria b\u0119d\u0105 nast\u0119puj\u0105ce:<\/p>\n<p>1. Pierwsze (najs\u0142ynniejsze i najbardziej krytyczne z wszystkich) \u2014 to obrazy, kt\u00f3re <strong>s\u0105 obecnie u\u017cywane w Kubernetes<\/strong>. Usuni\u0119cie tych obraz\u00f3w mo\u017ce prowadzi\u0107 do powa\u017cnych koszt\u00f3w zwi\u0105zanych z przestojami produkcji (na przyk\u0142ad obrazy mog\u0105 by\u0107 potrzebne podczas replikacji) lub uniewa\u017cni\u0107 wysi\u0142ki zespo\u0142u zajmuj\u0105cego si\u0119 debugowaniem w jednym z obszar\u00f3w. <i>(Z tego powodu stworzyli\u015bmy nawet specjalny <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/k8s-image-availability-exporter\"><i>eksporter Prometheus<\/i><\/a><\/noindex><i>, kt\u00f3ry monitoruje brak takich obraz\u00f3w w dowolnym klastrze Kubernetes.)<\/i><\/p>\n<p>2. Drugie (mniej oczywiste, ale r\u00f3wnie\u017c bardzo wa\u017cne i ponownie zwi\u0105zane z eksploatacj\u0105) \u2014 to obrazy, kt\u00f3re <strong>s\u0105 potrzebne do rollbacku w przypadku wykrycia powa\u017cnych problem\u00f3w<\/strong> w aktualnej wersji. Na przyk\u0142ad w przypadku Helm to obrazy, kt\u00f3re s\u0105 u\u017cywane w zapisanych wersjach release'u. (Swoj\u0105 drog\u0105, domy\u015blnie w Helm jest limit 256 rewizji, ale czy ktokolwiek naprawd\u0119 potrzebuje zachowa\u0107 <i>tak du\u017c\u0105<\/i> liczb\u0119 wersji?..) W ko\u0144cu przechowujemy wersje, aby mo\u017cna je by\u0142o p\u00f3\u017aniej wykorzysta\u0107, to znaczy 'wraca\u0107' do nich w razie potrzeby.<\/p>\n<p>3. Trzecie \u2014 <strong>potrzeby deweloper\u00f3w<\/strong>: wszystkie obrazy, kt\u00f3re s\u0105 zwi\u0105zane z ich aktualnymi pracami. Na przyk\u0142ad je\u015bli rozwa\u017camy PR, warto pozostawi\u0107 obraz, kt\u00f3ry odpowiada ostatniemu commitowi i powiedzmy poprzedniemu commitowi: dzi\u0119ki temu deweloper b\u0119dzie m\u00f3g\u0142 szybko powr\u00f3ci\u0107 do dowolnego zadania i pracowa\u0107 z najnowszymi zmianami. <\/p>\n<p>4. Czwarte \u2014 obrazy, kt\u00f3re <strong>odpowiadaj\u0105 wersjom naszej aplikacji<\/strong>, to znaczy s\u0105 ko\u0144cowym produktem: v1.0.0, 20.04.01, sierra itd.<\/p>\n<p>NB: Kryteria okre\u015blone tutaj zosta\u0142y sformu\u0142owane na podstawie do\u015bwiadcze\u0144 z pracy z dziesi\u0105tkami zespo\u0142\u00f3w deweloperskich z r\u00f3\u017cnych firm. Jednak oczywi\u015bcie w zale\u017cno\u015bci od charakterystyki proces\u00f3w deweloperskich i u\u017cywanej infrastruktury (na przyk\u0142ad, je\u015bli Kubernetes nie jest u\u017cywany), kryteria te mog\u0105 si\u0119 r\u00f3\u017cni\u0107. <\/p>\n<h2>Zgodno\u015b\u0107 z kryteriami i istniej\u0105ce rozwi\u0105zania<\/h2>\n<p>\nPopularne us\u0142ugi z rejestrem kontener\u00f3w zazwyczaj oferuj\u0105 w\u0142asne zasady usuwania obraz\u00f3w: mo\u017cna w nich okre\u015bla\u0107 warunki, na jakich tag jest usuwany z rejestru. Mo\u017cliwo\u015bci tych warunk\u00f3w ograniczaj\u0105 si\u0119 jednak do takich parametr\u00f3w, jak nazwy, czas utworzenia i liczba tag\u00f3w*.<\/p>\n<p><i>* Zale\u017cy to od konkretnych realizacji rejestru kontener\u00f3w. Rozwa\u017cali\u015bmy mo\u017cliwo\u015bci nast\u0119puj\u0105cych rozwi\u0105za\u0144: Azure CR, Docker Hub, ECR, GCR, GitHub Packages, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io \u2014 stan na wrzesie\u0144 2020.<\/i><\/p>\n<p>Taki zestaw parametr\u00f3w jest w zupe\u0142no\u015bci wystarczaj\u0105cy, aby spe\u0142ni\u0107 czwarty kryterium \u2014 czyli do selekcji obraz\u00f3w odpowiadaj\u0105cych wersjom. Jednak dla wszystkich pozosta\u0142ych kryteri\u00f3w trzeba wybiera\u0107 jakie\u015b kompromisowe rozwi\u0105zanie (bardziej rygorystyczn\u0105 lub, przeciwnie, \u0142agodniejsz\u0105 polityk\u0119) \u2014 w zale\u017cno\u015bci od oczekiwa\u0144 i mo\u017cliwo\u015bci finansowych.<\/p>\n<p>Na przyk\u0142ad trzecie kryterium \u2014 zwi\u0105zane z potrzebami deweloper\u00f3w \u2014 mo\u017cna rozwi\u0105za\u0107 poprzez organizacj\u0119 proces\u00f3w wewn\u0105trz zespo\u0142\u00f3w: specyficzne nazewnictwo obraz\u00f3w, prowadzenie specjalnych list dozwolonych oraz wewn\u0119trzne ustalenia. Ale ostatecznie to i tak trzeba zautomatyzowa\u0107. A je\u015bli mo\u017cliwo\u015bci gotowych rozwi\u0105za\u0144 s\u0105 niewystarczaj\u0105ce, trzeba stworzy\u0107 co\u015b w\u0142asnego.<\/p>\n<p>Podobna sytuacja dotyczy dw\u00f3ch pierwszych kryteri\u00f3w: nie mo\u017cna ich zaspokoi\u0107 bez uzyskania danych z zewn\u0119trznego systemu \u2014 tego samego, w kt\u00f3rym odbywa si\u0119 wdra\u017canie aplikacji (w naszym przypadku jest to Kubernetes).<\/p>\n<h3>Ilustracja workflow w Git<\/h3>\n<p>\nZak\u0142adaj\u0105c, \u017ce pracujesz mniej wi\u0119cej wed\u0142ug takiego schematu w Git:<\/p>\n<p><img decoding=\"async\" alt=\"Problem z &quot;inteligentnym&quot; czyszczeniem obraz\u00f3w kontener\u00f3w oraz jego rozwi\u0105zanie w werf\" src=\"\/wp-content\/uploads\/2020\/10\/45c9bfb6755da1b4d6be05b51ab17429.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<i>Ikona z g\u0142ow\u0105 na schemacie oznacza obrazy kontener\u00f3w, kt\u00f3re w danym momencie s\u0105 wdro\u017cone w Kubernetes dla jakichkolwiek u\u017cytkownik\u00f3w (u\u017cytkownik\u00f3w ko\u0144cowych, tester\u00f3w, mened\u017cer\u00f3w itd.) lub u\u017cywane przez deweloper\u00f3w do debugowania i podobnych cel\u00f3w.<\/i><\/p>\n<p>Co si\u0119 stanie, je\u015bli zasady usuwania pozwalaj\u0105 na pozostawienie (nieusuni\u0119cie) obraz\u00f3w tylko <b>po okre\u015blonych nazwach tag\u00f3w<\/b>?<\/p>\n<p><img decoding=\"async\" alt=\"Problem z &quot;inteligentnym&quot; czyszczeniem obraz\u00f3w kontener\u00f3w oraz jego rozwi\u0105zanie w werf\" src=\"\/wp-content\/uploads\/2020\/10\/e57ff24cb818799d28e8eb006aea2eb5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOczywi\u015bcie, taki scenariusz nikogo nie ucieszy.<\/p>\n<p>Co si\u0119 zmieni, je\u015bli zasady pozwalaj\u0105 na nieusuwanie obraz\u00f3w <b>po okre\u015blonym przedziale czasowym \/ liczbie ostatnich commit\u00f3w<\/b>?<\/p>\n<p><img decoding=\"async\" alt=\"Problem z &quot;inteligentnym&quot; czyszczeniem obraz\u00f3w kontener\u00f3w oraz jego rozwi\u0105zanie w werf\" src=\"\/wp-content\/uploads\/2020\/10\/7743581e6e64affb0a207ee156c00f6e.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWynik sta\u0142 si\u0119 znacznie lepszy, jednak wci\u0105\u017c jest daleki od idea\u0142u. Przecie\u017c mamy wci\u0105\u017c deweloper\u00f3w, kt\u00f3rzy potrzebuj\u0105 obraz\u00f3w w rejestrze (lub nawet wdro\u017conych w K8s) do debugowania b\u0142\u0119d\u00f3w\u2026<\/p>\n<p>Podsumowuj\u0105c sytuacj\u0119 na rynku: dost\u0119pne w rejestrach kontener\u00f3w funkcje nie oferuj\u0105 wystarczaj\u0105cej elastyczno\u015bci przy czyszczeniu, a g\u0142\u00f3wnym powodem jest <strong>brak mo\u017cliwo\u015bci interakcji ze \u015bwiatem zewn\u0119trznym<\/strong>. Okazuje si\u0119, \u017ce zespo\u0142y, kt\u00f3re potrzebuj\u0105 takiej elastyczno\u015bci, s\u0105 zmuszone do samodzielnego realizowania usuwania obraz\u00f3w \u201ena zewn\u0105trz\u201d, korzystaj\u0105c z Docker Registry API (lub natywnego API odpowiedniej implementacji).<\/p>\n<p>Szukali\u015bmy jednak uniwersalnego rozwi\u0105zania, kt\u00f3re automatyzowa\u0142oby czyszczenie obraz\u00f3w dla r\u00f3\u017cnych zespo\u0142\u00f3w korzystaj\u0105cych z r\u00f3\u017cnych rejestr\u00f3w\u2026<\/p>\n<h2>Nasza droga do uniwersalnego czyszczenia obraz\u00f3w<\/h2>\n<p>\nSk\u0105d taka potrzeba? Sprawa polega na tym, \u017ce nie jeste\u015bmy oddzieln\u0105 grup\u0105 programist\u00f3w, ale zespo\u0142em, kt\u00f3ry obs\u0142uguje wiele takich grup, pomagaj\u0105c kompleksowo rozwi\u0105zywa\u0107 problemy CI\/CD. A g\u0142\u00f3wnym narz\u0119dziem technicznym w tym celu jest Open Source-owa aplikacja <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.werf.io\/\">werf<\/a><\/noindex>. Jej cech\u0105 charakterystyczn\u0105 jest to, \u017ce nie wykonuje jednej funkcji, ale towarzyszy procesom ci\u0105g\u0142ej dostawy na wszystkich etapach: od budowy po wdro\u017cenie.<\/p>\n<p>Publikacja w rejestrze* obraz\u00f3w (zaraz po ich zbudowaniu) \u2014 oczywista funkcja takiej aplikacji. A poniewa\u017c obrazy s\u0105 tam przechowywane, to \u2014 je\u017celi twoje miejsce przechowywania nie jest nieograniczone \u2014 musisz r\u00f3wnie\u017c odpowiada\u0107 za ich p\u00f3\u017aniejsze czyszczenie. O tym, jak osi\u0105gn\u0119li\u015bmy sukces w tej kwestii, spe\u0142niaj\u0105c wszystkie zadane kryteria, b\u0119dzie mowa dalej.<\/p>\n<p><i>* Chocia\u017c same rejestry mog\u0105 by\u0107 r\u00f3\u017cne (Docker Registry, GitLab Container Registry, Harbor itp.), ich u\u017cytkownicy napotykaj\u0105 te same problemy. Uniwersalne rozwi\u0105zanie w naszym przypadku nie zale\u017cy od implementacji rejestru, poniewa\u017c wykonuje si\u0119 poza samymi rejestrami i oferuje jednolite zachowanie dla wszystkich.<\/i><\/p>\n<p>Mimo \u017ce u\u017cywamy werf jako przyk\u0142ad implementacji, mamy nadziej\u0119, \u017ce zastosowane podej\u015bcia b\u0119d\u0105 przydatne r\u00f3wnie\u017c innym zespo\u0142om, kt\u00f3re napotka\u0142y podobne trudno\u015bci.<\/p>\n<p>Zaj\u0119li\u015bmy si\u0119 <i>zewn\u0119trzn\u0105<\/i> implementacj\u0105 mechanizmu do czyszczenia obraz\u00f3w \u2014 zamiast tych mo\u017cliwo\u015bci, kt\u00f3re s\u0105 ju\u017c wbudowane w rejestry dla kontener\u00f3w. Pierwszym krokiem by\u0142o u\u017cycie Docker Registry API do stworzenia tych samych prostych polityk dotycz\u0105cych liczby tag\u00f3w i czasu ich stworzenia (wspomnianych wcze\u015bniej). Do nich dodano <strong>list\u0119 dozwolon\u0105 na podstawie obraz\u00f3w u\u017cywanych w wdro\u017conej infrastrukturze<\/strong>, czyli Kubernetes. Dla tego ostatniego wystarczy\u0142o, aby przeszuka\u0107 wszystkie wdro\u017cone zasoby za pomoc\u0105 Kubernetes API i uzyska\u0107 list\u0119 warto\u015bci. <code>image<\/code>.<\/p>\n<p>To trywialne rozwi\u0105zanie zamkn\u0119\u0142o najwa\u017cniejszy problem (kryterium nr 1), ale by\u0142o tylko pocz\u0105tkiem naszej drogi do poprawy mechanizmu oczyszczania. Kolejnym \u2014 i znacznie ciekawszym \u2014 krokiem by\u0142o rozwi\u0105zanie <strong>po\u0142\u0105czenia publikowanych obraz\u00f3w z histori\u0105 Git.<\/strong>.<\/p>\n<h3>Schematy tagowania<\/h3>\n<p>\nNa pocz\u0105tek wybrali\u015bmy podej\u015bcie, w kt\u00f3rym ko\u0144cowy obraz musi przechowywa\u0107 niezb\u0119dne informacje do oczyszczania, i opracowali\u015bmy proces oparty na schematach tagowania. Podczas publikacji obrazu u\u017cytkownik wybiera\u0142 okre\u015blon\u0105 opcj\u0119 tagowania (<code>git-branch<\/code>, <code>git-commit<\/code> lub <code>git-tag<\/code>) i u\u017cywa\u0142 odpowiedniej warto\u015bci. W systemach CI te warto\u015bci by\u0142y ustawiane automatycznie na podstawie zmiennych \u015brodowiskowych. W istocie <strong>ko\u0144cowy obraz by\u0142 powi\u0105zany z okre\u015blonym Gitem-prymitywem<\/strong>, przechowuj\u0105c niezb\u0119dne dane do oczyszczania w etykietach.<\/p>\n<p>W ramach tego podej\u015bcia powsta\u0142 zbi\u00f3r polityk, kt\u00f3re pozwala\u0142y u\u017cywa\u0107 Git jako jedynego \u017ar\u00f3d\u0142a prawdy:<\/p>\n<ul>\n<li>Przy usuwaniu ga\u0142\u0119zi\/tagu w Git automatycznie usuwane by\u0142y r\u00f3wnie\u017c powi\u0105zane obrazy w rejestrze.<\/li>\n<li>Liczb\u0119 obraz\u00f3w powi\u0105zanych z tagami i commitami Git mo\u017cna by\u0142o regulowa\u0107 liczb\u0105 tag\u00f3w u\u017cytych w wybranym schemacie i czasem utworzenia powi\u0105zanego commita.<\/li>\n<\/ul>\n<p>\nOg\u00f3lnie rzecz bior\u0105c, zrealizowane rozwi\u0105zanie spe\u0142nia\u0142o nasze potrzeby, ale wkr\u00f3tce czeka\u0142o nas nowe wyzwanie. Ot\u00f3\u017c w czasie korzystania ze schemat\u00f3w tagowania wed\u0142ug prymityw\u00f3w Git napotkali\u015bmy szereg wad. <i>(Poniewa\u017c ich opis wykracza poza temat tego artyku\u0142u, wszyscy ch\u0119tni mog\u0105 zapozna\u0107 si\u0119 ze szczeg\u00f3\u0142ami <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/495112\/\"><i>tutaj<\/i><\/a><\/noindex><i>.)<\/i> Dlatego, decyduj\u0105c si\u0119 na przej\u015bcie do bardziej efektywnego podej\u015bcia do tagowania (tagowanie oparte na tre\u015bci), musieli\u015bmy przeanalizowa\u0107 r\u00f3wnie\u017c wdro\u017cenie oczyszczania obraz\u00f3w.<\/p>\n<h3>Nowy algorytm<\/h3>\n<p>\nDlaczego? Przy tagowaniu na podstawie tre\u015bci ka\u017cdy tag mo\u017ce odpowiada\u0107 wielu commitom w Git. Przy oczyszczaniu obraz\u00f3w nie mo\u017cna ju\u017c wyj\u015b\u0107 <i>tylko<\/i> z commita, na kt\u00f3rym nowy tag zosta\u0142 dodany do rejestru.<\/p>\n<p>Dla nowego algorytmu oczyszczania zdecydowano si\u0119 odej\u015b\u0107 od schemat\u00f3w tagowania i zbudowa\u0107 <strong>proces na meta-obrazach<\/strong>, z kt\u00f3rych ka\u017cdy przechowuje powi\u0105zanie z:<\/p>\n<ul>\n<li>komita, na kt\u00f3rym przeprowadzono publikacj\u0119 (przy czym nie ma znaczenia, czy dodano, zmieniono, czy pozostawiono dotychczasowy obraz w rejestrze kontener\u00f3w);<\/li>\n<li>i naszego wewn\u0119trznego identyfikatora, odpowiadaj\u0105cego zbudowanemu obrazowi.<\/li>\n<\/ul>\n<p>\nInnymi s\u0142owy, zapewniono <strong>powi\u0105zanie publikowanych tag\u00f3w z komitami w Git<\/strong>.<\/p>\n<h3>Finalna konfiguracja i og\u00f3lny algorytm<\/h3>\n<p>\nU\u017cytkownikom przy konfiguracji czyszczenia udost\u0119pnione zosta\u0142y polityki, wed\u0142ug kt\u00f3rych wybierane s\u0105 aktualne obrazy. Ka\u017cda taka polityka definiowana jest przez:<\/p>\n<ul>\n<li>wiele referencji, tj. Git-tag\u00f3w lub ga\u0142\u0119zi Git, kt\u00f3re s\u0105 u\u017cywane podczas skanowania;<\/li>\n<li>oraz limitem wyszukiwanych obraz\u00f3w dla ka\u017cdej referencji z tego zestawu.<\/li>\n<\/ul>\n<p>\nDla ilustracji \u2014 oto jak wygl\u0105da\u0142a konfiguracja polityk domy\u015blnych:<\/p>\n<pre><code class=\"plaintext\">cleanup:\n  keepPolicies:\n  - references:\n      tag: \\\/.*\\\/ \n      limit:\n        last: 10\n  - references:\n      branch: \\\/.*\\\/ \n      limit:\n        last: 10\n        in: 168h\n        operator: And\n    imagesPerReference:\n      last: 2\n      in: 168h\n      operator: And\n  - references:  \n      branch: \\\/^(main|staging|production)$\\\/ \n    imagesPerReference:\n      last: 10\n<\/code><\/pre>\n<p>\nTaka konfiguracja zawiera trzy polityki, kt\u00f3re odpowiadaj\u0105 nast\u0119puj\u0105cym zasadom:<\/p>\n<ol>\n<li>Zachowywa\u0107 obraz dla 10 ostatnich Git-tag\u00f3w (wed\u0142ug daty utworzenia tagu).<\/li>\n<li>Zachowywa\u0107 nie wi\u0119cej ni\u017c 2 obrazy opublikowane w ci\u0105gu ostatniego tygodnia, dla nie wi\u0119cej ni\u017c 10 ga\u0142\u0119zi z aktywno\u015bci\u0105 w ci\u0105gu ostatniego tygodnia.<\/li>\n<li>Zachowywa\u0107 po 10 obraz\u00f3w dla ga\u0142\u0119zi <code>main<\/code>, <code>staging<\/code> i <code>production<\/code>.<\/li>\n<\/ol>\n<p>\nOstateczny algorytm sprowadza si\u0119 do nast\u0119puj\u0105cych krok\u00f3w:<\/p>\n<ul>\n<li>Pobranie manife\u015bcie z rejestru kontener\u00f3w.<\/li>\n<li>Wykluczenie obraz\u00f3w u\u017cywanych w Kubernetes, poniewa\u017c zosta\u0142y ju\u017c uprzednio przefiltrowane, pytaj\u0105c K8s API.<\/li>\n<li>Skanowanie historii Git i wykluczenie obraz\u00f3w wed\u0142ug zadanych polityk.<\/li>\n<li>Usuni\u0119cie pozosta\u0142ych obraz\u00f3w.<\/li>\n<\/ul>\n<p>\nWracaj\u0105c do naszej ilustracji, oto co otrzymujemy z werf:<\/p>\n<p><img decoding=\"async\" alt=\"Problem z &quot;inteligentnym&quot; czyszczeniem obraz\u00f3w kontener\u00f3w oraz jego rozwi\u0105zanie w werf\" src=\"\/wp-content\/uploads\/2020\/10\/c453092dca23860a0dda604843845507.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJednak\u017ce, nawet je\u015bli nie u\u017cywasz werf, podobne podej\u015bcie do zaawansowanego czyszczenia obraz\u00f3w \u2014 w takiej lub innej formie (zgodnie z preferowanym podej\u015bciem do tagowania obraz\u00f3w) \u2014 mo\u017ce by\u0107 stosowane tak\u017ce w innych systemach\/narz\u0119dziach. Wystarczy pami\u0119ta\u0107 o problemach, kt\u00f3re si\u0119 pojawiaj\u0105, i znale\u017a\u0107 te mo\u017cliwo\u015bci w twoim stosie, kt\u00f3re pozwalaj\u0105 na jak najszybsze wbudowanie ich rozwi\u0105zania. Mamy nadziej\u0119, \u017ce droga, kt\u00f3r\u0105 przeszli\u015bmy, pomo\u017ce spojrze\u0107 na tw\u00f3j przypadek z nowymi szczeg\u00f3\u0142ami i pomys\u0142ami.<\/p>\n<h2>Podsumowanie<\/h2>\n<p><\/p>\n<ul>\n<li>Pr\u0119dzej czy p\u00f3\u017aniej z problemem przepe\u0142nienia rejestru boryka si\u0119 wi\u0119kszo\u015b\u0107 zespo\u0142\u00f3w. <\/li>\n<li>Podczas poszukiwania rozwi\u0105za\u0144 najpierw nale\u017cy okre\u015bli\u0107 kryteria aktualno\u015bci obrazu.<\/li>\n<li>Narz\u0119dzia oferowane przez popularne serwisy rejestru kontener\u00f3w umo\u017cliwiaj\u0105 bardzo prost\u0105 procedur\u0119 czyszczenia, kt\u00f3ra nie uwzgl\u0119dnia \u201ezewn\u0119trznego \u015bwiata\u201d: obrazy u\u017cywane w Kubernetes oraz cechy proces\u00f3w roboczych w zespole.<\/li>\n<li>Elastyczny i efektywny algorytm musi mie\u0107 poj\u0119cie o procesach CI\/CD i operowa\u0107 nie tylko na danych obraz\u00f3w Docker.<\/li>\n<\/ul>\n<p><\/p>\n<h2>P.S.<\/h2>\n<p>\nPrzeczytaj tak\u017ce na naszym blogu:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/495112\/\">Tagowanie oparte na zawarto\u015bci w zbieraczu werf: po co i jak to dzia\u0142a?<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/476646\/\">Fuzja 3-way w werf: wdro\u017cenie w Kubernetes z Helm \u201ena sterydach\u201d<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465131\/\">Wsparcie dla monorepo i multirepo w werf i jakie ma to znaczenie dla Docker Registry<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/493170\/\">Wydanie werf 1.1: ulepszenia w kompilatorze oraz plany na przysz\u0142o\u015b\u0107.<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/522024\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0442\u0438\u043a\u0430 \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0440\u0435\u0435\u0441\u0442\u0440\u0430\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 (Docker Registry \u0438 \u0435\u0433\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0430\u0445) \u0432 \u0440\u0435\u0430\u043b\u0438\u044f\u0445 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 CI\/CD-\u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u043e\u0432 \u0434\u043b\u044f cloud native-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0432 Kubernetes. \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u0438 \u0432\u044b\u0442\u0435\u043a\u0430\u044e\u0449\u0438\u0435 \u0438\u0437 \u043d\u0438\u0445 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0447\u0438\u0441\u0442\u043a\u0438, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0441\u0442\u0430 \u0438 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044f\u043c \u043a\u043e\u043c\u0430\u043d\u0434. \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e Open Source-\u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u044d\u0442\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":96066,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-96065","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u00ab\u0443\u043c\u043d\u043e\u0439\u00bb \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u0435\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 werf | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-10-07T11:42:09+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-10-07T11:42:09+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Problem \u201einteligentnego\u201d czyszczenia obraz\u00f3w kontener\u00f3w oraz jego rozwi\u0105zanie w werf | ProHoster","description":"W artykule om\u00f3wiono.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u00ab\u0443\u043c\u043d\u043e\u0439\u00bb \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u0435\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 werf | ProHoster","og:description":"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-10-07T11:42:09+00:00","article:modified_time":"2020-10-07T11:42:09+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"96065","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 10:52:24","updated":"2022-10-01 08:58:07","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/96065","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=96065"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/96065\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/96066"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=96065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=96065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=96065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}