ProHoster > Blog > administracja > Nasze doświadczenie w tworzeniu sterownika CSI w Kubernetes dla Yandex.Cloud
Nasze doświadczenie w tworzeniu sterownika CSI w Kubernetes dla Yandex.Cloud
Z przyjemnością informujemy, że Flant rozszerza swój wkład w narzędzia Open Source dla Kubernetes wydając wersja alfa sterownika CSI (Interfejs przechowywania kontenerów) dla Yandex.Cloud.
Zanim jednak przejdziemy do szczegółów wdrożenia, odpowiedzmy sobie na pytanie, dlaczego jest to w ogóle potrzebne, skoro Yandex ma już usługę Usługa zarządzana dla Kubernetes.
Wprowadzenie
Dlaczego to?
W naszej firmie od samego początku wykorzystania Kubernetesa w produkcji (tj. już od kilku lat) rozwijamy własne narzędzie (deckhouse), które notabene planujemy wkrótce udostępnić również jako projekt Open Source . Za jego pomocą jednolicie konfigurujemy i konfigurujemy wszystkie nasze klastry, a obecnie jest ich już ponad 100, na szerokiej gamie konfiguracji sprzętowych i we wszystkich dostępnych usługach chmurowych.
Klastry korzystające z nadbudówki posiadają wszystkie komponenty niezbędne do działania: balansery, monitorowanie za pomocą wygodnych wykresów, metryk i alertów, uwierzytelnianie użytkowników za pośrednictwem zewnętrznych dostawców w celu uzyskania dostępu do wszystkich dashboardów i tak dalej. Nie ma sensu instalować tak „napompowanego” klastra w rozwiązaniu zarządzanym, ponieważ często jest to albo niemożliwe, albo będzie prowadzić do konieczności wyłączenia połowy komponentów.
NB: Takie jest nasze doświadczenie i jest ono dość specyficzne. W żadnym wypadku nie sugerujemy, że każdy powinien samodzielnie wdrażać klastry Kubernetes, zamiast korzystać z gotowych rozwiązań. Nawiasem mówiąc, nie mamy prawdziwego doświadczenia w obsłudze Kubernetesa od Yandex i nie będziemy oceniać tej usługi w tym artykule.
Obecnie wielu dużych dostawców usług w chmurze opracowało sterowniki umożliwiające używanie ich dysków w chmurze jako woluminów trwałych w Kubernetes. Jeśli dostawca nie posiada takiego sterownika, ale wszystkie niezbędne funkcje udostępniane są poprzez API, to nic nie stoi na przeszkodzie, aby samodzielnie zaimplementować sterownik. Tak właśnie stało się z Yandex.Cloud.
Przyjęliśmy jako podstawę rozwoju Sterownik CSI dla chmury DigitalOcean i kilka pomysłów z sterowniki do GCP, ponieważ interakcja z API tych chmur (Google i Yandex) ma wiele podobieństw. W szczególności API i GCPoraz Yandex zwrócić obiekt Operation do śledzenia statusu długotrwałych operacji (na przykład tworzenia nowego dysku). Aby współdziałać z interfejsem API Yandex.Cloud, użyj Zestaw SDK Yandex.Cloud Go.
Wynik wykonanej pracy opublikowane na GitHubie i może być przydatny dla tych, którzy z jakiegoś powodu korzystają z własnej instalacji Kubernetes na maszynach wirtualnych Yandex.Cloud (ale nie z gotowego klastra zarządzanego) i chcieliby korzystać (zamawiać) dyski poprzez CSI.
realizacja
Najważniejsze cechy
Obecnie sterownik obsługuje następujące funkcje:
Uporządkowanie dysków we wszystkich strefach klastra zgodnie z topologią węzłów w klastrze;
Usuwanie wcześniej zamówionych płyt;
Zmiana rozmiaru dysków offline (Yandex.Cloud nie wspieraj zwiększenie liczby dysków zamontowanych na maszynie wirtualnej). Informacje na temat modyfikacji sterownika, aby zmiana rozmiaru była jak najbardziej bezbolesna, można znaleźć poniżej.
W przyszłości planujemy wdrożyć obsługę tworzenia i usuwania migawek dysków.
Główna trudność i sposób jej pokonania
Brak możliwości zwiększania dysków w czasie rzeczywistym w Yandex.Cloud API to ograniczenie, które komplikuje operację zmiany rozmiaru dla PV (Persistent Volume): w tym przypadku konieczne jest zatrzymanie aplikacji korzystającej z dysku, co może powodować przestoje aplikacji.
Według Specyfikacje CSI, jeśli kontroler CSI zgłosi, że może zmieniać rozmiar dysków tylko „offline” (VolumeExpansion.OFFLINE), to proces zwiększania dysku powinien przebiegać następująco:
Jeśli wtyczka ma tylko VolumeExpansion.OFFLINE możliwości rozbudowy i tom są aktualnie publikowane lub dostępne w węźle ControllerExpandVolume NALEŻY wywołać TYLKO po:
Wtyczka posiada kontroler PUBLISH_UNPUBLISH_VOLUME zdolności i ControllerUnpublishVolume został pomyślnie wywołany.
ALBO
Wtyczka NIE posiada kontrolera PUBLISH_UNPUBLISH_VOLUME możliwości, wtyczka ma node STAGE_UNSTAGE_VOLUME możliwości i NodeUnstageVolume został pomyślnie zakończony.
ALBO
Wtyczka NIE posiada kontrolera PUBLISH_UNPUBLISH_VOLUME możliwości ani węzła STAGE_UNSTAGE_VOLUME możliwości i NodeUnpublishVolume zakończyło się pomyślnie.
Zasadniczo oznacza to, że musisz odłączyć dysk od maszyny wirtualnej przed jej rozszerzeniem.
Jednak niestety wdrożenie Specyfikacja CSI z przyczepami bocznymi nie spełnia tych wymagań:
W kontenerze z przyczepą boczną csi-attacher, który powinien odpowiadać za obecność wymaganej przerwy pomiędzy mocowaniami, ta funkcjonalność po prostu nie jest zaimplementowana w przypadku zmiany rozmiaru offline. Rozpoczęto dyskusję na ten temat tutaj.
Czym dokładnie jest kontener z wózkiem bocznym w tym kontekście? Sama wtyczka CSI nie wchodzi w interakcję z API Kubernetes, a jedynie odpowiada na wywołania gRPC wysyłane do niej przez kontenery sidecar. Najnowszy są rozwijane przez społeczność Kubernetes.
W naszym przypadku (wtyczka CSI) operacja powiększenia dysku wygląda następująco:
Próbujemy zwiększyć dysk w API, ale pojawia się błąd o niemożności wykonania operacji, ponieważ dysk jest zamontowany;
Identyfikator dysku przechowujemy na mapie, która zawiera dyski, dla których należy wykonać operację zwiększania. Poniżej dla zwięzłości będziemy nazywać tę mapę jako volumeResizeRequired;
Ręcznie usuń moduł korzystający z dysku. Kubernetes uruchomi go ponownie. Aby dysk nie miał czasu na zamontowanie (ControllerPublishVolume) przed zakończeniem operacji zwiększania przy próbie zamontowania sprawdzamy, czy dany dysk nadal jest na swoim miejscu volumeResizeRequired i zwróć błąd;
Sterownik CSI próbuje ponownie wykonać operację zmiany rozmiaru. Jeśli operacja się powiodła, wyjmij dysk z volumeResizeRequired;
Ponieważ Brak identyfikatora dysku volumeResizeRequired, ControllerPublishVolume przechodzi pomyślnie, dysk jest zamontowany, kapsuła uruchamia się.
Wszystko wygląda dość prosto, ale jak zawsze są pułapki. Powiększa dyski zewnętrzny-resizer, co w przypadku błędu podczas operacji korzysta z kolejki z wykładniczym wzrostem czasu oczekiwania do 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)},
)
}
Może to okresowo powodować wydłużenie operacji rozszerzania dysku o ponad 15 minut, a tym samym niedostępność odpowiedniego zasobnika.
Jedyną opcją, która w miarę łatwo i bezboleśnie pozwoliła nam skrócić potencjalne przestoje, było zastosowanie naszej wersji zewnętrznego-resizera z maksymalnym limitem czasu w 5 sekund:
Nie uznaliśmy za konieczne pilnego wszczynania dyskusji i łatania zewnętrznego narzędzia zmiany rozmiaru, ponieważ zmiana rozmiaru dysków w trybie offline to powrót do przeszłości, który wkrótce zniknie ze wszystkich dostawców usług w chmurze.
Jak zacząć z niego korzystać?
Sterownik jest obsługiwany na platformie Kubernetes w wersji 1.15 i wyższej. Aby kierowca mógł pracować muszą być spełnione następujące wymagania:
Flaga --allow-privileged ustawić na wartość true dla serwera API i kubelet;
Dołączony --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true dla serwera API i kubelet;
Propagacja wierzchowców (propagacja wierzchowców) musi być włączona w klastrze. Podczas korzystania z Dockera demon musi być skonfigurowany tak, aby zezwalał na wspólne montowanie.
Wszystkie niezbędne kroki do samej instalacji opisane w README. Instalacja polega na utworzeniu obiektów w Kubernetesie z manifestów.
Aby sterownik działał, potrzebne będą:
Określ identyfikator katalogu w manifeście (folder-id) Yandex.Cloud (zobacz dokumentację);
Do interakcji z API Yandex.Cloud sterownik CSI korzysta z konta usługi. W manifeście należy przekazać Sekret autoryzowane klucze z konta usługi. W dokumentacji opisane, jak założyć konto w serwisie i zdobyć klucze.
W sumie - spróbuji będziemy szczęśliwi, jeśli otrzymamy informację zwrotną i nowe problemyjeśli napotkasz jakiekolwiek problemy!
Dalsze wsparcie
W rezultacie pragniemy zaznaczyć, że wdrożyliśmy ten sterownik CSI nie z wielkiej chęci dobrej zabawy przy pisaniu aplikacji w Go, ale z powodu pilnej potrzeby wewnątrz firmy. Utrzymywanie własnej implementacji nie wydaje nam się praktyczne, więc jeśli Yandex wykaże zainteresowanie i zdecyduje się na dalsze wspieranie sterownika, chętnie przeniesiemy do niego repozytorium.
Ponadto Yandex prawdopodobnie posiada własną implementację sterownika CSI w zarządzanym przez siebie klastrze Kubernetes, który można udostępnić w formacie Open Source. Również tę opcję rozwoju postrzegamy jako korzystną – społeczność będzie mogła skorzystać ze sprawdzonego sterownika od usługodawcy, a nie od zewnętrznej firmy.