ProHoster > Blog > podávání > 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.
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:
Přijímáme hovor gRPC ControllerExpandVolume;
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;
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;
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;
Ovladač CSI se pokusí znovu provést operaci změny velikosti. Pokud byla operace úspěšná, vyjměte disk z volumeResizeRequired;
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:
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.