Meie kogemus CSI-draiveri arendamisel Kuberneteses Yandex.Cloudile

Meie kogemus CSI-draiveri arendamisel Kuberneteses Yandex.Cloudile

Meil on hea meel teatada, et ettevõte «Flant» suurendab oma panust Kubernetes'e avatud lähtekoodiga tööriistadesse, vabastades CSI draiveri alpha versiooni (Container Storage Interface) Yandex Cloud'ile.

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

Sissejuhatus

Miks see on vajalik?

Käesoleva ettevõtte sees, alates Kubernetes'e tootmisest meie poolt (st juba mitu aastat), on arenenud meie enda tööriist (deckhouse), mille me plaanime peagi avatud lähtekoodiga projektiks muuta. Selle abil konfigureerime ja seadistame me kõik oma klastrid ühtlaselt, ja praegu on neid juba üle 100, erinevates riistvarakonfiguratsioonides ja kõigis pakutavates pilveteenustes.

Deckhouse'i kasutavad klastrid sisaldavad kõiki vajalikke komponente tööks: koormuse tasakaalustajad, mugava graafikuga jälgimine, mõõdikud ja hoiatused, autentimine väliste pakkujate kaudu juurdepääsuks kõigile juhtpaneelidele ja nii edasi. Sellise "täiustatud" klastriga ei ole mõtet kasutada hallatud lahendust, kuna sageli pole seda kas võimalik või see nõuab poole komponentide välja lülitamist.

NB: See on meie kogemus ja see on üsna spetsiifiline. Me ei väida sugugi, et igaühel tasuks ise tegeleda Kubernetes'e klastrite käivitamisega, selle asemel et kasutada valmislahendusi. Ütleme nii, et meil ei ole reaalset kogemust Yandexi Kubernetes'e kasutamisega ning me ei anna selle teenuse kohta selles artiklis mingit hinnangut.

Mis see on ja kellele see on mõeldud?

Nii et me oleme juba rääkinud kaasaegsetest lähenemistest Kubernetes'e salvestustes: kuidas CSI töötab ja kuidas kogukond jõudis sellise lähenemiseni.

Praegu on paljud suured pilveteenuste pakkujad välja töötanud draivereid, et kasutada oma "pilve" kettaid kui Persistent Volume Kuberneteses. Kui sellist draiverit pakkujal ei ole, kuid kõik vajalikud funktsioonid on saadaval API kaudu, siis ei ole midagi takistamas oma draiveri loomist. Meie puhul tegime just sedasi Yandex.Cloudiga.

Arenduse aluseks võtsime CSI-draiveri DigitalOceanile ja paar ideed GCP-draiverist, sest nende pilvede (Google ja Yandex) API-de vahel on mitmeid sarnasusi. Eelkõige tagastavad API-d nii GCPkui ka Yandex objekti Operation pikemate operatsioonide oleku jälgimiseks (näiteks uue ketta loomine). Yandex.Cloud API-ga suhtlemiseks kasutatakse Yandex.Cloud Go SDK-d.

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

Rakendus

Peamised funktsioonid

Praegu toetab draiver järgmisi funktsioone:

  • Kettad tellimine kõigis klastritsoonides vastavalt klastris olevate sõlmede topoloogiale;
  • Varem tellitud ketaste eemaldamine;
  • Ketaste offline-mõõtmete muutmine (Yandex. Cloud tugi ketaste suurendamine, mis on kinnitatud virtuaalmasinale). Kuidas tuli draiverit täiustada, et võimalikult valutult mõõtmeid muuta, vt allpool.

Tulevikus on plaanis rakendada diskisnapshotide loomise ja kustutamise toetust.

Peamine keerukus ja selle ületamine

Yandex. Cloud API-s puudub reaalajas ketaste suurendamise võimalus — piirang, mis raskendab PV (Persistent Volume) mõõtmete muutmise operatsiooni: sel juhul peab rakenduse pod, mis kasutab ketast, olema peatatud, mis võib põhjustada rakenduse seiskumist.

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

Kui pistikprogramm omab ainult VolumeExpansion.OFFLINE suurendamise võimalust ja maht on hetkel avalikustatud või node'il saadaval, siis ControllerExpandVolume PEAB olema kutsutud AINULT pärast järgmist:

  • Pistikprogrammil on kontroller PUBLISH_UNPUBLISH_VOLUME võime ja ControllerUnpublishVolume on edukalt käivitatud.

Või

  • Pistikprogrammil ei ole kontrolleri PUBLISH_UNPUBLISH_VOLUME võimet, pistikprogrammil on node'i STAGE_UNSTAGE_VOLUME võime ja NodeUnstageVolume on arvutatud edukalt.

Või

  • Pistikprogrammil ei ole kontrolleri PUBLISH_UNPUBLISH_VOLUME võime, ega sõlm STAGE_UNSTAGE_VOLUME võime ja NodeUnpublishVolume on lõpetatud edukalt.

See tähendab, et enne ketta suurendamist tuleb see virtuaalsest masinast eemaldada.

Kahjuks aga teostamine CSI spetsifikatsiooni rakendamine sidecar’ide kaudu ei vasta nendele nõuetele:

  • Sidecar-konteineris csi-attacher, mis peaks tagama vajaliku ajavahemiku montaažide vahel, ei ole offline-suurendamise korral see funktsionaalsus lihtsalt olemas. Arutelu selle üle on algatanud siit.
  • Mis on üldse sidecar-konteiner antud kontekstis? Isegi CSI-plugin ei tegele interaktsiooniga Kubernetes API-ga, vaid reageerib ainult gRPC-kõnedele, mida saadavad talle sidecar-konteinerid. Viimased arendatakse Kubernetes'i kogukonna poolt.

Meie (CSI-plugin) olukorras näeb ketta suurendamise operatsioon välja selline:

  1. Saame gRPC-kõne ControllerExpandVolume;
  2. Püüdleme ketta suurendamise poole API-s, kuid saame vea, et operatsiooni ei saa teostada, kuna disk on monteeritud;
  3. Salvestame ketta identifikaatori kaardile, mis sisaldab diskide loendit, mille jaoks tuleb suurendamise operatsioon läbi viia. Edaspidi nimetame seda kaarti volumeResizeRequired;
  4. Käsitsi eemaldame pod'i, mis kasutab ketast. Kubernetes käivitab selle uuesti. Et kõvaketas ei jõuaks monteeruda (ControllerPublishVolume) enne, kui suurendamise protsess on lõpule jõudnud montaaži katsetamisel, kontrollime, et see kõvaketas on endiselt volumeResizeRequired ja tagastame veateate;
  5. CSI-draiver püüab suurendamise toimingut uuesti teostada. Kui toiming on edukas, eemaldame ketta volumeResizeRequired;
  6. Kuna ketta ID puudub volumeResizeRequired, ControllerPublishVolume läbiviimine on edukas, ketas monteeritakse, pod käivitub.

Kõik tundub piisavalt lihtne, kuid nagu alati, on ka varjatud ohte. Ketaste suurendamist teostab external-resizer, mis veateate korral toimingu teostamisel kasutab järjekorda äge, millel on eksponentsiaalne aja piirangu suurenemine kuni 1000 sekundit:

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 perioodiliselt põhjustada, et ketta suurendamise operatsioon venib 15+ minutiks, muutes seega vastava pod'i kätte saamata.

Ainus variant, mis võimaldas meil piisavalt lihtsalt ja valutult vähendada võimaliku seisaku aega, oli oma versiooni external-resizer kasutamine maksimaalse ajapiiranguga 5 sekundit:

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

Me ei pidanud vajalikuks äkitselt arutelu algatada ja external-resizerit parandama, kuna offline diskide ümbermõõtmine on reliikvia, mis varsti kaob kõigilt pilveteenuse pakkujalt.

Kuidas alustada kasutamist?

Juhtimist toetatakse Kubernetes versioonis 1.15 ja kõrgem. Juhtimise töötamiseks tuleb järgida järgmisi nõudeid:

  • Lipp --allow-privileged seadistatud väärtuseks true API-serveri ja kubelet'i jaoks;
  • Käivitatud --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true API-serveri ja kubelet'i jaoks;
  • Mountimise levik (mount propagation) peab olema klastris lubatud. Dockerit kasutades peab daemon olema konfigureeritud nii, et jagatud mount'id oleksid lubatud.

Kõik vajalikud sammud paigaldamise kohta on toodud README's.Installeerimine hõlmab objektide loomist Kuberneteses manifestide põhjal.

Juhtimise jaoks on teil vaja järgmist:

  • Määrake manifeestis katalooge identiteet (folder-id) Yandex Cloud (vt. dokumentatsioon);
  • Yandex Cloud API-ga suhtlemiseks kasutatakse CSI-draiveris teenusekontot. Manifeedis Secrets peate edastama autorizatsioonivõtmed teenusekontolt. Dokumentatsioonis detailsemalt, kuidas luua teenusekonto ja saada võtmed.

Üldiselt — proovige, ja me ootame head tagasisidet ja uusi probleeme, kui peaksite silmitsi seisma probleemidega!

Edasine tugi

Kokkuvõtteks tahaksime märkida, et seda CSI-draiverit ei ole me ellu viinud üksnes suures soovist rakenduste arendamisega tegeleda, vaid ettevõttes sisemise terava vajaduse tõttu. Oma rakenduse toetamist ei pea me mõistlikuks, seega, kui Yandex peaks näitama huvi ja otsustama draiveri toe jätkuvuse, siis anname hea meelega hoidla nende käsutusse.

Lisaks on ilmselt Yandexi managed Kubernetes klastris oma CSI draiveri rakendus, mille saab avada Open Source'iks. Selline suund tundub meile samuti soodne — kogukond saab kasutada teenusepakkujast kontrollitud draiverit, mitte kolmanda osapoole firma oma.

P.S.

Lugege ka meie blogist:

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster