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

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

A cikk a konténerképek tisztításának problémáit tárgyalja, amelyek a konténerregiszterekben (Docker Registry és hasonlók) halmozódnak fel a modern CI/CD folyamatok valóságában, a Kubernetes-ben szolgáltatott cloud native alkalmazások esetében. Ismerteti a képek relevanciájának fő kritériumait, valamint az ezekből származó nehézségeket az automatizált tisztítás, a helymegtakarítás és a csapatok igényeinek kielégítése során. Végül egy konkrét Open Source projekt példáján bemutatjuk, hogyan lehet ezeket a nehézségeket leküzdeni.

Bevezetés

A konténerregiszterben tárolt képek száma gyorsan növekedhet, egyre több helyet foglalva el a tárolóban, ami ennek megfelelően jelentősen növeli a költségeit is. Az elfogadható terjedés ellenőrzésére, korlátozására vagy fenntartására a registry leegyszerűsítését szokták alkalmazni:

  1. rögzített számú címke használata a képekhez;
  2. valamilyen módon a képek tisztítása.


Az első korlátozás néha megengedett kisebb csapatok számára. Ha a fejlesztőknek elegendő a folyamatos címkék (latest, main, teszt, boris és hasonlók), a regiszter nem fog megnőni, és hosszú időn keresztül egyáltalán nem kell gondolkodni a tisztításon. Mivel az összes elavult kép felülíródik, a tisztításhoz egyszerűen nem marad munka (minden automatikusan a beépített szemétgyűjtő által történik).

Mindazonáltal ez a megközelítés erősen korlátozza a fejlesztést, és ritkán alkalmazható a modern projektek CI/CD folyamataiban. A fejlesztés elengedhetetlen részévé vált a automatizálás, amely lehetővé teszi az új funkciók sokkal gyorsabb tesztelését, telepítését és felhasználókhoz való eljuttatását. Például nálunk minden projektben minden egyes commitnál automatikusan létrejön egy CI-pipe. Ebben a képet összegyűjtik, tesztelik, különböző Kubernetes-környezetekbe telepítik hibakeresés és további ellenőrzések céljából, és ha minden rendben van, a változások eljutnak a végfelhasználóhoz. Ez már régen nem rocket science, hanem a mindennapi élet része sokak számára — valószínűleg Önnek is, hiszen ezt a cikket olvassa.

Mivel a hibák javítása és az új funkciók fejlesztése párhuzamosan zajlik, és a kiadások akár naponta többször is végrehajthatók, nyilvánvaló, hogy a fejlesztési folyamatot jelentős számú commit kíséri, tehát — nagy számú kép a registry-benEzért fontos kérdéssé válik az effektív registry-tisztítás megszervezése, azaz a nem aktuális képek törlése.

De hogyan lehet egyáltalán meghatározni, hogy aktuális-e egy kép?

A kép aktualitásának kritériumai

A legtöbb esetben a fő kritériumok a következők lesznek:

1. Az első (a legnyilvánvalóbb és legkritikusabb) — azok a képek, amelyek jelenleg Kubernetes-ben használva vannak.Ezeknek a képeknek a törlése komoly veszteségeket okozhat a production leállása miatt (például, ezek a képek szükségesek lehetnek a replikáció során), vagy teljesen kudarcba vihetik azt a csapat erőfeszítést, amely a hibakeresésért felelős valamelyik környezetben. (Ezért készítettünk egy külön Prometheus exporter, amely figyeli az ilyen képek hiányát bármely Kubernetes klaszterben.)

2. A második (kevésbé nyilvánvaló, de szintén nagyon fontos és újra az üzemeltetéstől függ) — azok a képek, amelyek szükségesek a visszaállításhoz, ha komoly problémák merülnek fel a jelenlegi verzióban. Például a Helm esetében ezek a képek, amelyek a mentett verziókban használatosak. (Egyébként alapértelmezés szerint a Helm korlátozása 256 revízió, de ki az, aki valójában szükségesnek érzi annyi verziót megőrizni?..) Végül is, pontosan azért tárolunk verziókat, hogy később fel lehessen használni őket, azaz "vissza lehessen állni" rájuk, ha szükséges.

