
S potěšením oznamujeme, že společnost „Flant“ posiluje svůj příspěvek k nástrojům Open Source pro Kubernetes vydáním (Container Storage Interface) pro Yandex.Cloud.
Ale předtím, než se dostaneme k podrobnostem implementace, odpovězme na otázku, proč to vlastně potřebujeme, když má Yandex již službu .
Úvod
Proč to?
Uvnitř naší společnosti, ještě od samého začátku používání Kubernetes v produkci (tj. už několik let), se vyvíjí vlastní nástroj (deckhouse), který, mimochodem, plánujeme brzy zpřístupnit jako projekt Open Source. S jeho pomocí jednotně konfigurujeme a nastavujeme všechny naše clustery, a v současné době jich máme více než 100, přičemž na nejrůznějších konfiguracích hardware a ve všech dostupných cloudových službách.
Clustery, ve kterých se používá deckhouse, obsahují všechny potřebné komponenty pro provoz: vyvažovače zatížení, monitoring s pohodlnými grafy, metrikami a upozorněními, autentizaci uživatelů prostřednictvím externích poskytovatelů pro přístup ke všem dashboardům a tak dále. Takový „vylepšený“ cluster nemá smysl nasazovat v managed řešení, protože to často není možné, nebo to povede k nutnosti vypnout polovinu komponentů.
NB: Toto je naše zkušenost a je poměrně specifická. V žádném případě netvrdíme, že se všichni mají sami zabývat nasazením clusterů Kubernetes namísto toho, aby využívali hotová řešení. Mimochodem, reálnou zkušenost s používáním Kubernetes od Yandexu nemáme a v této článku nebudeme hodnotit tuto službu.
Co to je a pro koho?
Takže jsme již hovořili o moderním přístupu k úložištím v Kubernetes: a k takovému 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 Persistent Volume v Kubernetes. Pokud však daný poskytovatel nemá takový ovladač, ale všechny potřebné funkce jsou poskytovány přes API, nic nebrání tomu, abychom ovladač realizovali vlastními silami. A tak se to stalo i s Yandex.Cloud.
Základem pro vývoj jsme vzali a pár myšlenek z , protože interakce s API těchto cloudů (Google a Yandex) má řadu podobností. Především, API mají jak , tak vrací objekt Operace pro sledování stavu dlouhotrvajících operací (například vytváření nového disku). Pro interakci s API Yandex.Cloud se používá .
Výsledek vykonané práce a může být užitečný těm, kteří z nějakého důvodu používají vlastní instalaci Kubernetes na virtuálních strojích Yandex.Cloud (ale ne hotový managed cluster) a chtěli by používat (objednávat) disky prostřednictvím CSI.
Implementace
Hlavní funkce
V současné době ovladač podporuje následující funkce:
- Objednávání disků ve všech zónách clusteru podle topologie existujících uzlů v clusteru;
- Odstraňování dříve objednaných disků;
- Offline resize pro disky (Yandex.Cloud zvětšování disků, které jsou připojeny k virtuálnímu stroji). O tom, jak bylo nutné upravit ovladač pro co nejbezproblémovější provedení resize, viz níže.
Do budoucna se plánuje realizace podpory vytváření a odstraňování snímků disků.
Hlavní obtíž a její překonání
Nedostatek možnosti zvyšování disků v reálném čase v API Yandex.Cloud — omezení, které ztěžuje operaci resize pro PV (Persistent Volume): vždyť v takovém případě je nutné, aby pod aplikace, která používá disk, byl zastaven, a to může způsobit nefunkčnost aplikace.
Podle , pokud CSI řadič hlásí, že umí provádět resize disků pouze „offline“ (VolumeExpansion.OFFLINE), pak proces zvyšování disku musí probíhat takto:
Pokud plugin má pouze
VolumeExpansion.OFFLINEcapability pro zvětšení a objem je aktuálně publikován nebo dostupný na uzlu, pakControllerExpandVolumeMUSÍ být volán POUZE po:
- Plugin má řadič
PUBLISH_UNPUBLISH_VOLUMEcapability aControllerUnpublishVolumebyl úspěšně vyvolán.NEBO
- Pokud plugin NEMÁ řadič
PUBLISH_UNPUBLISH_VOLUMEcapability, plugin má uzlovéSTAGE_UNSTAGE_VOLUMEcapability aNodeUnstageVolumebyl úspěšně dokončen.NEBO
- Pokud plugin NEMÁ řadič
PUBLISH_UNPUBLISH_VOLUMEkapacitu, ani uzelSTAGE_UNSTAGE_VOLUMEcapability aNodeUnpublishVolumebyl úspěšně dokončen.
V podstatě to znamená, že je nutné odpojit disk od virtuálního stroje, než ho zvětšíte.
Bohužel však, implementace specifikace CSI prostřednictvím sidecarů neodpovídají těmto požadavkům:
- V sidecar kontejneru
csi-attacher, který by měl zajišťovat přítomnost potřebného intervalu mezi montážemi, není při offline-resize jednoduše tento funkční prvek realizován. Diskusi o tom iniciovali . - Co vlastně znamená sidecar kontejner v tomto kontextu? Samotný CSI plugin se nezabývá interakcí s Kubernetes API, ale pouze reaguje na gRPC volání, která mu posílají sidecar kontejnery. Tyto komunity Kubernetes.
V našem případě (CSI plugin) operace zvětšení disku vypadá takto:
- Získáváme gRPC volání
ControllerExpandVolume; - Snažíme se zvětšit disk v API, ale obdržíme chybu o nemožnosti provést operaci, protože disk je připojen;
- Ukládáme identifikátor disku do mapy, která obsahuje disky, pro které je třeba provést operaci zvětšení. Dále pro stručnost budeme tuto mapu nazývat
volumeResizeRequired; - Ručním způsobem odstraňujeme pod, který používá disk. Kubernetes ho přitom restartuje. Aby disk nebyl připojen (
ControllerPublishVolume) před dokončením operace zvětšení při pokusu o připojení, kontrolujeme, že tento disk je stále vvolumeResizeRequireda vracíme chybu; - CSI ovladač se znovu pokouší provést operaci resize. Pokud je operace úspěšná, odstraníme disk z
volumeResizeRequired; - Jelikož identifikátor disku není přítomen v
volumeResizeRequired,ControllerPublishVolumeprochází úspěšně, disk se připojuje, pod se spouští.
Vše vypadá docela jednoduše, ale jako vždy jsou tu skryté úskalí. Zvětšení disků zajišťuje , který v případě chyby při provádění operace s exponenciálně se zvyšujícími časovými limity až 1000 sekund:
func DefaultControllerRateLimiter() RateLimiter {
return NewMaxOfRateLimiter(
NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second),
// 10 qps, 100 velikost bucketu. Toto je pouze pro rychlost opakování a je to jen celkový faktor (ne na položku)
&BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
)
}To může občas způsobit, že operace zvětšení disku se protahuje na více než 15 minut a tím dochází k nedostupnosti odpovídajícího podu.
Jedinou možností, která nám dostatečně snadno a bezbolestně umožnila snížit potenciální dobu prostojů, bylo použití naší verze external-resizer s maximálním limitem časového limitu :
workqueue.NewItemExponentialFailureRateLimiter(5*time.Millisecond, 5*time.Second)Nehodlali jsme urgentně iniciovat diskusi a patchovat external-resizer, protože offline resizing disků je atavismus, který brzy vymizí u všech poskytovatelů cloudu.
Jak začít používat?
Ovladač je podporován v Kubernetes verzi 1.15 a výše. Pro funkci ovladače musí být splněny následující požadavky:
- Přepínač
--allow-privilegednastaven na hodnotutruepro API server a kubelet; - Zapnuto
--feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=truepro API server a kubelet; - Šíření montování () musí být povoleno v clusteru. Při použití Dockeru musí být démon nakonfigurován tak, aby bylo povoleno sdílené montování (shared mounts).
Všechny potřebné kroky pro samotnou instalaci . Instalace zahrnuje vytváření objektů v Kubernetes z manifestů.
Pro provoz ovladače budete potřebovat následující:
- Uvedení identifikátoru adresáře v manifestu (
folder-id) Yandex.Cloud (); - Pro interakci s API Yandex.Cloud v CSI ovladači se používá servisní účet. V manifestu Secret je třeba předat od servisního účtu. V dokumentaci , jak vytvořit servisní účet a získat klíče.
Obecně — , a budeme rádi za zpětnou vazbu a , pokud narazíte na nějaké problémy!
Další podpora
Na závěr bychom rádi zdůraznili, že tento CSI ovladač jsme implementovali ne z velké touhy zabývat se vývojem aplikací v Go, ale z naléhavé potřeby uvnitř společnosti. Nepřijde nám rozumné udržovat vlastní implementaci, proto pokud Yandex projeví zájem a rozhodne se pokračovat v podpoře ovladače, rádi předáme repozitář do jejich správy.
Kromě toho má Yandex pravděpodobně ve spravovaném clusteru Kubernetes vlastní implementaci CSI ovladače, který lze vydat jako Open Source. Taková možnost se nám také jeví jako příznivá — komunita by mohla využívat osvědčený ovladač od poskytovatele služeb, nikoli od třetí strany.
P.S.
Přečtěte si také náš blog:
- «»;
- «»;
- «»;
- «».
Zdroj: habr.com
