Naše zkušenosti s vývojem ovladače CSI v Kubernetes pro Yandex.Cloud

Naše zkušenosti s vývojem ovladače CSI v Kubernetes pro Yandex.Cloud

S potěšením oznamujeme, že Flant vydáním rozšiřuje svůj příspěvek k nástrojům Open Source pro Kubernetes alfa verze ovladače CSI (Container Storage Interface) pro Yandex.Cloud.

Než však přejdeme k podrobnostem implementace, odpovězme na otázku, proč je to vůbec potřeba, když Yandex již službu má Spravovaná služba pro Kubernetes.

úvod

Proč je to?

V rámci naší společnosti od samého začátku používání Kubernetes ve výrobě (tedy již několik let) vyvíjíme vlastní nástroj (deckhouse), který mimochodem také plánujeme brzy zpřístupnit jako Open Source projekt . S jeho pomocí jednotně konfigurujeme a konfigurujeme všechny naše clustery a v současné době jich je již více než 100, na široké škále hardwarových konfigurací a ve všech dostupných cloudových službách.

Clustery, které používají palubní přístřešek, mají všechny komponenty nezbytné pro provoz: balancéry, monitorování pomocí pohodlných grafů, metriky a výstrahy, ověřování uživatelů prostřednictvím externích poskytovatelů pro přístup ke všem dashboardům a tak dále. Nemá smysl instalovat takový „napumpovaný“ cluster do spravovaného řešení, protože to je často buď nemožné, nebo to povede k nutnosti deaktivovat polovinu komponent.

NB: Toto je naše zkušenost a je zcela konkrétní. V žádném případě nenavrhujeme, aby každý nasazoval clustery Kubernetes sám, místo aby používal hotová řešení. Mimochodem, nemáme žádné skutečné zkušenosti s provozem Kubernetes od Yandexu a v tomto článku nebudeme tuto službu hodnotit.

Co to je a pro koho?

Takže jsme již mluvili o moderním přístupu k úložišti v Kubernetes: jak CSI funguje? и jak komunita přišla k tomuto přístupu.

V současné době mnoho velkých poskytovatelů cloudových služeb vyvinulo ovladače pro použití svých cloudových disků jako trvalého svazku v Kubernetes. Pokud dodavatel takový ovladač nemá, ale všechny potřebné funkce zajišťuje přes API, pak vám nic nebrání si ovladač implementovat sami. To se stalo s Yandex.Cloud.

Vzali jsme jako základ pro rozvoj CSI ovladač pro cloud DigitalOcean a pár nápadů od ovladače pro GCP, protože interakce s API těchto cloudů (Google a Yandex) má řadu podobností. Zejména API a GCP, a Yandex vrátit předmět Operation ke sledování stavu dlouho probíhajících operací (například vytvoření nového disku). Chcete-li komunikovat s rozhraním Yandex.Cloud API, použijte Yandex.Cloud Go SDK.

Výsledek odvedené práce zveřejněno na GitHubu a může být užitečné pro ty, kteří z nějakého důvodu používají vlastní instalaci Kubernetes na virtuálních strojích Yandex.Cloud (nikoli však hotový spravovaný cluster) a chtěli by používat (objednat) disky přes CSI.

uskutečnění

Klíčové vlastnosti

V současné době ovladač podporuje následující funkce:

  • Řazení disků ve všech zónách clusteru podle topologie uzlů v clusteru;
  • Vyjmutí dříve objednaných disků;
  • Offline změna velikosti disků (Yandex.Cloud nepodporují zvýšení disků připojených k virtuálnímu počítači). Informace o tom, jak musel být ovladač upraven, aby změna velikosti byla co nejméně bolestivá, viz níže.

Do budoucna plánujeme implementovat podporu pro vytváření a mazání snímků disku.

Hlavní problém a jak ho překonat

Nedostatek možnosti zvětšovat disky v reálném čase v rozhraní Yandex.Cloud API je omezení, které komplikuje operaci změny velikosti pro PV (Persistent Volume): v tomto případě je nutné, aby byl aplikační modul, který disk používá, zastaven, a to může způsobit výpadky aplikací.

Podle Specifikace CSI, pokud řadič CSI hlásí, že může měnit velikost disků pouze „offline“ (VolumeExpansion.OFFLINE), pak by proces zvětšování disku měl probíhat takto:

Pokud má plugin pouze VolumeExpansion.OFFLINE možnost rozšíření a objem je aktuálně publikován nebo dostupný na uzlu ControllerExpandVolume MUSÍ být zavoláno POUZE po:

  • Plugin má ovladač PUBLISH_UNPUBLISH_VOLUME schopnost a ControllerUnpublishVolume byla úspěšně vyvolána.

NEBO JINAK

  • Plugin NEMÁ ovladač PUBLISH_UNPUBLISH_VOLUME má plugin uzel STAGE_UNSTAGE_VOLUME schopnosti a NodeUnstageVolume byl úspěšně dokončen.

NEBO JINAK

  • Plugin NEMÁ ovladač PUBLISH_UNPUBLISH_VOLUME schopnost, ani uzel STAGE_UNSTAGE_VOLUME schopnosti a NodeUnpublishVolume úspěšně dokončeno.

To v podstatě znamená, že musíte disk odpojit od virtuálního počítače, než jej rozbalíte.

Nicméně bohužel implementace Specifikace CSI přes postranní vozíky nesplňuje tyto požadavky:

  • V kontejneru postranního vozíku csi-attacher, který by měl být zodpovědný za přítomnost požadované mezery mezi připojeními, tato funkce prostě není implementována v offline změně velikosti. Byla o tom zahájena diskuse zde.
  • Co přesně je v této souvislosti kontejner postranního vozíku? Samotný plugin CSI neinteraguje s Kubernetes API, ale pouze reaguje na volání gRPC, která mu posílají kontejnery sidecar. Nejnovější se vyvíjejí od komunity Kubernetes.

V našem případě (CSI plugin) operace zvětšení disku vypadá takto:

  1. Přijímáme hovor gRPC ControllerExpandVolume;
  2. Snažíme se zvětšit disk v API, ale dostáváme chybu o nemožnosti provedení operace, protože disk je připojen;
  3. Identifikátor disku uložíme do mapy, která obsahuje disky, u kterých je potřeba provést operaci zvýšení. Níže pro stručnost budeme tuto mapu nazývat jako volumeResizeRequired;
  4. Ručně vyjměte podložku, která používá disk. Kubernetes jej restartuje. Aby se disk nestihl připojit (ControllerPublishVolume) před dokončením operace zvýšení při pokusu o připojení zkontrolujeme, zda je daný disk stále in volumeResizeRequired a vrátí chybu;
  5. Ovladač CSI se pokusí znovu provést operaci změny velikosti. Pokud byla operace úspěšná, vyjměte disk z volumeResizeRequired;
  6. Protože Chybí ID disku volumeResizeRequired, ControllerPublishVolume úspěšně projde, disk je připojen, pod se spustí.

Vše vypadá dost jednoduše, ale jako vždy to má svá úskalí. Zvětšuje disky externí resizer, který v případě chyby během operace používá frontu s exponenciálním prodloužením časového limitu až na 1000 sekund:

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 může periodicky vést k tomu, že se operace rozšiřování disku prodlouží na více než 15 minut, a proto bude odpovídající modul nedostupný.

Jedinou možností, která nám celkem snadno a bezbolestně umožnila snížit potenciální prostoje, bylo použití naší verze externího resizeru s maximálním časovým limitem za 5 sekund:

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

Nepovažovali jsme za nutné urychleně iniciovat diskuzi a záplatovat external-resizer, protože offline změna velikosti disků je návrat, který brzy zmizí u všech cloudových poskytovatelů.

Jak ho začít používat?

Ovladač je podporován na Kubernetes verze 1.15 a vyšší. Aby řidič mohl pracovat, musí být splněny následující požadavky:

  • Vlajka --allow-privileged nastavit na hodnotu true pro server API a kubelet;
  • Zahrnuta --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true pro server API a kubelet;
  • Propagace montáže (mount propagace) musí být v clusteru povoleno. Při používání Dockeru musí být démon nakonfigurován tak, aby umožňoval sdílená připojení.

Všechny potřebné kroky pro samotnou instalaci popsané v README. Instalace zahrnuje vytváření objektů v Kubernetes z manifestů.

Aby ovladač fungoval, budete potřebovat následující:

  • Zadejte identifikátor adresáře v manifestu (folder-id) Yandex.Cloud (viz dokumentace);
  • K interakci s rozhraním Yandex.Cloud API používá ovladač CSI servisní účet. V manifestu musí být předáno Tajné autorizované klíče ze servisního účtu. V dokumentaci popsáno, jak si vytvořit servisní účet a získat klíče.

Celkově vzato - zkuste to, a budeme rádi za zpětnou vazbu a nové záležitostipokud narazíte na nějaké problémy!

Další podpora

V důsledku toho bychom chtěli poznamenat, že jsme tento ovladač CSI implementovali ne z velké touhy bavit se psaním aplikací v Go, ale z naléhavé potřeby v rámci společnosti. Nezdá se nám praktické udržovat vlastní implementaci, takže pokud Yandex projeví zájem a rozhodne se ovladač nadále podporovat, rádi jim úložiště převedeme.

Kromě toho má Yandex pravděpodobně vlastní implementaci ovladače CSI ve svém spravovaném clusteru Kubernetes, který lze vydat v Open Source. I tuto možnost vývoje vnímáme jako příznivou – komunita bude moci používat osvědčený ovladač od poskytovatele služeb, nikoli od třetí strany.

PS

Přečtěte si také na našem blogu:

Zdroj: www.habr.com

Přidat komentář