3. A harmadik — a fejlesztők igényei: minden kép, amely összefügg a jelenlegi munkájukkal. Például, ha egy PR-t nézünk, érdemes megőrizni azt a képet, amely megfelel az utolsó commitnak és, mondjuk, az előző commitnak: így a fejlesztő gyorsan vissza tud térni bármely feladathoz, és dolgozhat az utolsó módosításokkal.

4. A negyedik — azok a képek, amelyek az alkalmazásunk verzióinak felelnek meg, azaz végső termékként léteznek: v1.0.0, 20.04.01, sierra stb.

NB: A fent említett kritériumokat számos fejlesztőcsapattal való tapasztalat alapján fogalmaztuk meg különböző cégekből. Azonban természetesen a fejlesztési folyamatok és az használt infrastruktúra jellemzői (például ha nem használnak Kuberenetes-t) szerint ezek a kritériumok eltérhetnek.

A kritériumok megfelelése és a meglévő megoldások

A népszerű container registry szolgáltatások általában saját képmúlt érdektelenségi politikájukat ajánlják: ezek által megadhatók azok a feltételek, amelyek mellett a címke törlésre kerül a registry-ből. Azonban ezeknek a feltételeknek a lehetőségeit olyan paraméterek korlátozzák, mint a nevek, a létrehozás ideje és a címkék száma*.

* A container registry konkrét megvalósításaitól függ. Az alábbi megoldások lehetőségeit vizsgáltuk: Azure CR, Docker Hub, ECR, GCR, GitHub Packages, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io – 2020 szeptemberi állapot szerint.

Ez a paraméterek sora elegendő ahhoz, hogy eleget tegyünk a negyedik kritériumnak – azaz képesek legyünk a verzióknak megfelelő képek kiválasztására. Azonban minden más kritérium esetében valamilyen kompromisszumos megoldást kell választani (szigorúbb vagy éppen ellenkezőleg, engedékeny politikát) az elvárások és a pénzügyi lehetőségek függvényében.

Például a harmadik kritérium – a fejlesztők igényeivel kapcsolatos – a csapatokon belüli folyamatok megszervezésével oldható meg: képek specifikus elnevezése, külön engedélyezési listák vezetése és belső megállapodások. De végső soron ezt is automatizálni kell. Ha pedig a meglévő megoldások nem elegendőek, valami sajátot kell készíteni.

Hasonló a helyzet az első két kritériummal: ezeket nem lehet teljesíteni anélkül, hogy adatokat kapnánk egy külső rendszerből – abból, ahol az alkalmazások telepítése történik (a mi esetünkben ez a Kubernetes).

A workflow illusztrációja a Git-ben

Tegyük fel, hogy körülbelül így dolgozik a Git-ben:

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

A diagramon a fej ikonnal jelölten vannak azok a konténer képek, amelyeket jelenleg Kubernetes-ben telepítettek különböző felhasználók (végfelhasználók, tesztelők, menedzserek stb.) vagy amelyeket a fejlesztők hibajavításra és hasonló célokra használnak.

Mi fog történni, ha a megtakarítási politikák csak a megadott címkék alapján engedélyezik a képek megtartását (nem törlését) a megadott címkék alapján?

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

Nyilvánvaló, hogy egy ilyen forgatókönyv senkinek sem lesz kedvére.

Mi változik, ha a politikák engedik, hogy ne töröljük a képeket a megadott időintervallum / az utolsó elkötelezések számának megfelelően?

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

Az eredmény sokkal jobb lett, azonban még mindig messze van az ideáltól. Végül is a fejlesztőknek továbbra is szükségük van képekre a registry-ben (vagy akár a K8s-ben telepítve) a hibák javításához...

