Naše iskustvo u razvoju CSI drajvera u Kubernetesu za Yandex.Cloud

Naše iskustvo u razvoju CSI drajvera u Kubernetesu za Yandex.Cloud

Zadovoljstvo nam je objaviti da Flant proširuje svoj doprinos alatima otvorenog koda za Kubernetes objavljivanjem alfa verzija CSI drajvera (Sučelje za pohranu spremnika) za Yandex.Cloud.

Ali prije nego prijeđemo na detalje implementacije, odgovorimo na pitanje zašto je to uopće potrebno kada Yandex već ima uslugu Upravljana usluga za Kubernetes.

Uvod

Zašto je ovo?

Unutar naše tvrtke od samog početka korištenja Kubernetesa u produkciji (dakle već nekoliko godina) razvijamo vlastiti alat (deckhouse) koji, usput, također planiramo uskoro staviti na raspolaganje kao Open Source projekt . Uz njegovu pomoć jednoobrazno konfiguriramo i konfiguriramo sve naše klastere, a trenutno ih ima više od 100, na najrazličitijim hardverskim konfiguracijama i u svim dostupnim cloud servisima.

Klasteri koji koriste palubnu kućicu imaju sve komponente potrebne za rad: balansere, praćenje s praktičnim kartama, metriku i upozorenja, autentifikaciju korisnika putem vanjskih pružatelja usluga za pristup svim nadzornim pločama itd. Nema smisla instalirati takav "napumpani" klaster u upravljano rješenje, budući da je to često nemoguće ili će dovesti do potrebe za onesposobljavanjem polovice komponenti.

NB: To je naše iskustvo i dosta je specifično. Ni na koji način ne sugeriramo da bi svatko trebao sam implementirati Kubernetes klastere umjesto da koristi gotova rješenja. Usput, nemamo stvarnog iskustva u upravljanju Kubernetesom iz Yandexa i nećemo dati nikakvu ocjenu ove usluge u ovom članku.

Što je i za koga?

Dakle, već smo govorili o modernom pristupu pohrani u Kubernetesu: kako radi CSI? и kako je zajednica došla ovom pristupu.

Trenutačno su mnogi veliki pružatelji usluga u oblaku razvili upravljačke programe za korištenje svojih diskova u oblaku kao trajnog volumena u Kubernetesu. Ako dobavljač nema takav upravljački program, ali su sve potrebne funkcije osigurane putem API-ja, ništa vas ne sprječava da sami implementirate upravljački program. To se dogodilo s Yandex.Cloudom.

Uzeli smo kao osnovu za razvoj CSI upravljački program za DigitalOcean oblak i par ideja od upravljački programi za GCP, budući da interakcija s API-jem ovih oblaka (Google i Yandex) ima brojne sličnosti. Konkretno, API i GCPi na Yandex vratiti objekt Operation za praćenje statusa dugotrajnih operacija (na primjer, stvaranje novog diska). Za interakciju s API-jem Yandex.Cloud koristite Yandex.Cloud Go SDK.

Rezultat obavljenog posla objavljeno na GitHubu i može biti korisno za one koji iz nekog razloga koriste vlastitu Kubernetes instalaciju na Yandex.Cloud virtualnim strojevima (ali ne gotov upravljani klaster) i željeli bi koristiti (naručivati) diskove putem CSI-ja.

Provedba

Ključne značajke

Trenutačno upravljački program podržava sljedeće funkcije:

  • Redoslijed diskova u svim zonama klastera prema topologiji čvorova u klasteru;
  • Vađenje prethodno naručenih diskova;
  • Izvanmrežna promjena veličine za diskove (Yandex.Cloud ne podržavaju povećanje diskova koji su montirani na virtualni stroj). Za informacije o tome kako je upravljački program morao biti izmijenjen kako bi promjena veličine bila što bezbolnija, pogledajte dolje.

U budućnosti planiramo implementirati podršku za izradu i brisanje snimaka diska.

Glavna poteškoća i kako je prevladati

Nedostatak mogućnosti povećanja diskova u stvarnom vremenu u Yandex.Cloud API-ju je ograničenje koje komplicira operaciju promjene veličine za PV (Persistent Volume): u ovom slučaju, potrebno je da se aplikacijski blok koji koristi disk zaustavi, a to može uzrokovati prekid rada aplikacija.

Prema CSI specifikacije, ako CSI kontroler javi da može mijenjati veličinu diskova samo "offline" (VolumeExpansion.OFFLINE), tada bi proces povećanja diska trebao ići ovako:

Ako dodatak ima samo VolumeExpansion.OFFLINE mogućnost proširenja i volumen trenutno su objavljeni ili dostupni na čvoru ControllerExpandVolume MORA biti pozvan SAMO nakon:

  • Dodatak ima kontroler PUBLISH_UNPUBLISH_VOLUME sposobnost i ControllerUnpublishVolume je uspješno pozvan.

ILI DRUGO

  • Dodatak NEMA kontroler PUBLISH_UNPUBLISH_VOLUME mogućnost, dodatak ima čvor STAGE_UNSTAGE_VOLUME sposobnost, i NodeUnstageVolume je uspješno dovršen.

ILI DRUGO

  • Dodatak NEMA kontroler PUBLISH_UNPUBLISH_VOLUME sposobnost, niti čvor STAGE_UNSTAGE_VOLUME sposobnost, i NodeUnpublishVolume je uspješno završeno.

To u biti znači da trebate odvojiti disk od virtualnog stroja prije nego što ga proširite.

Međutim, nažalost izvršenje CSI specifikacija putem bočnih prikolica ne ispunjava ove zahtjeve:

  • U kontejneru bočne prikolice csi-attacher, koji bi trebao biti odgovoran za prisutnost potrebnog razmaka između nosača, ova funkcionalnost jednostavno nije implementirana u offline promjeni veličine. O tome je pokrenuta rasprava здесь.
  • Što je točno bočni kontejner u ovom kontekstu? Sam CSI dodatak ne komunicira s Kubernetes API-jem, već samo odgovara na gRPC pozive koje mu šalju sidecar kontejneri. Najnoviji razvijaju se od strane zajednice Kubernetes.

U našem slučaju (CSI dodatak), operacija povećanja diska izgleda ovako:

  1. Primamo gRPC poziv ControllerExpandVolume;
  2. Pokušavamo povećati disk u API-ju, ali dobivamo pogrešku o nemogućnosti izvođenja operacije jer je disk montiran;
  3. Identifikator diska pohranjujemo u mapu koja sadrži diskove za koje je potrebno izvršiti operaciju povećanja. U nastavku ćemo ovu kartu zbog kratkoće nazvati kao volumeResizeRequired;
  4. Ručno uklonite mahunu koja koristi disk. Kubernetes će ga ponovno pokrenuti. Tako da disk nema vremena za montiranje (ControllerPublishVolume) prije dovršetka operacije povećanja pri pokušaju montiranja, provjeravamo je li dati disk još uvijek unutra volumeResizeRequired i vrati grešku;
  5. CSI upravljački program pokušava ponovno izvršiti operaciju promjene veličine. Ako je operacija bila uspješna, uklonite disk iz volumeResizeRequired;
  6. Jer ID diska nedostaje iz volumeResizeRequired, ControllerPublishVolume prolazi uspješno, disk je montiran, pod se pokreće.

Sve izgleda dovoljno jednostavno, ali kao i uvijek postoje zamke. Povećava diskove vanjski-resizer, koji u slučaju greške tijekom rada koristi red čekanja s eksponencijalnim povećanjem vremena čekanja do 1000 sekundi:

func DefaultControllerRateLimiter() RateLimiter {
  return NewMaxOfRateLimiter(
  NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second),
  // 10 qps, 100 bucket size.  This is only for retry speed and its only the overall factor (not per item)
  &BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
  )
}

To može povremeno rezultirati produljenjem operacije proširenja diska za 15+ minuta i stoga odgovarajuća grupa nije dostupna.

Jedina opcija koja nam je prilično lako i bezbolno omogućila da smanjimo potencijalni zastoj bila je upotreba naše verzije external-resizer-a s maksimalnim vremenskim ograničenjem za 5 sekundi:

workqueue.NewItemExponentialFailureRateLimiter(5*time.Millisecond, 5*time.Second)

Nismo smatrali potrebnim hitno pokrenuti raspravu i zakrpati external-resizer, jer je izvanmrežna promjena veličine diskova povratak koji će uskoro nestati kod svih cloud providera.

Kako početi koristiti?

Upravljački program je podržan na Kubernetes verziji 1.15 i novijim. Da bi vozač radio, moraju biti ispunjeni sljedeći zahtjevi:

  • zastava --allow-privileged postaviti na vrijednost true za API poslužitelj i kubelet;
  • Uključeno --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true za API poslužitelj i kubelet;
  • Širenje montiranja (montirati širenje) moraju biti omogućeni na klasteru. Kada koristite Docker, demon mora biti konfiguriran da dopušta dijeljena montiranja.

Svi potrebni koraci za samu instalaciju opisano u README. Instalacija uključuje stvaranje objekata u Kubernetesu iz manifesta.

Za rad vozača trebat će vam sljedeće:

  • Navedite identifikator direktorija u manifestu (folder-id) Yandex.Cloud (pogledajte dokumentaciju);
  • Za interakciju s API-jem Yandex.Cloud, CSI vozač koristi račun usluge. U manifestu, Secret se mora predati ovlašteni ključevi sa servisnog računa. U dokumentaciji opisano, kako kreirati servisni račun i dobiti ključeve.

Sve u svemu - probati, a bit će nam drago primiti povratne informacije i nova pitanjaako naiđete na probleme!

Daljnja podrška

Kao rezultat toga, želimo napomenuti da smo implementirali ovaj CSI driver ne iz velike želje da se zabavimo pisanjem aplikacija u Go-u, već zbog hitne potrebe unutar tvrtke. Ne čini nam se praktičnim održavati vlastitu implementaciju, pa ako Yandex pokaže interes i odluči nastaviti podržavati vozača, rado ćemo im prenijeti repozitorij.

Osim toga, Yandex vjerojatno ima vlastitu implementaciju CSI drajvera u svom upravljanom Kubernetes klasteru, koji se može objaviti u Open Sourceu. Ovu mogućnost razvoja također vidimo kao povoljnu - zajednica će moći koristiti provjereni upravljački program od pružatelja usluga, a ne od tvrtke treće strane.

PS

Pročitajte i na našem blogu:

Izvor: www.habr.com

Dodajte komentar