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 izdavanjem alfa verzija CSI drajvera (Sučelje za pohranu kontejnera) za Yandex.Cloud.

Ali prije nego što pređ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 kompanije, od samog početka korištenja Kubernetesa u proizvodnji (tj. već nekoliko godina), razvijamo vlastiti alat (deckhouse), koji, inače, planiramo uskoro učiniti dostupnim kao Open Source projekat . Uz njegovu pomoć ujednačeno konfiguriramo i konfiguriramo sve naše klastere, a trenutno ih ima više od 100, na raznim hardverskim konfiguracijama iu svim dostupnim cloud servisima.

Klasteri koji koriste palubu imaju sve komponente neophodne za rad: balansere, praćenje sa praktičnim grafikonima, metrikama i upozorenjima, autentifikaciju korisnika preko eksternih provajdera za pristup svim kontrolnim tablama, itd. Nema smisla instalirati takav "napumpani" klaster u upravljano rješenje, jer je to često ili nemoguće ili će dovesti do potrebe da se polovina komponenti onesposobi.

NB: Ovo je naše iskustvo, i prilično je specifično. Ni na koji način ne sugeriramo da bi svako trebao samostalno implementirati Kubernetes klastere umjesto da koristi gotova rješenja. Usput, nemamo pravog iskustva u upravljanju Kubernetes-om iz Yandexa i nećemo dati nikakvu ocjenu ove usluge u ovom članku.

Šta je to i za koga?

Dakle, već smo govorili o modernom pristupu skladištenju u Kubernetesu: kako CSI radi? и kako je zajednica nastala ovom pristupu.

Trenutno su mnogi veliki dobavljači usluga u oblaku razvili drajvere za korištenje svojih diskova u oblaku kao Persistent Volume u Kubernetesu. Ako dobavljač nema takav drajver, ali su sve potrebne funkcije omogućene putem API-ja, onda vas ništa ne sprječava da sami implementirate drajver. Ovo se dogodilo sa Yandex.Cloud.

Uzeli smo kao osnovu za razvoj CSI drajver za oblak DigitalOcean i par ideja iz drajveri za GCP, budući da interakcija sa API-jem ovih oblaka (Google i Yandex) ima niz sličnosti. Konkretno, API i GCP, i Yandex vratiti objekat Operation za praćenje statusa dugotrajnih operacija (na primjer, kreiranje novog diska). Za interakciju s Yandex.Cloud API-jem, 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 virtuelnim mašinama (ali ne i gotov upravljani klaster) i žele da koriste (naruče) diskove preko CSI.

Реализация

Ključne karakteristike

Trenutno drajver podržava sljedeće funkcije:

  • Naručivanje diskova u svim zonama klastera prema topologiji čvorova u klasteru;
  • Uklanjanje prethodno naručenih diskova;
  • Vanmrežna promjena veličine za diskove (Yandex.Cloud ne podržavaju povećanje diskova koji se montiraju na virtuelnu mašinu). Za informacije o tome kako je drajver morao biti izmijenjen da bi promjena veličine bila što bezbolnija, pogledajte dolje.

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

Glavna poteškoća i kako je prevazići

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

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

Ako dodatak ima samo VolumeExpansion.OFFLINE sposobnost proširenja i volumen su trenutno objavljeni ili tada dostupni na čvoru ControllerExpandVolume MORA se pozvati 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 node STAGE_UNSTAGE_VOLUME sposobnost, i NodeUnstageVolume je uspešno završen.

ILI DRUGO

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

Ovo u suštini znači da morate da odvojite disk od virtuelne mašine pre nego što ga proširite.

Međutim, nažalost implementacija CSI specifikacija preko bočnih prikolica ne ispunjava ove zahtjeve:

  • U kontejneru za prikolicu csi-attacher, koji bi trebao biti odgovoran za postojanje potrebnog razmaka između montiranja, ova funkcionalnost jednostavno nije implementirana u offline promjeni veličine. Pokrenuta je rasprava o tome ovdje.
  • Šta je zapravo bočni kontejner u ovom kontekstu? Sam CSI dodatak ne stupa u interakciju sa Kubernetes API-jem, već samo odgovara na gRPC pozive koje mu šalju sidecar kontejneri. Najnoviji se razvijaju od strane Kubernetes zajednice.

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

  1. Primamo gRPC poziv ControllerExpandVolume;
  2. Pokušavamo povećati disk u API-ju, ali dobijamo grešku o nemogućnosti izvođenja operacije jer je disk montiran;
  3. Identifikator diska pohranjujemo u mapu, koja sadrži diskove za koje treba izvršiti operaciju povećanja. U nastavku, radi sažetosti, nazvat ćemo ovu kartu kao volumeResizeRequired;
  4. Ručno uklonite pod koji koristi disk. Kubernetes će ga ponovo pokrenuti. Tako da disk nema vremena za montiranje (ControllerPublishVolume) prije nego što završimo operaciju povećanja pri pokušaju montiranja, provjeravamo da li je dati disk još uvijek unutra volumeResizeRequired i vrati grešku;
  5. CSI drajver pokušava ponovo izvršiti operaciju promjene veličine. Ako je operacija bila uspješna, uklonite disk iz volumeResizeRequired;
  6. Jer Nedostaje ID diska volumeResizeRequired, ControllerPublishVolume prođe uspješno, disk je montiran, pod počinje.

Sve izgleda dovoljno jednostavno, ali kao i uvijek postoje zamke. Uvećava diskove external-resizer, što u slučaju greške tokom rada koristi red sa 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)},
  )
}

Ovo može povremeno rezultirati produženjem operacije proširenja diska za 15+ minuta i, prema tome, odgovarajući pod biti nedostupan.

Jedina opcija koja nam je prilično lako i bezbolno omogućila da smanjimo potencijalne zastoje bila je korištenje naše verzije eksternog resizera s maksimalnim ograničenjem vremenskog ograničenja za 5 sekundi:

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

Nismo smatrali da je potrebno hitno pokrenuti raspravu i zakrpiti eksterni resizer, jer je offline promjena veličine diskova povratna informacija koja će uskoro nestati kod svih cloud provajdera.

Kako početi koristiti?

Drajver je podržan na Kubernetes verziji 1.15 i novijim. Da bi vozač mogao da radi, moraju biti ispunjeni sledeći uslovi:

  • Zastava --allow-privileged postaviti na vrijednost true za API server i kubelet;
  • Uključeno --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true za API server i kubelet;
  • razmnožavanje (mount propagation) mora biti omogućeno na klasteru. Kada koristite Docker, demon mora biti konfiguriran da omogući dijeljeno montiranje.

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

Da bi drajver radio trebaće vam sledeće:

  • Navedite identifikator direktorija u manifestu (folder-id) Yandex.Cloud (vidi dokumentaciju);
  • Za interakciju sa Yandex.Cloud API-jem, CSI drajver koristi nalog usluge. U manifestu, Tajna mora biti proslijeđena autorizovani ključevi sa servisnog računa. U dokumentaciji opisano, kako kreirati servisni nalog i dobiti ključeve.

Sve u svemu - probaj, i bit će nam drago dobiti povratne informacije i nova izdanja, ako naiđete na bilo kakve probleme!

Dalja podrška

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

Osim toga, Yandex vjerovatno ima sopstvenu implementaciju CSI drajvera u svom upravljanom Kubernetes klasteru, koji može biti objavljen u otvorenom kodu. Ovu razvojnu opciju takođe vidimo kao povoljnu - zajednica će moći da koristi provereni drajver od dobavljača usluga, a ne od kompanije treće strane.

PS

Pročitajte i na našem blogu:

izvor: www.habr.com

Dodajte komentar