Összefoglalva a piacon kialakult helyzetet: a konténernyilvántartásokban elérhető funkciók nem nyújtanak elegendő rugalmasságot a takarításhoz, ennek fő oka pedig az, hogy nincs lehetőség a külső világgal való interakcióra. Így azok a csapatok, akiknek ilyen rugalmasságra van szükségük, kénytelenek maguk megoldani a képek törlését "kívülről" a Docker Registry API (vagy a megfelelő implementáció natív API-ja) használatával.

Mindazonáltal egy általános megoldást kerestünk, amely automatizálná a képek törlését különböző csapatok számára, amelyek különböző nyilvántartásokat használnak…

Utunk az egyetemes képtakarításhoz

Honnan származik ez a szükséglet? Az a helyzet, hogy mi nem egy különálló fejlesztőcsoport vagyunk, hanem egy csapat, amely számos ilyen csoportot szolgál ki, segítve az integrált CI/CD problémák megoldását. Ehhez a fő technikai eszközünk a nyílt forráskódú segédeszköz, werf. A lényege, hogy nem egyetlen funkciót lát el, hanem kíséri a folyamatos szállítás folyamatait minden szakaszban: a buildtől a deployig.

A képek nyilvántartásban való közzététele (azaz a build után) nyilvánvaló funkciója egy ilyen eszköznek. Mivel a képek tárolásra kerülnek, ha a tárolója nem korlátlan, akkor a későbbi törlésükért is felelősnek kell lennie. Arról, hogy hogyan értük el ezt a sikert az összes megadott kritérium teljesítése mellett, majd beszámolunk.

* Bár a nyilvántartások különbözőek lehetnek (Docker Registry, GitLab Container Registry, Harbor stb.), felhasználóik ugyanazokkal a problémákkal találkoznak. Az egyetemes megoldás a mi esetünkben független a nyilvántartás implementációjától, mivel azokon kívül valósul meg, és az összes számára azonos működést kínál.

Bár a werf-et használjuk példa implementációként, reméljük, hogy a használt megközelítések más csapatok számára is hasznosak lesznek, akik hasonló nehézségekkel küzdenek.

Tehát elkezdtük a képek törlésének megvalósítását — a konténernyilvántartásokban már beépített lehetőségek helyett. Az első lépés a Docker Registry API használata volt, hogy létrehozzuk a fent említett egyszerű politikákat a címkék számáról és azok létrehozásának idejéről. Ezen kívül hozzáadtunk egy engedélyezési listát a telepített infrastruktúrában használt képek alapján, azaz Kubernetes. Az utóbbihoz elegendő volt a Kubernetes API-n keresztül végigjárni az összes telepített erőforrást és listázni az értékeket. kép.

Ez a triviális megoldás lezárta a legkritikusabb problémát (1. kritérium), de csak a tisztítási mechanizmus fejlesztésének kezdetét jelentette. A következő — és lényegesen érdekesebb — lépés a megoldás volt a közzétett képek összekapcsolása a Git-történettel..

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

Kezdetben olyan megközelítést választottunk, ahol a végső képnek tárolnia kellett a tisztításhoz szükséges információkat, és a címkézési sémákra építettük a folyamatot. 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 az ennek megfelelő értéket használta. A CI-rendszerekben ezeknek az értékeknek a beállítása automatikusan történt a környezeti változók alapján. Lényegében a végső kép összekapcsolódott egy adott Git-primitívvel,megőrizve a tisztításhoz szükséges adatokat címkékben.

Ez a megközelítés egy olyan politikák sorozatát eredményezte, amely lehetővé tette, hogy a Git az egyetlen igazságforrásként működjön:

  • A Git ágon/címkén történő törlésével automatikusan törlődtek a kapcsolódó képek is a registry-ből.
  • A Git-címkékhez és commitokhoz kapcsolódó képek számát a kiválasztott séma alapján használt címkék számával és a kapcsolódó commit létrehozásának idejével szabályozhattuk.

