A CSI-meghajtó fejlesztésének tapasztalata Kubernetesben a Yandex.Cloud számára

A CSI-meghajtó fejlesztésének tapasztalata Kubernetesben a Yandex.Cloud számára

Örömmel jelentjük be, hogy a Flant cég hozzájárulása a Kubernetes Open Source eszközeihez bővül, kiadva a CSI illesztőprogram alfa verzióját (Container Storage Interface) a Yandex Felhőhöz.

De mielőtt rátérnénk a megvalósítás részleteire, válaszoljunk arra a kérdésre, hogy miért van erre egyáltalán szükség, amikor a Yandex már kínálja a Managed Service for Kubernetes-t..

Bevezetés

Miért?

Cégünk belső működésében, a Kubernetes éles üzemeltetésének megkezdése óta (azaz már több éve) folyamatosan fejlődik egy saját eszközünk (deckhouse), amelyet szintén tervezzük hamarosan Open Source projektként elérhetővé tenni. Ennek segítségével egységesen konfiguráljuk és állítjuk be az összes klasztert, és jelenleg már több mint 100 klaszterünk van, különböző hardverkonfigurációkon és minden elérhető felhőszolgáltatáson.

A deckhouse-t használó klaszterek minden szükséges komponenst tartalmaznak: terheléselosztók, monitoring kényelmes grafikonokkal, metrikákkal és riasztásokkal, felhasználói autentikáció külső szolgáltatók által a dashboardok eléréséhez és így tovább. Egy ilyen „feljavított” klasztert nincs értelme menedzselt megoldásként telepíteni, mert gyakran ez lehetetlen, vagy félkomponens letiltásához vezet.

NB: Ez a tapasztalatunk, és elég speciális. Semmiképpen sem állítjuk, hogy mindenkinek önállóan kellene a Kubernetes klaszterek telepítésével foglalkoznia ahelyett, hogy kész megoldásokat használnának. Érdemes megjegyezni, hogy a Yandex-től nincs valós Kubernetes üzemeltetési tapasztalatunk, ezért a szolgáltatás értékelésével kapcsolatban semmiféle nyilatkozatot nem teszünk a jelen cikkben.

Mi ez és kinek szól?

Tehát már beszéltünk a Kubernetes tárolókkal kapcsolatos modern megközelítésekről: hogyan működik a CSI és hogyan jutott a közösség ehhez a megközelítéshez.

Jelenleg sok nagy felhőszolgáltató kifejlesztett illesztőprogramokat a saját „felhős” lemezeik Kubernetes Persistent Volume-ként való használatához. Ha pedig a szolgáltatónak nincs ilyen illesztőprogramja, de minden szükséges funkció API-n keresztül rendelkezésre áll, akkor semmi sem akadályozza meg, hogy saját erőből implementálj egy illesztőprogramot. Mi is így jártunk a Yandex Felhő esetében.

A fejlesztés alapjául a DigitalOcean felhőhöz készült CSI-illesztőprogramot vettük és néhány ötletet a GCP illesztőprogramból, mivel ezen felhők (Google és Yandex) API-ja között számos hasonlóság van. Különösen az API mindkettőnél, és a GCPYandex is. visszatér egy objektumot Művelet a hosszú távú műveletek állapotának nyomon követésére (például új lemez létrehozása). Az API-val való interakcióhoz a Yandex.Cloud-ot használják Yandex.Cloud Go SDK.

A végrehajtott munka eredménye közzétéve a GitHub-on és hasznos lehet azok számára, akik valamilyen okból saját Kubernetes telepítést használnak a Yandex.Cloud virtuális gépein (de nem kész, kezelt klaszter) és szeretnék használni (rendelni) a lemezeket a CSI-n keresztül.

Megvalósítás

Főbb lehetőségek

Jelenleg a meghajtó a következő funkciókat támogatja:

  • Lemezek rendelése a klaszter összes zónájában a klaszterben lévő csomópontok topológiája szerint;
  • Korábban rendelhető lemezek eltávolítása;
  • Offline méretezés a lemezekhez (Yandex.Cloud nem támogatja növelés lemezek, amelyek csatlakoztatva vannak a virtuális géphez). Arról, hogy hogyan kellett módosítani a meghajtót, hogy a lehető legkisebb fájdalommal végrehajthassuk a méretezést, lásd alább.

A jövőben tervezik a lemezképek létrehozásának és törlésének támogatását.

A fő nehézség és annak leküzdése

Az, hogy az API Yandex.Cloud-ban nincs lehetőség a lemezek valós idejű növelésére — korlátozás, amely megnehezíti a PV (Persistent Volume) méretezési műveletet: hiszen ilyenkor a pod alkalmazás, amely a lemezt használja, leállítása szükséges, ami leállást okozhat az alkalmazásban.

A következő szerint a CSI specifikációban, ha a CSI-vezérlő arról tájékoztat, hogy a lemezek méretezését csak «offline» tudja végezni (VolumeExpansion.OFFLINE), akkor a lemez növelési folyamatának így kell zajlania:

Ha a plugin csak VolumeExpansion.OFFLINE kiterjesztési képességgel rendelkezik és a Volume jelenleg ki van adva vagy elérhető egy csomóponton, akkor A ControllerExpandVolume-ot CSAK akkor kell hívni, miután:

  • A plugin rendelkezik controller PUBLISH_UNPUBLISH_VOLUME képességgel és A ControllerUnpublishVolume-t sikeresen hívták.

VAGY HA

  • A plugin NEM rendelkezik vezérlő PUBLISH_UNPUBLISH_VOLUME képességgel, a plugin rendelkezik csomópont STAGE_UNSTAGE_VOLUME képességgel, és A NodeUnstageVolume sikeresen befejeződött.

VAGY HA

  • A plugin NEM rendelkezik vezérlő PUBLISH_UNPUBLISH_VOLUME sem csomópont STAGE_UNSTAGE_VOLUME képességgel, és A NodeUnpublishVolume sikeresen befejeződött.

Lényegében ez azt jelenti, hogy a lemezt le kell csatlakoztatni a virtuális gépről, mielőtt növelni lehet.

Sajnálatos módon % implementációja, a CSI specifikációk közötti sidecar-ok nem felelnek meg ezeknek a követelményeknek:

  • A sidecar konténerben csi-attacher, amelynek biztosítania kell a szükséges szünetet a csatlakoztatások között, offline méretezés esetén egyszerűen nem valósult meg ez a funkció. Erről a vitát kezdeményeztek. itt.
  • Mi is az a sidecar konténer ebben a kontextusban? Maga a CSI plugin nem foglalkozik a Kubernetes API-val való interakcióval, csak reagál azokra a gRPC hívásokra, amelyeket a sidecar konténerek küldenek. Az utóbbiak fejlesztés alatt állnak a Kubernetes közösségről.

A mi esetünkben (CSI plugin) a lemez bővítési művelete a következőképpen néz ki:

  1. Megkapjuk a gRPC hívást A ControllerExpandVolume-ot;
  2. Megpróbáljuk bővíteni a lemezt az API-ban, de hibát kapunk, amely arra figyelmeztet, hogy a művelet nem hajtható végre, mivel a lemez csatlakoztatva van;
  3. Mentjük a lemez azonosítóját egy térképre, amely a lemezeket tartalmazza, amelyek esetében bővítési műveletet kell végezni. A továbbiakban a tékéről a következőképpen fogunk hivatkozni: volumeResizeRequired;
  4. Kézzel eltávolítjuk a podot, amely a lemezt használja. A Kubernetes újraindítja azt. Annak érdekében, hogy a lemez ne csatlakozzon (ControllerPublishVolume) a bővítési művelet befejezése előtt, az összekapcsolás próbálkozásakor ellenőrizzük, hogy a lemez továbbra is volumeResizeRequired és hibát adunk vissza;
  5. A CSI driver megpróbálja újra elvégezni a bővítési műveletet. Ha a művelet sikeres, a lemezt eltávolítjuk a volumeResizeRequired;
  6. Mivel a lemez azonosítója hiányzik a volumeResizeRequired, ControllerPublishVolume sikeresen végbemegy, a lemez csatlakozik, a pod elindul.

Mindez elég egyszerűen hangzik, de mint mindig, itt is vannak buktatók. A lemezek bővítésével foglalkozik external-resizer, amely hiba esetén a művelet végrehajtása során használja a sorqueue-t exponenciális időzítésű időtúllépéssel, amely 1000 másodpercig terjed:

func DefaultControllerRateLimiter() RateLimiter {
  return NewMaxOfRateLimiter(
  NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second),
  // 10 qps, 100 vödrös méret. Ez csak a próbálkozás sebességére vonatkozik, és ez csak az általános tényező (nem elemenként)
  &BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
  )
}

Ez időnként ahhoz vezethet, hogy a lemez bővítési művelete 15+ percig elhúzódik, így a megfelelő pod elérhetetlen.

Az egyetlen lehetőség, amely viszonylag könnyen és fájdalommentesen lehetővé tette számunkra a potenciális leállási idő csökkentését, az volt, hogy saját verziót használtunk az external-resizerből, maximális időtúllépési korlátozással 5 másodperc:

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

Nem tartottuk szükségesnek, hogy sürgősen kezdeményezzünk egy vitát és javítsuk az external-resizer-t, mivel a lemezek offline bővítése — a többi felhőszolgáltató által hamarosan megszűnő archaizmus.

Hogyan kezdjük el a használatát?

A drivert a Kubernetes 1.15-ös és újabb verziói támogatják. A driver működéséhez a következő követelményeknek kell teljesülniük:

  • Zászló --allow-privileged beállítva igaz az API-szerver és kubelet számára;
  • Bekapcsolva --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true az API-szerver és kubelet számára;
  • A csatlakoztatás terjedelme (mount propagation) engedélyezve kell legyen a klaszterben. Docker használata esetén a démon konfigurálva kell legyen, hogy megengedje a megosztott csatlakozásokat (shared mounts).

Minden szükséges lépés az installációval kapcsolatban a README dokumentumban. Az installálás a Kubernetes objektumok létrehozását jelenti a manifesztumokból.

A meghajtó működéséhez a következőre van szükség:

  • Meg kell adnia a manifesztumban a könyvtár azonosítóját (folder-id) a Yandex Felhőben (lásd a dokumentációt);
  • A Yandex Felhő API-jával való interakcióhoz a CSI-meghajtóban szolgáltatói fiókot kell használni. A Secret manifesztumban meg kell adni az engedélyezett kulcsokat a szolgáltatói fióktól. A dokumentációban ami le van írva, hogyan kell szolgáltatói fiókot létrehozni és kulcsokat szerezni.

Összességében — próbáld ki, és örömmel fogadjuk a visszajelzéseket és új jelzéseket, ha bármilyen problémával találkozna!

További támogatás

Összefoglalva szeretnénk megjegyezni, hogy ezt a CSI-meghajtót nem nagy kíváncsiságból kezdtük el a Go alkalmazások írásával foglalkozni, hanem a cégünk belső igényéből. Nem látjuk célszerűnek a saját megvalósításunk fenntartását, ezért ha a Yandex érdeklődést mutat és továbbra is támogatni kívánja a meghajtót, örömmel átadjuk a repót a rendelkezésére.

Továbbá, valószínűleg a Yandex-nek a managed Kubernetes klaszterében van saját CSI-meghajtó realizációja, amelyet Open Source-ként ki lehet adni. Ez a fejlesztési lehetőség is kedvező számunkra — a közösség megbízható meghajtót használhatna a szolgáltatótól, nem pedig egy külső cégtől.

P.S.

Olvasson további információkat a blogunkban:

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster