Säiliökuvien "älykkään" puhdistuksen ongelma ja sen ratkaisu werfissä

Säiliökuvien "älykkään" puhdistuksen ongelma ja sen ratkaisu werfissä

Artikkelissa käsitellään konttirekistereihin (Docker Registry ja sen analogit) kerääntyvien kuvien puhdistamisen ongelmia Kubernetesille toimitettujen pilvipohjaisten sovellusten nykyaikaisten CI/CD-putkien todellisuudessa. Pääkriteerit kuvien relevanssille ja niistä aiheutuville vaikeuksille siivouksen automatisoinnissa, tilan säästämisessä ja tiimien tarpeiden täyttämisessä esitetään. Lopuksi kerromme tietyn avoimen lähdekoodin projektin esimerkin avulla, kuinka nämä vaikeudet voidaan voittaa.

Esittely

Säiliörekisterin kuvien määrä voi kasvaa nopeasti, mikä vie enemmän tallennustilaa ja lisää siten merkittävästi sen kustannuksia. Rekisterin käytössä olevan tilan hyväksyttävän kasvun hallitsemiseksi, rajoittamiseksi tai ylläpitämiseksi hyväksytään:

  1. käytä kuville kiinteää määrää tunnisteita;
  2. puhdistaa kuvat jollain tavalla.


Ensimmäinen rajoitus on joskus hyväksyttävä pienille ryhmille. Jos kehittäjillä on tarpeeksi pysyviä tunnisteita (latest, main, test, boris jne.), rekisteri ei paisu kooltaan, eikä sinun tarvitse pitkään aikaan ajatella sen puhdistamista ollenkaan. Loppujen lopuksi kaikki merkityksettömät kuvat poistetaan, eikä puhdistukseen yksinkertaisesti jää enää työtä (kaiken tekee tavallinen roskakeräilijä).

Tämä lähestymistapa rajoittaa kuitenkin suuresti kehitystä, ja sitä voidaan harvoin soveltaa nykyaikaisiin CI/CD-projekteihin. Olennainen osa kehitystä oli automaatio, jonka avulla voit testata, ottaa käyttöön ja toimittaa uusia toimintoja käyttäjille paljon nopeammin. Esimerkiksi kaikissa projekteissamme CI-putki luodaan automaattisesti jokaisen sitoumuksen yhteydessä. Siinä kuva kootaan, testataan, rullataan erilaisille Kubernetes-piireille virheenkorjausta ja jäljellä olevia tarkistuksia varten, ja jos kaikki on hyvin, muutokset saavuttavat loppukäyttäjän. Ja tämä ei ole enää rakettitiedettä, vaan arkipäivää monille - todennäköisesti sinulle, koska luet tätä artikkelia.

Koska bugien korjaus ja uusien toimintojen kehittäminen tapahtuu rinnakkain ja julkaisuja voidaan tehdä useita kertoja päivässä, on ilmeistä, että kehitysprosessiin liittyy huomattava määrä committeja, mikä tarkoittaa suuri määrä kuvia rekisterissä. Tämän seurauksena herää kysymys rekisterin tehokkaan puhdistuksen järjestämisestä, ts. epäolennaisten kuvien poistaminen.

Mutta miten voit edes määrittää, onko kuva relevantti?

Kuvan osuvuuden kriteerit

Suurimmassa osassa tapauksista tärkeimmät kriteerit ovat:

1. Ensimmäinen (ilmeisin ja kriittisin kaikista) ovat kuvat, jotka tällä hetkellä käytössä Kubernetes. Näiden kuvien poistaminen voi aiheuttaa merkittäviä tuotannon seisokkeja (esimerkiksi kuvia voidaan tarvita replikointiin) tai tehdä tyhjäksi tiimin ponnistelut missä tahansa silmukassa virheenkorjaustyössä. (Tästä syystä teimme jopa erityisen Prometheuksen viejät, joka seuraa tällaisten kuvien puuttumista missään Kubernetes-klusterissa.)

2. Toinen (vähemmän ilmeinen, mutta myös erittäin tärkeä ja liittyy jälleen hyväksikäyttöön) - kuvat, jotka tarvitaan palautus, jos havaitaan vakavia ongelmia nykyisessä versiossa. Esimerkiksi Helmin tapauksessa nämä ovat kuvia, joita käytetään julkaisun tallennetuissa versioissa. (Muuten, oletuksena Helmissä raja on 256 versiota, mutta on epätodennäköistä, että kenenkään todella tarvitsee tallentaa kuten a suuri määrä versioita?..) Säilytämmehän me erityisesti versioita, jotta voimme käyttää niitä myöhemmin, ts. "palaa takaisin" heidän luokseen tarvittaessa.