Összességében a megvalósítás kielégítette a szükségleteinket, de hamarosan új kihívás várt ránk. Az a helyzet, hogy a Git-primitívokon alapuló címkézési sémák használata során számos hátrányba ütköztünk. (Mivel a leírásuk túllép a cikk keretein, minden érdeklődő megismerkedhet a részletekkel; itt.) Ezért, amikor úgy döntöttünk, hogy áttérünk egy hatékonyabb címkézési megközelítésre (tartalomalapú címkézés), át kellett gondolnunk a képek tisztításának megvalósítását is.

Új algoritmus

Miért? A tartalomalapú címkézés keretein belül minden címke megfelelhet több Git commitnak. A képek tisztításakor többé nem lehet a fő DB példányhoz a commitból kiindulni, amelyre az új címkét a registry-be hozzáadták.

Az új tisztítási algoritmushoz úgy döntöttünk, hogy elhagyjuk a címkézési sémákat, és a meta-képek alapján építjük fel a folyamatot,mindegyik tárol egy párost az alábbiak szerint:

  • a kötelező elköteleződés, amelyen a közzététel történt (függetlenül attól, hogy új kép került hozzáadásra, módosult, vagy változatlan maradt a tárolóban);
  • és a belső azonosítónk, amely a létrehozott képet jelöli.

Más szavakkal, biztosítva volt a közzétett tagek és a Git elköteleződések közötti kapcsolatot.

A végső konfiguráció és általános algoritmus

A felhasználók számára, a tisztítás konfigurálásakor elérhetők lettek a politikák, amelyek meghatározzák az aktuális képek kiválasztását. Minden ilyen politika a következők által van meghatározva:

  • több referenciából, azaz Git-tagekből vagy Git-ágakból, amelyek a szkennelés során használatosak;
  • és a keresett képek korlátja minden referencia esetén.

Illusztrációként — nézd meg, hogyan nézett ki a konfiguráció alapértelmezett politikái:

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 politikát tartalmaz, amelyek a következő szabályoknak felelnek meg:

  1. Megőrizni a legutolsó 10 Git-taget (a címke létrehozásának dátuma szerint).
  2. Maximálisan 2 képet tartani az utolsó héten közzétett képekből, legfeljebb 10 ágon, amelyek az utolsó héten aktívak.
  3. Megőrizni 10 képet az ágak számára main, staging és production.

A végső algoritmus a következő lépésekre redukálódik:

  • Mennyiségek beszerzése a tárolóból.
  • Kizárni a Kubernetesben használt képeket, mivel ezeket már előre kiválasztottuk a K8s API megkérdezésével.
  • A Git-történet szkennelése és a képek kizárása a megadott politikák szerint.
  • A megmaradt képek eltávolítása.

Visszatérve az illusztrációnkhoz, így fest a werf:

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

Bár, ha nem használod a werfet, ez a fejlett képtisztítási megközelítés — bármilyen megvalósításban (a képek címkézésének preferált megközelítése szerint) — alkalmazható más rendszerekben/jóváhagyásokban is. Csak annyit kell megjegyezni a felmerülő problémákról, és megtalálni azokat a lehetőségeket a te rendszeredben, amelyek beépítik a megoldásokat a lehető legsimábban. Reméljük, hogy a megtett útunk segít új részletekkel és gondolatokkal megvizsgálni a te esetet is.

Zárás

  • Előbb vagy utóbb a legtöbb csapat szembesül a registry túlcsordulásának problémájával.
  • A megoldások keresésekor első lépésként meg kell határozni a kép relevanciájának kritériumait.
  • A népszerű container registry szolgáltatások által kínált eszközök lehetővé teszik egy nagyon egyszerű tisztítás megszervezését, amely nem veszi figyelembe a „külső világot”: a Kubernetesben használt képeket és a csapat munkafolyamatainak sajátosságait.
  • A rugalmas és hatékony algoritmusnak tisztában kell lennie a CI/CD folyamatokkal, és nem csak a Docker képekkel kell operálnia.

P.S.

Olvasson további információkat a blogunkban:

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster