A konténerképek "okos" tisztításának problémája és megoldása a werf-ben

A konténerképek "okos" tisztításának problémája és megoldása a werf-ben

A cikk a konténer-nyilvántartásokban (Docker Registry és analógjai) felhalmozódó képek tisztításának problémáit tárgyalja a Kubernetesnek szállított, felhőalapú natív alkalmazások modern CI/CD-folyamatainak valóságában. Adva vannak a képek relevanciájának fő kritériumai és az ebből adódó nehézségek a takarítás automatizálásában, a helytakarékosságban és a csapatok igényeinek kielégítésében. Végül egy konkrét nyílt forráskódú projekt példáján elmondjuk, hogyan lehet ezeket a nehézségeket leküzdeni.

Bevezetés

A konténer-nyilvántartásban lévő képek száma gyorsan növekedhet, több tárhelyet foglalva, és ezáltal jelentősen megnövelheti a költségeket. A rendszerleíró adatbázisban elfoglalt terület elfogadható növekedésének szabályozása, korlátozása vagy fenntartása elfogadott:

  1. fix számú címkét használjon a képekhez;
  2. valamilyen módon tisztítsa meg a képeket.


Az első korlátozás néha elfogadható kis csapatok számára. Ha a fejlesztőknek elegendő állandó címkéjük van (latest, main, test, boris stb.), a rendszerleíró adatbázis mérete nem duzzad, és sokáig nem kell a tisztítására gondolnia. Végül is minden irreleváns kép törlődik, és egyszerűen nem marad munka a tisztításra (mindent egy rendes szemétgyűjtő végez).

Ez a megközelítés azonban nagymértékben korlátozza a fejlesztést, és ritkán alkalmazható a modern CI/CD projekteknél. A fejlesztés szerves része volt automatizálás, amely lehetővé teszi az új funkciók sokkal gyorsabb tesztelését, üzembe helyezését és a felhasználókhoz való eljuttatását. Például minden projektünkben minden véglegesítéssel automatikusan létrejön egy CI-folyamat. Ebben a képet összeállítják, tesztelik, kigörgetik a különböző Kubernetes áramkörökre a hibakereséshez és a fennmaradó ellenőrzésekhez, és ha minden rendben van, a változtatások eljutnak a végfelhasználóhoz. És ez már nem rakétatudomány, hanem sokak mindennapi jelensége – nagy valószínűséggel az Ön számára, hiszen ezt a cikket olvassa.

Mivel a hibák kijavítása és az új funkciók fejlesztése párhuzamosan történik, és a kiadások naponta többször is végrehajthatók, nyilvánvaló, hogy a fejlesztési folyamatot jelentős számú commit kíséri, ami azt jelenti, hogy nagy számú kép a rendszerleíró adatbázisban. Ennek eredményeként felmerül a rendszerleíró adatbázis hatékony tisztításának megszervezésének kérdése, i.e. az irreleváns képek eltávolítása.

De hogyan lehet megállapítani, hogy egy kép releváns-e?

A kép relevanciájának kritériumai

Az esetek túlnyomó többségében a fő kritériumok a következők:

1. Az első (a legnyilvánvalóbb és legkritikusabb mind közül) azok a képek, amelyek jelenleg Kubernetesben használják. Ezeknek a lemezképeknek az eltávolítása jelentős termelési leállási költségeket eredményezhet (például szükség lehet a lemezképekre a replikációhoz), vagy meghiúsítja a csapat bármely cikluson végzett hibakeresési erőfeszítését. (Ezért még egy különlegeset is készítettünk Prometheus exportőrök, amely nyomon követi az ilyen képek hiányát bármely Kubernetes-fürtben.)

2. Második (kevésbé nyilvánvaló, de szintén nagyon fontos, és ismét a kizsákmányolással kapcsolatos) - olyan képek, amelyek súlyos problémák észlelése esetén szükséges a visszaállításhoz a jelenlegi verzióban. Például a Helm esetében ezek olyan képek, amelyeket a kiadás mentett verziói használnak. (Mellesleg a Helmben alapértelmezés szerint 256 revízió a határ, de nem valószínű, hogy valakinek tényleg mentenie kell ilyen a nagyszámú változat?..) Hiszen mi különösen azért tároljuk a verziókat, hogy később felhasználhassuk, pl. „visszatekerjük” hozzájuk, ha szükséges.

3. Harmadik - fejlesztői igények: Minden kép, amely az aktuális munkájukhoz kapcsolódik. Például, ha PR-t fontolgatunk, akkor érdemes az utolsó és mondjuk az előző commitnak megfelelő képet hagyni: így a fejlesztő gyorsan visszatérhet bármilyen feladathoz, és a legújabb változtatásokkal dolgozhat.

4. Negyedszer - képek, amelyek megfelelnek az alkalmazásunk verzióinak, azaz a végtermékek: v1.0.0, 20.04.01/XNUMX/XNUMX, sierra stb.

Megjegyzés: Az itt meghatározott kritériumokat a különböző cégek tucatnyi fejlesztőcsapatával való együttműködés során szerzett tapasztalatok alapján fogalmaztuk meg. Természetesen a fejlesztési folyamatok sajátosságaitól és a használt infrastruktúrától függően (például a Kubernetes nem használatos) ezek a kritériumok eltérőek lehetnek.

Jogosultság és meglévő megoldások

A konténer-nyilvántartásokkal rendelkező népszerű szolgáltatások általában saját képtisztítási házirendeket kínálnak: ezekben meghatározhatja, hogy milyen feltételek mellett távolítsa el a címkéket a rendszerleíró adatbázisból. Ezeket a feltételeket azonban olyan paraméterek korlátozzák, mint a nevek, a létrehozási idő és a címkék száma*.

* Az adott tárolóregiszter-megvalósításoktól függ. A következő megoldások lehetőségeit mérlegeltük: Azure CR, Docker Hub, ECR, GCR, GitHub Packages, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io – 2020 szeptemberétől.

Ez a paraméterkészlet elegendő a negyedik feltétel teljesítéséhez - vagyis a verzióknak megfelelő képek kiválasztásához. Az összes többi kritériumhoz azonban valamilyen kompromisszumos megoldást kell választani (keményebb vagy éppen ellenkezőleg, engedékenyebb politika) - az elvárásoktól és a pénzügyi lehetőségektől függően.

Például a harmadik - fejlesztői igényekhez kapcsolódó - kritérium megoldható csapaton belüli folyamatok szervezésével: képek konkrét elnevezése, speciális engedélyezési listák és belső megállapodások vezetése. De végül még mindig automatizálni kell. Ha pedig a kész megoldások képességei nem elegendőek, akkor valamit saját kezűleg kell csinálni.

Hasonló a helyzet az első két feltétellel: nem teljesíthetők anélkül, hogy egy külső rendszertől nem kapnának adatokat - attól, ahol az alkalmazásokat telepítik (esetünkben a Kubernetes).

A Git munkafolyamatának illusztrációja

Tegyük fel, hogy valami ilyesmit dolgozol a Gitben:

A konténerképek "okos" tisztításának problémája és megoldása a werf-ben

A diagramon egy fejjel ellátott ikon azokat a tárolóképeket jelöli, amelyek jelenleg a Kubernetesben vannak telepítve bármely felhasználó (végfelhasználók, tesztelők, menedzserek stb.) számára, vagy amelyeket a fejlesztők hibakeresésre és hasonló célokra használnak.

Mi történik, ha a tisztítási házirendek csak a képek megőrzését teszik lehetővé (nem törlését) megadott címkenevek szerint?

A konténerképek "okos" tisztításának problémája és megoldása a werf-ben

Nyilvánvalóan egy ilyen forgatókönyv senkit sem tesz boldoggá.

Mi fog megváltozni, ha a házirendek megengedik, hogy a képeket ne töröljék? adott időintervallum szerint / az utolsó commitok száma szerint?

A konténerképek "okos" tisztításának problémája és megoldása a werf-ben

Az eredmény sokkal jobb lett, de még mindig messze van az ideálistól. Elvégre még mindig vannak fejlesztőink, akiknek a rendszerleíró adatbázisban (vagy akár a K8s-ban telepített) képekre van szükségük a hibák elhárításához...

Összefoglalva a jelenlegi piaci helyzetet: a konténernyilvántartásokban elérhető funkciók nem nyújtanak kellő rugalmasságot a tisztítás során, ennek fő oka az, hogy nincs mód a külvilággal való érintkezésre. Kiderült, hogy az ilyen rugalmasságot igénylő csapatok kénytelenek önállóan végrehajtani a képtörlést „kívülről”, a Docker Registry API-val (vagy a megfelelő megvalósítás natív API-jával).

Azonban olyan univerzális megoldást kerestünk, amely automatizálná a képtisztítást a különböző csapatok számára, különböző nyilvántartásokat használva...

Útunk az univerzális képtisztítás felé

Honnan ez az igény? A helyzet az, hogy nem egy különálló fejlesztői csoportot alkotunk, hanem egy csapatot, amely sokukat egyszerre szolgálja ki, segítve a CI/CD problémák átfogó megoldását. Ennek fő technikai eszköze pedig a nyílt forráskódú segédprogram werf. Különlegessége, hogy nem egyetlen funkciót lát el, hanem végigkíséri a folyamatos szállítási folyamatokat minden szakaszban: az összeszereléstől a telepítésig.

A képek közzététele a rendszerleíró adatbázisban* (közvetlenül a létrehozásuk után) egy ilyen segédprogram nyilvánvaló funkciója. És mivel a képek tárolás céljából ott vannak elhelyezve, így - ha nem korlátlan a tárhelye - Önnek kell felelnie azok utólagos tisztításáért. Hogy miként értünk el ebben az összes meghatározott kritériumnak megfelelő sikert, arról a továbbiakban szó lesz.

* Bár maguk a nyilvántartások eltérőek lehetnek (Docker Registry, GitLab Container Registry, Harbor stb.), felhasználóik ugyanazokkal a problémákkal szembesülnek. Az univerzális megoldás esetünkben nem a registry megvalósításától függ, mert magán a nyilvántartásokon kívül fut, és mindenki számára ugyanazt a viselkedést kínálja.

Noha példaként a werf-et használjuk, reméljük, hogy az alkalmazott megközelítések hasznosak lesznek más, hasonló nehézségekkel küzdő csapatok számára.

Szóval elfoglaltak lettünk külső a képek tisztítására szolgáló mechanizmus megvalósítása - a tárolók nyilvántartásaiba már beépített képességek helyett. Az első lépés az volt, hogy a Docker Registry API-val ugyanazokat a primitív házirendeket hozzuk létre a címkék számára és létrehozásuk idejére vonatkozóan (a fent említett). Hozzájuk adva engedélyezési lista a telepített infrastruktúrában használt képek alapján, azaz Kubernetes. Utóbbihoz elég volt a Kubernetes API használata az összes telepített erőforrás iterálásához és az értékek listájának megszerzéséhez. image.

Ez a triviális megoldás megoldotta a legkritikusabb problémát (1. kritérium), de csak a kezdete volt a tisztítási mechanizmus fejlesztésére irányuló utunknak. A következő – és sokkal érdekesebb – lépés a döntés volt társítani a közzétett képeket a Git előzményeivel.

Címkézési sémák

Kezdetnek olyan megközelítést választottunk, amelyben a végső kép tárolja a tisztításhoz szükséges információkat, és a folyamatot címkézési sémákra építettük. A kép közzétételekor a felhasználó egy adott címkézési lehetőséget választott (git-branch, git-commit vagy git-tag), és a megfelelő értéket használta. A CI rendszerekben ezeket az értékeket a környezeti változók alapján automatikusan beállították. Valójában a végső képet egy adott Git primitívhez társították, a tisztításhoz szükséges adatok tárolása címkéken.

Ez a megközelítés olyan irányelveket eredményezett, amelyek lehetővé tették, hogy a Git az igazság egyetlen forrása legyen:

  • Amikor töröl egy ágat/címkét a Gitben, a rendszerleíró adatbázisban lévő kapcsolódó képek automatikusan törlődnek.
  • A Git címkékkel és véglegesítésekkel társított képek száma a kiválasztott sémában használt címkék számával és a kapcsolódó véglegesítés létrehozásának időpontjával szabályozható.

Az így létrejött megvalósítás összességében kielégítette igényeinket, de hamarosan új kihívás várt ránk. A helyzet az, hogy a Git primitíveken alapuló címkézési sémák használata során számos hiányossággal találkoztunk. (Mivel leírásuk túlmutat jelen cikk keretein, mindenki megismerkedhet a részletekkel itt.) Ezért, miután úgy döntöttünk, hogy a címkézés hatékonyabb megközelítésére (tartalom alapú címkézés) váltunk, át kellett gondolnunk a képtisztítás megvalósítását.

Új algoritmus

Miért? A tartalom alapú címkézéssel minden címke több véglegesítést is teljesíthet a Gitben. A képek tisztítása során már nem feltételezheti csak a véglegesítésből, ahol az új címkét hozzáadták a rendszerleíró adatbázishoz.

Az új tisztítási algoritmus esetében úgy döntöttek, hogy elhagyják a címkézési sémákat és építenek meta-kép folyamat, amelyek mindegyike a következőket tárolja:

  • a véglegesítés, amelyen a közzétételt végrehajtották (nem számít, hogy a képet hozzáadták, megváltoztatták vagy változatlan maradt a tároló nyilvántartásában);
  • és az összeállított képnek megfelelő belső azonosítónkat.

Más szóval, megadták a közzétett címkék összekapcsolása a Git-ben végzett véglegesítésekkel.

Végső konfiguráció és általános algoritmus

A tisztítás konfigurálásakor a felhasználók hozzáférhetnek az aktuális képeket kiválasztó házirendekhez. Minden ilyen szabályzat meghatározása:

  • sok hivatkozás, pl. A vizsgálat során használt Git-címkék vagy Git-ágak;
  • és a keresett képek korlátja a készletből származó egyes hivatkozásokhoz.

Szemléltetésképpen a következőképpen kezdett kinézni az alapértelmezett házirend-konfiguráció:

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

Ez a konfiguráció három irányelvet tartalmaz, amelyek megfelelnek a következő szabályoknak:

  1. Mentse el a képet az utolsó 10 Git-címkéhez (a címke létrehozásának dátuma szerint).
  2. Legfeljebb 2, az elmúlt héten közzétett képet mentsen el legfeljebb 10 olyan szálhoz, amelyek aktivitása az elmúlt héten volt.
  3. Mentse el 10 képet az ágakhoz main, staging и production.

A végső algoritmus a következő lépésekből áll:

  • Manifestek lekérése a tároló-nyilvántartásból.
  • Kivéve a Kubernetesben használt képeket, mert Már előre kiválasztottuk őket a K8s API lekérdezésével.
  • A Git-előzmények vizsgálata és a képek kizárása meghatározott házirendek alapján.
  • A fennmaradó képek eltávolítása.

Visszatérve az illusztrációnkhoz, a werf esetében ez történik:

A konténerképek "okos" tisztításának problémája és megoldása a werf-ben

Azonban még ha nem is használ werf-et, a fejlett képtisztítás hasonló megközelítése - egyik vagy másik megvalósításban (a képcímkézés preferált megközelítése szerint) - más rendszerekre/segédprogramokra is alkalmazható. Ehhez elegendő emlékezni a felmerülő problémákra, és megtalálni azokat a lehetőségeket a veremben, amelyek lehetővé teszik a megoldások lehető legzökkenőmentesebb integrálását. Reméljük, hogy az általunk bejárt út segít új részletekkel és gondolatokkal szemlélni konkrét esetét.

Következtetés

  • Előbb-utóbb a legtöbb csapat szembesül a rendszerleíró adatbázis túlcsordulási problémájával.
  • A megoldások keresése során először meg kell határozni a kép relevanciájának kritériumait.
  • A népszerű konténernyilvántartó szolgáltatások által kínált eszközök lehetővé teszik egy nagyon egyszerű takarítás megszervezését, amely nem veszi figyelembe a „külvilágot”: a Kubernetesben használt képeket és a csapat munkafolyamatainak sajátosságait.
  • Egy rugalmas és hatékony algoritmusnak ismernie kell a CI/CD folyamatokat, és nem csak a Docker képadatokkal kell működnie.

PS

Olvassa el blogunkon is:

Forrás: will.com

Hozzászólás