3. Kolmas - kehittäjien tarpeisiin: Kaikki kuvat, jotka liittyvät heidän nykyiseen työhönsä. Jos esimerkiksi harkitsemme PR:tä, on järkevää jättää kuva, joka vastaa viimeistä ja esimerkiksi edellistä toimitusta: näin kehittäjä voi nopeasti palata mihin tahansa tehtävään ja työskennellä uusimpien muutosten kanssa.

4. Neljänneksi - kuvat vastaavat sovelluksemme versioita, eli ovat lopputuote: v1.0.0, 20.04.01/XNUMX/XNUMX, sierra jne.

HUOM: Tässä määritellyt kriteerit on muotoiltu kokemuksen perusteella, joka on saatu vuorovaikutuksessa kymmenien eri yritysten kehitystiimien kanssa. Tietysti nämä kriteerit voivat kuitenkin vaihdella kehitysprosessien ja käytetyn infrastruktuurin erityispiirteiden mukaan (esimerkiksi Kubernetes ei ole käytössä).

Kelpoisuus ja olemassa olevat ratkaisut

Suosituilla konttirekistereillä varustetuilla palveluilla on pääsääntöisesti omat kuvanpuhdistuskäytännöt: niissä voit määritellä ehdot, joilla tunniste poistetaan rekisteristä. Näitä ehtoja rajoittavat kuitenkin parametrit, kuten nimet, luontiaika ja tunnisteiden määrä*.

* Riippuu tietyistä säilörekisterin toteutuksista. Harkitsemme seuraavien ratkaisujen mahdollisuuksia: Azure CR, Docker Hub, ECR, GCR, GitHub Packages, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io – syyskuusta 2020 alkaen.

Tämä parametrijoukko riittää täyttämään neljännen kriteerin - eli valitsemaan versioita vastaavat kuvat. Kaikille muille kriteereille on kuitenkin valittava jonkinlainen kompromissiratkaisu (tiukempi tai päinvastoin lempeämpi politiikka) - odotuksista ja taloudellisista mahdollisuuksista riippuen.

Esimerkiksi kolmas - kehittäjien tarpeisiin liittyvä - kriteeri voidaan ratkaista järjestämällä prosesseja tiimien sisällä: kuvien erityisellä nimeämisellä, erityisten lupaluetteloiden ja sisäisten sopimusten ylläpidolla. Mutta lopulta se on vielä automatisoitava. Ja jos valmiiden ratkaisujen ominaisuudet eivät riitä, on tehtävä jotain omaa.

Tilanne kahden ensimmäisen kriteerin kanssa on samanlainen: niitä ei voida täyttää vastaanottamatta tietoja ulkoisesta järjestelmästä - järjestelmästä, jossa sovelluksia otetaan käyttöön (tapauksessamme Kubernetes).

Kuva työnkulusta Gitissä

Oletetaan, että työskentelet Gitissä jotain tämän kaltaista:

Säiliökuvien "älykkään" puhdistuksen ongelma ja sen ratkaisu werfissä

Kaaviossa oleva pääkuvake osoittaa säilökuvat, jotka ovat tällä hetkellä käytössä Kubernetesissä kaikille käyttäjille (loppukäyttäjille, testaajille, johtajille jne.) tai joita kehittäjät käyttävät virheenkorjaukseen ja vastaaviin tarkoituksiin.

Mitä tapahtuu, jos puhdistuskäytännöt sallivat vain kuvien säilyttämisen (ei poistamisen) annettujen tunnisteiden nimien mukaan?

Säiliökuvien "älykkään" puhdistuksen ongelma ja sen ratkaisu werfissä

Sellainen skenaario ei tietenkään tee ketään onnelliseksi.

Mikä muuttuu, jos käytännöt sallivat kuvien poistamisen? tietyn aikavälin / viimeisten sitoumusten lukumäärän mukaan?

Säiliökuvien "älykkään" puhdistuksen ongelma ja sen ratkaisu werfissä

Tuloksesta on tullut paljon parempi, mutta se on edelleen kaukana ihanteellisesta. Loppujen lopuksi meillä on edelleen kehittäjiä, jotka tarvitsevat kuvia rekisteristä (tai jopa K8:ssa käyttöön otettuja) virheiden korjaamiseen...

Yhteenvetona tämän hetkisestä markkinatilanteesta: konttirekistereissä olevat toiminnot eivät tarjoa tarpeeksi joustavuutta siivouksessa ja suurin syy tähän on ei tapaa olla vuorovaikutuksessa ulkomaailman kanssa. Osoittautuu, että tiimit, jotka vaativat tällaista joustavuutta, pakotetaan itsenäisesti toteuttamaan kuvien poistaminen "ulkopuolelta" käyttämällä Docker Registry API:ta (tai vastaavan toteutuksen alkuperäistä APIa).

Etsimme kuitenkin universaalia ratkaisua, joka automatisoi kuvien siivouksen eri ryhmille eri rekistereillä...

Polkumme yleiseen kuvanpuhdistukseen

Mistä tämä tarve tulee? Tosiasia on, että emme ole erillinen kehittäjäryhmä, vaan tiimi, joka palvelee monia heistä kerralla ja auttaa kokonaisvaltaisesti ratkaisemaan CI/CD-ongelmia. Ja tärkein tekninen työkalu tähän on Open Source -apuohjelma werf. Sen erikoisuus on, että se ei suorita yhtä toimintoa, vaan se seuraa jatkuvia toimitusprosesseja kaikissa vaiheissa: kokoonpanosta käyttöönottoon.

Kuvien julkaiseminen rekisterissä* (välittömästi niiden rakentamisen jälkeen) on tällaisen apuohjelman ilmeinen toiminto. Ja koska kuvat sijoitetaan sinne säilytystä varten, niin - jos tallennustilasi ei ole rajoittamaton - sinun on vastattava niiden myöhemmästä puhdistuksesta. Siitä, kuinka onnistuimme tässä, täyttäen kaikki määritellyt kriteerit, keskustellaan edelleen.

* Vaikka itse rekisterit voivat olla erilaisia ​​(Docker Registry, GitLab Container Registry, Harbor jne.), niiden käyttäjät kohtaavat samat ongelmat. Universaali ratkaisu meidän tapauksessamme ei riipu rekisterin toteutuksesta, koska toimii itse rekisterien ulkopuolella ja tarjoaa saman käyttäytymisen kaikille.

Vaikka käytämme werfiä esimerkkitoteutuksena, toivomme, että käytetyistä lähestymistavoista on hyötyä muille vastaavista vaikeuksista kärsiville joukkueille.

Joten meillä oli kiire ulkoinen kuvien puhdistusmekanismin toteuttaminen - niiden ominaisuuksien sijaan, jotka ovat jo valmiit säiliöiden rekistereihin. Ensimmäinen askel oli Docker Registry API:n avulla luoda samat primitiiviset käytännöt tagien lukumäärälle ja luomisajalle (mainittu yllä). Lisätty niihin sallia luettelo käyttöönotetussa infrastruktuurissa käytettyjen kuvien perusteella, eli Kubernetes. Jälkimmäiselle riitti Kubernetes API:n käyttäminen kaikkien käyttöönotettujen resurssien iteroimiseen ja arvoluettelon saamiseen. image.

Tämä triviaali ratkaisu ratkaisi kriittisimmän ongelman (kriteeri nro 1), mutta oli vasta alkua matkallemme puhdistusmekanismin parantamiseksi. Seuraava - ja paljon mielenkiintoisempi - askel oli päätös liittää julkaistut kuvat Gitin historiaan.

Merkintäjärjestelmät

Aluksi valitsimme lähestymistavan, jossa lopulliseen kuvaan tulisi tallentaa puhdistukseen tarvittavat tiedot, ja rakensimme prosessin merkintäkaavioille. Julkaiseessaan kuvaa käyttäjä valitsi tietyn merkintävaihtoehdon (git-branch, git-commit tai git-tag) ja käytti vastaavaa arvoa. CI-järjestelmissä nämä arvot asetettiin automaattisesti ympäristömuuttujien perusteella. Itse asiassa lopullinen kuva yhdistettiin tiettyyn Git-primitiiviin, tallentaa tarvittavat tiedot puhdistukseen tarroihin.

Tämä lähestymistapa johti joukkoon käytäntöjä, jotka mahdollistivat Gitin käytön ainoana totuuden lähteenä:

  • Kun haara/tunniste poistettiin Gitissä, siihen liittyvät kuvat rekisteristä poistettiin automaattisesti.
  • Git-tunnisteisiin ja -toimituksiin liittyvien kuvien määrää voidaan hallita valitussa skeemassa käytettyjen tunnisteiden määrällä ja ajankohdasta, jolloin liittyvä sitoumus luotiin.

Kokonaisuudessaan toteutus täytti tarpeitamme, mutta pian meitä odotti uusi haaste. Tosiasia on, että kun käytimme Git-primitiiviin perustuvia taggausjärjestelmiä, kohtasimme joukon puutteita. (Koska niiden kuvaus ei kuulu tämän artikkelin piiriin, jokainen voi tutustua yksityiskohtiin täällä.) Siksi, kun olemme päättäneet siirtyä tehokkaampaan koodaustapaan (sisältöön perustuva taggaus), jouduimme harkitsemaan uudelleen kuvanpuhdistuksen toteuttamista.

Uusi algoritmi

Miksi? Sisältöpohjaisella taggauksella jokainen tunniste voi täyttää useita Git-sitoumuksia. Kun puhdistat kuvia, et voi enää olettaa vain vahvistuksesta, jossa uusi tunniste lisättiin rekisteriin.

Uuden puhdistusalgoritmin osalta päätettiin luopua merkintäjärjestelmistä ja rakentaa meta-kuvaprosessi, joista jokainen sisältää joukon:

  • sitoumus, jolla julkaisu suoritettiin (ei ole väliä onko kuva lisätty, muutettu tai pysynyt samana säilörekisterissä);
  • ja sisäinen tunniste, joka vastaa koottua kuvaa.

Toisin sanoen se tarjottiin julkaistujen tunnisteiden linkittäminen Git-sitoumuksiin.

Lopullinen konfigurointi ja yleinen algoritmi

Kun määrität puhdistusta, käyttäjät voivat nyt käyttää käytäntöjä, jotka valitsevat nykyiset kuvat. Jokainen tällainen käytäntö määritellään:

  • paljon viittauksia, esim. Git-tunnisteet tai Git-haarat, joita käytetään skannauksen aikana;
  • ja haettujen kuvien enimmäismäärä jokaiselle joukon viitteelle.

Havainnollistaen, että oletuskäytännön kokoonpano alkoi näyttää tältä:

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

Tämä kokoonpano sisältää kolme käytäntöä, jotka noudattavat seuraavia sääntöjä:

  1. Tallenna kuva viimeisille 10 Git-tagille (tunnisteen luontipäivämäärän mukaan).
  2. Tallenna enintään 2 viime viikolla julkaistua kuvaa enintään 10 säiettä, joissa on toimintaa viime viikolla.
  3. Tallenna 10 kuvaa oksille main, staging и production.

Lopullinen algoritmi tiivistyy seuraaviin vaiheisiin:

  • Haetaan luetteloita säilörekisteristä.
  • Lukuun ottamatta Kubernetesissa käytettyjä kuvia, koska Olemme jo esivalinneet ne K8s-sovellusliittymän kyselyllä.
  • Git-historian skannaus ja kuvien poissulkeminen määritettyjen käytäntöjen perusteella.
  • Poistetaan jäljellä olevia kuvia.

Palatakseni kuvaamme, näin tapahtuu werfin kanssa:

Säiliökuvien "älykkään" puhdistuksen ongelma ja sen ratkaisu werfissä

Kuitenkin, vaikka et käyttäisikään werfiä, samanlaista lähestymistapaa edistyneeseen kuvanpuhdistukseen - yhdessä tai toisessa toteutuksessa (suositun kuvakoodaustavan mukaan) - voidaan soveltaa muihin järjestelmiin/apuohjelmiin. Tätä varten riittää, että muistat nousevat ongelmat ja etsit pinostasi ne mahdollisuudet, joiden avulla voit integroida niiden ratkaisun mahdollisimman sujuvasti. Toivomme, että kulkemamme polku auttaa sinua tarkastelemaan tapaustasi uusilla yksityiskohdilla ja ajatuksella.

Johtopäätös

  • Ennemmin tai myöhemmin useimmat tiimit kohtaavat rekisterin ylivuoto-ongelman.
  • Ratkaisuja etsittäessä on ensin määritettävä kuvan relevanssikriteerit.
  • Suosittujen konttirekisteripalveluiden tarjoamien työkalujen avulla voit järjestää hyvin yksinkertaisen siivouksen, jossa ei oteta huomioon "ulkomaailmaa": Kubernetesissa käytettyjä kuvia ja tiimin työnkulkujen erityispiirteitä.
  • Joustavan ja tehokkaan algoritmin on ymmärrettävä CI/CD-prosessit, ja sen on toimittava paitsi Docker-kuvadatan kanssa.

PS.

Lue myös blogistamme:

Lähde: will.com

Lisää kommentti