Meie kogemus CSI-draiveri väljatöötamisel Kuberneteses Yandex.Cloudile

Meie kogemus CSI-draiveri väljatöötamisel Kuberneteses Yandex.Cloudile

Meil on hea meel teatada, et ettevõte "Flant" suurendab oma panust avatud lähtekoodiga tööriistadesse Kubernetes'ile, välja andes alpha-versiooni CSI-draiverist (Container Storage Interface) Yandex Cloudile.

Kuid enne, kui läheme rakenduse üksikasjade juurde, vastame küsimusele, miks see üldse vajalik on, kui Yandex'il on juba teenus Managed Service for Kubernetes.

Sissejuhatus

Miks see vajalik on?

Meie ettevõttes on juba algusest peale, kui Kubernetes'it hakatakse tootmises kasutama (st juba mitu aastat), arendatud oma tööriista (deckhouse), mille me kavatseme varsti muuta kergesti kättesaadavaks kui avatud lähtekoodiga projekti. Selle abil konfigureerime ja seadistame kõiki oma klustreid ühtlaselt ning hetkel on neid juba üle 100, erinevates riistvara konfiguratsioonides ja kõikides saadaolevates pilveteenustes.

Klusterid, milles kasutatakse deckhouse'i, sisaldavad kõiki vajalikke töökomponente: laadijad, mugava graafiku, mõõdikute ja häiretega jälgimine, kasutajate autentimine väliste teenusepakkujate kaudu juurdepääsuks kõikidele armatuurlaudadele ja nii edasi. Sellist "täiustatud" klustrit pole mõtet paigaldada hallatud lahendusse, kuna see on sageli kas võimatu või viib vajaduseni välja отключить poole komponente.

NB: See on meie kogemus ja see on üsna spetsiifiline. Me ei väida mingil juhul, et kõigil tasuks iseseisvalt Kubernetes'i klustreid üles seada, selle asemel et kasutada valmis lahendusi. Ütleme nii, et meil ei ole Yandex'i tegelikest Kubernetes'i kasutuse kaalutlustest ja me ei anna selle teenuse kohta hinnangut käesolevas artiklis.

Mis see on ja kellele?

Nii et me oleme juba rääkinud kaasaegsest lähenemisest andmete salvestamisele Kubernetes'is: kuidas CSI töötab ja kuidas kogukond jõudis sellise lähenemiseni.

Praegu on paljud suured pilveteenuse pakkujad välja töötanud draiverid, et kasutada oma "pilve" kettaid kui Persistent Volume Kubernetes'es. Kui pakkujal sellist draiverit ei ole, kuid kõik vajalikud funktsioonid on API kaudu saadaval, siis ei ole midagi, mis takistaks draiveri ise ellu viimist. Meie puhul ongi nii läinud Yandex Cloudiga.

Arenduse aluseks võtsime CSI-draiveri DigitalOceani pilve jaoks ja mõned ideed GCP-draiverist, kuna interaktsioon API-dega nendes pilvedes (Google ja Yandex) on mitmeid sarnaseid jooni. Eelkõige on API nii GCP, kui ka Yandex tagastab objekti Toiming pikaajaliste toimingute (nt uue ketta loomise) staatuse jälgimiseks. API-ga suhtlemiseks Yandex.Cloudis kasutatakse Yandex.Cloud Go SDK-d.

Tehtud töö tulemus on avaldatud GitHubis ja võib olla kasulik neile, kes mingil põhjusel kasutavad oma isiklikku Kubernetes'i installatsiooni Yandex.Cloudi virtuaalmasinatel (aga mitte hallatud klastrit) ja soovivad kettaid kasutada (tellida) kaudu CSI.

Rakendamine

Põhiomadused

Praegu toetab draiver järgmisi funktsioone:

  • Kettad tellitakse igas klastrite tsoonis vastavalt klastris olemasolevate sõlmede topoloogiale;
  • Varem tellitud ketaste kustutamine;
  • Offline-ketaste muutmine (Yandex.Cloud ei toeta kettad, mis on ühendatud virtuaalmasinaga). Kuidas draiverit tuli kohandada, et võimalikult valutult teostada muutmist, vt allpool.

Tulevikus plaanitakse rakendada toe loomist ja kustutamist kettaste jaoks.

Peamine keerukus ja selle ületamine

Yandex.Cloud API-l puudub võimalus suurendada kettaid reaalajas — piirang, mis raskendab PV (püsiv maht) suurendamise operatsiooni: sellisel juhul peab rakenduse pod, mis kasutab ketast, olema peatatud, mis võib põhjustada rakenduse seiskumist.

Vastavalt specifikatsioonide CSI, kui CSI-kontroller teatab, et suudab suurendada kettaid ainult «offline» (VolumeExpansion.OFFLINE), peab ketta suurendamise protsess toimuma järgmiselt:

Kui pistikprogrammil on ainult VolumeExpansion.OFFLINE suurendamise võimekus ja maht on hetkel avaldatud või sõlmes saadaval, siis ControllerExpandVolume PEAB olema kutsutud AINULT pärast ühte järgmist:

  • Pistikprogrammil on kontroller PUBLISH_UNPUBLISH_VOLUME võimekus ja ControllerUnpublishVolume on edukalt kutsutud.

VÕI MUUD

  • Pistikprogrammil ei ole kontrolleri PUBLISH_UNPUBLISH_VOLUME võimekust, pistikprogrammil on sõlme STAGE_UNSTAGE_VOLUME võimekust ja NodeUnstageVolume on edukalt lõpule viidud.

VÕI MUUD

  • Pistikprogrammil ei ole kontrolleri PUBLISH_UNPUBLISH_VOLUME võimekust, ega sõlme STAGE_UNSTAGE_VOLUME võimekust ja NodeUnpublishVolume ei ole edukalt lõpule viidud.

Tegelikult tähendab see, et enne ketta suurendamist tuleb see virtuaalmasinast lahti ühendada.

Kahjuks, rakendus CSI spetsifikatsioonid ei vasta suunistele sidecar'ide kaudu:

  • Sidecar konteineris csi-attacher, mis peaks vastutama vajaliku vahemaa olemasolu eest mountide vahel, offline-resize'i puhul see funktsioon lihtsalt ei ole rakendatud. Arutelu selle üle algatasid siin.
  • Mis on sidecar-konteiner antud kontekstis? CSI-plugin ise ei suhtle Kubernetes API-ga, vaid reageerib vaid gRPC-kõnedele, mida saadavad sidecar-konteinerid. Viimased arendatakse Kubernetes kogukonna.

Meie juhul (CSI-plugin) disk space'i suurendamise protsess näeb välja järgmine:

  1. Saame gRPC-kõne ControllerExpandVolume;
  2. Püüame suurendada ketast API-s, kuid saame vea, et operatsiooni ei saa teostada, kuna ketas on ühendatud;
  3. Salvestame ketta ID kaardile, mis sisaldab kettasid, mille puhul tuleb teostada suurendamisoperatsioon. Edasi kutsume seda kaarti volumeResizeRequired;
  4. Käsitsi kustutame pod’i, mis kasutab ketast. Kubernetes taaskäivitab selle. Et ketas ei jõuaks enne operatsiooni lõppu ühenduda (ControllerPublishVolume) suurendamisoperatsiooni katsetamisel kontrollime, et ketas on endiselt volumeResizeRequired ja tagastame vea;
  5. CSI-draiver püüab uuesti suurendamisoperatsiooni teostada. Kui operatsioon on edukas, eemaldame ketta volumeResizeRequired;
  6. Kuna ketta ID puudub volumeResizeRequired, ControllerPublishVolume jõuab edukalt lõpule, ketas mountitakse, pod käivitatakse.

Kõik näeb välja piisavalt lihtne, kuid nagu ikka, on peidetud lõkse. Diskide suurendamisega tegeleb external-resizer, mis juhul, kui operatsioon ebaõnnestub, kasutab järjekorda mille näol on tegu eksponentsiaalselt kasvava ajavahemikuga kuni 1000 sekundini:

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)},
  )
}

See võib aeg-ajalt põhjustada, et disk space'i suurendamise operatsioon venib 15+ minutiks ja seega vastava pod'i mitte kättesaadavuseks.

Ainukeseks variandiks, mis võimaldas meil piisavalt lihtsalt ja valutult vähendada potentsiaalset seisaku aega, oli oma versiooni external-resizer kasutamine maksimaalse ajapiiranguga 5 sekundile:

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

Me ei pidanud vajalikuks äkitselt arutelusid alustada ja external-resizer'i patši teha, kuna offline diskide suurendamine on anahronism, mis peagi kaob kõigi pilveteenuste pakkujate juurest.

Kuidas alustada kasutamist?

Draiver on toetatud Kubernetes versioonis 1.15 ja uuemates. Draiveri tööks peavad olema täidetud järgmised nõuded:

  • Lipp --allow-privileged seatud väärtuseks true API-serveri ja kubeleti jaoks;
  • Aktiveeritud --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true API-serveri ja kubeleti jaoks;
  • Mountimise levitamine (mount propagation) peab olema klastris lubatud. Docker'i kasutamisel peab deemon olema konfigureeritud nii, et lubatud on jagatud mount'id.

Kõik vajalikud installimisprotsessi sammud on kirjas README's.Installeerimine hõlmab objektide loomist Kuberneteses manifestide põhjal.

Draiveri tööks on vajalik järgmine:

  • Manifestis tuleb näidata katalooge ID-d (folder-id) Yandex.Cloudis (vt dokumentatsiooni);
  • Yandex.Cloud API-ga suhtlemiseks kasutatakse CSI-draiveris teenusekontot. Manifestis Secret tuleb edastada volitatud võtmed teenusekontolt. Dokumentatsioonis kirjeldatud, kuidas luua teenusekonto ja saada võtmed.

Üldiselt — proovige, ja me oleksime rõõmsad tagasiside ja uute probleemide teemade üle, kui satute mingitesse probleemidesse!

Edasine tugi

Kokkuvõtteks tahame rõhutada, et me arendasime selle CSI-draiveri mitte mitte niivõrd soovist nautida Go keeles rakenduste loomist, vaid ettevõtte sees esinenud ägeda vajaduse tõttu. Oma rakenduse toetamine ei tundu meile mõttekas, seega kui Yandex näitab huvi ja otsustab draiveri toetamise jätkata, oleme huvitatud reposi neile üleandmisest.

Lisaks, võib-olla on Yandex'l oma rakendus CSI-draiver tõstatatud Kubernetes'is oma hallatud klastris, mille nad võiksid välja anda avatud lähtekoodiga. See variant näib meile samuti soodne — kogukond saab kasutada teenusepakkuja poolt testitud draiverit, mitte kolmanda osapoole oma.

P.S.

Lugege ka meie blogist:

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster