Wzorce przechowywania danych w Kubernetesie

Wzorce przechowywania danych w Kubernetesie
Hej Habra!

Przypominamy, że wydaliśmy kolejny niezwykle ciekawy i przydatny книга o wzorcach Kubernetesa. Wszystko zaczęło się od „Wzory„Brendan Burns, a swoją drogą mamy pracę w tym segmencie czyraki. Już dziś zapraszamy do lektury artykułu z bloga MinIO, który w skrócie przedstawia trendy i specyfikę wzorców przechowywania danych w Kubernetesie.

Kubernetes zasadniczo zmienił tradycyjne wzorce tworzenia i wdrażania aplikacji. Teraz zespół może opracować, przetestować i wdrożyć aplikację w ciągu kilku dni — w wielu środowiskach, a wszystko to w klastrach Kubernetes. Taka praca z technologiami poprzednich generacji trwała zwykle tygodnie, jeśli nie miesiące.

To przyspieszenie jest możliwe dzięki abstrakcji zapewnianej przez Kubernetes - to znaczy, ponieważ sam Kubernetes wchodzi w interakcję ze szczegółami niskiego poziomu maszyn fizycznych lub wirtualnych, umożliwiając użytkownikom zadeklarowanie żądanego procesora, żądanej ilości pamięci i liczby kontenerów przypadkach, wśród innych parametrów. Dzięki ogromnej społeczności wspierającej Kubernetes i jego ciągłemu rozwojowi, Kubernetes jest z dużą przewagą liderem wśród wszystkich platform orkiestracji kontenerów.

Wraz ze wzrostem wykorzystania Kubernetesa rośnie zamieszanie dotyczące wzorców jego przechowywania..

Ponieważ wszyscy rywalizują o kawałek tortu Kubernetesa (czyli przechowywanie danych), jeśli chodzi o przechowywanie danych, sygnał tonie w dużym szumie.
Kubernetes ucieleśnia nowoczesny model tworzenia, wdrażania i zarządzania aplikacjami. Ten nowoczesny model oddziela przechowywanie danych od obliczeń. Aby w pełni zrozumieć oderwanie w kontekście Kubernetesa, trzeba także zrozumieć, czym są aplikacje stanowe i bezstanowe oraz jak wpisuje się w to przechowywanie danych. W tym miejscu podejście API REST stosowane przez S3 ma wyraźną przewagę nad podejściem POSIX/CSI w innych rozwiązaniach.

W tym artykule omówimy wzorce przechowywania danych w Kubernetesie, a konkretnie poruszymy debatę pomiędzy aplikacjami stanowymi i bezstanowymi, aby lepiej zrozumieć, jaka jest między nimi różnica i dlaczego jest to ważne. W pozostałej części tekstu przyjrzymy się aplikacjom i wzorcom przechowywania danych w świetle najlepszych praktyk pracy z kontenerami i Kubernetesem.

Kontenery bezstanowe

Kontenery są z natury lekkie i efemeryczne. Można je łatwo zatrzymać, usunąć lub wdrożyć w innym węźle – a wszystko to w ciągu kilku sekund. W systemie orkiestracji dużych kontenerów takie operacje zdarzają się cały czas, a użytkownicy nawet nie zauważają takich zmian. Jednak przenoszenie jest możliwe tylko wtedy, gdy kontener nie ma żadnych zależności od węzła, na którym się znajduje. Mówi się, że takie pojemniki działają bezpaństwowiec.

Kontenery stanowe

Jeśli kontener przechowuje dane na urządzeniach podłączonych lokalnie (lub na urządzeniu blokowym), to w przypadku awarii magazyn danych, na którym się znajduje, będzie musiał zostać przeniesiony do nowego węzła wraz z samym kontenerem. Jest to o tyle istotne, że w przeciwnym razie aplikacja działająca w kontenerze nie będzie mogła poprawnie działać, gdyż potrzebuje dostępu do danych przechowywanych na nośnikach lokalnych. Mówi się, że takie pojemniki działają stanowy.

Z czysto technicznego punktu widzenia kontenery stanowe można przenosić także do innych węzłów. Zwykle osiąga się to za pomocą rozproszonych systemów plików lub blokowej pamięci sieciowej podłączonej do wszystkich węzłów, na których działają kontenery. W ten sposób kontenery uzyskują dostęp do woluminów w celu trwałego przechowywania danych, a informacje są przechowywane na dyskach rozmieszczonych w całej sieci. Nazwę tę metodę „stanowe podejście kontenerowe”, i w dalszej części artykułu będę to tak nazywał, dla zachowania jednolitości.

Wzorce przechowywania danych w Kubernetesie

W typowym podejściu opartym na kontenerze stanowym wszystkie moduły aplikacji są dołączone do jednego rozproszonego systemu plików — rodzaju współdzielonej pamięci masowej, w której znajdują się wszystkie dane aplikacji. Chociaż możliwe są pewne różnice, jest to podejście na wysokim poziomie.

Przyjrzyjmy się teraz, dlaczego podejście oparte na kontenerach stanowych jest antywzorcem w świecie skoncentrowanym na chmurze.

Projektowanie aplikacji natywnych w chmurze

Tradycyjnie aplikacje wykorzystywały bazy danych do strukturalnego przechowywania informacji oraz dyski lokalne lub rozproszone systemy plików, do których zrzucane były wszystkie dane nieustrukturyzowane lub nawet częściowo ustrukturyzowane. Wraz ze wzrostem ilości nieustrukturyzowanych danych programiści zdali sobie sprawę, że POSIX jest zbyt rozmowny, powoduje znaczne obciążenie i ostatecznie utrudnia wydajność aplikacji przy przechodzeniu na naprawdę duże skale.

Przyczyniło się to głównie do powstania nowego standardu przechowywania danych, czyli przechowywania danych w chmurze, działającego przede wszystkim w oparciu o REST API i uwalniającego aplikację od uciążliwej konserwacji lokalnego magazynu danych. W tym przypadku aplikacja faktycznie przechodzi w tryb bezstanowy (ponieważ stan znajduje się w magazynie zdalnym). Nowoczesne aplikacje budowane są od podstaw z myślą o tym czynniku. Z reguły każda nowoczesna aplikacja przetwarzająca tego czy innego rodzaju dane (logi, metadane, obiekty blob itp.) jest zbudowana zgodnie z paradygmatem zorientowanym na chmurę, gdzie stan jest przenoszony do systemu oprogramowania specjalnie dedykowanego do jego przechowywania.

Podejście oparte na kontenerach stanowych wymusza powrót całego paradygmatu dokładnie tam, gdzie się zaczął!

Wykorzystując interfejsy POSIX do przechowywania danych, aplikacje działają tak, jakby były stanowe, przez co odchodzą od najważniejszych założeń projektowania chmurocentrycznego, czyli możliwości różnicowania wielkości wątków roboczych aplikacji w zależności od przychodzących input.load, przejdź do nowego węzła, gdy tylko bieżący węzeł ulegnie awarii i tak dalej.

Przyglądając się bliżej tej sytuacji, zauważamy, że wybierając magazyn danych, raz po raz stajemy przed dylematem POSIX vs. REST API, ALE z dodatkowym pogorszeniem problemów POSIX ze względu na rozproszony charakter środowisk Kubernetes. W szczególności,

  • POSIX jest rozmowny: Semantyka POSIX wymaga, aby każda operacja była powiązana z metadanymi i deskryptorami plików, które pomagają utrzymać stan operacji. Wiąże się to ze znacznymi kosztami, które nie mają realnej wartości. Interfejsy API obiektowej pamięci masowej, w szczególności API S3, pozbywają się tych wymagań, pozwalając aplikacji na uruchomienie, a następnie „zapomnienie” o wywołaniu. Odpowiedź systemu pamięci masowej wskazuje, czy akcja zakończyła się pomyślnie, czy nie. Jeśli się nie powiedzie, aplikacja może spróbować ponownie.
  • Ograniczenia sieciowe: W systemie rozproszonym sugeruje się, że wiele aplikacji może próbować zapisać dane na tym samym podłączonym nośniku. Dlatego nie tylko aplikacje będą ze sobą konkurować o przepustowość przesyłania danych (w celu wysyłania danych na nośnik), ale sam system pamięci masowej będzie konkurował o tę przepustowość, przesyłając dane przez dyski fizyczne. Ze względu na gadatliwość POSIX liczba połączeń sieciowych wzrasta kilkakrotnie. Z drugiej strony API S3 zapewnia wyraźne rozróżnienie pomiędzy wywołaniami sieciowymi pomiędzy tymi, które pochodzą od klienta do serwera, a tymi, które występują wewnątrz serwera.
  • bezpieczeństwo: Model zabezpieczeń POSIX został zaprojektowany z myślą o aktywnym udziale człowieka: administratorzy konfigurują określone poziomy dostępu dla każdego użytkownika lub grupy. Ten paradygmat jest trudny do dostosowania do świata skoncentrowanego na chmurze. Nowoczesne aplikacje opierają się na modelach bezpieczeństwa opartych na API, gdzie prawa dostępu definiowane są jako zbiór polityk, przydzielane są konta usług, tymczasowe dane uwierzytelniające itp.
  • Zarządzalność: Kontenery stanowe wiążą się z pewnymi kosztami zarządzania. Mówimy o synchronizacji równoległego dostępu do danych, zapewnieniu spójności danych, to wszystko wymaga dokładnego przemyślenia, jakie wzorce dostępu do danych zastosować. Należy zainstalować, monitorować i konfigurować dodatkowe oprogramowanie, nie wspominając o dodatkowym wysiłku programistycznym.

Interfejs przechowywania danych kontenera

Chociaż interfejs Container Storage Interface (CSI) bardzo pomógł w rozprzestrzenianiu się warstwy woluminów Kubernetes, częściowo zlecając ją zewnętrznym dostawcom pamięci masowej, w sposób niezamierzony przyczynił się również do przekonania, że ​​podejście oparte na kontenerach stanowych jest zalecaną metodą przechowywanie danych w Kubernetesie.

CSI został opracowany jako standard w celu zapewnienia dowolnych systemów przechowywania bloków i plików dla starszych aplikacji działających na platformie Kubernetes. Jak pokazano w tym artykule, jedyną sytuacją, w której podejście oparte na kontenerze stanowym (i CSI w jego obecnej formie) ma sens, jest sytuacja, gdy sama aplikacja jest starszym systemem, w którym nie jest możliwe dodanie obsługi API obiektowego przechowywania danych .

Ważne jest, aby zrozumieć, że korzystając z CSI w jego obecnej formie, czyli montując woluminy podczas pracy z nowoczesnymi aplikacjami, napotkamy w przybliżeniu te same problemy, które pojawiły się w systemach, w których przechowywanie danych jest zorganizowane w stylu POSIX.

Lepsze podejście

W tym przypadku ważne jest, aby zrozumieć, że większość aplikacji nie jest z natury zaprojektowana specjalnie do pracy stanowej lub bezstanowej. To zachowanie zależy od ogólnej architektury systemu i konkretnych wyborów projektowych. Porozmawiajmy trochę o aplikacjach stanowych.

Zasadniczo wszystkie dane aplikacji można podzielić na kilka ogólnych typów:

  • Dane dziennika
  • Dane znacznika czasu
  • Data transakcji
  • Metadane
  • Obrazy kontenerów
  • Dane typu Blob (duży obiekt binarny).

Wszystkie te typy danych są bardzo dobrze obsługiwane na nowoczesnych platformach pamięci masowej, a istnieje kilka natywnych platform chmurowych dostosowanych do dostarczania danych w każdym z tych konkretnych formatów. Na przykład dane i metadane transakcji mogą znajdować się w nowoczesnej bazie danych natywnej w chmurze, takiej jak CockroachDB, YugaByte itp. Obrazy kontenerów lub dane obiektów BLOB można przechowywać w rejestrze platformy dokowanej opartym na MinIO. Dane znacznika czasu można przechowywać w bazie danych szeregów czasowych, takiej jak InfluxDB itp. Nie będziemy tutaj szczegółowo omawiać każdego typu danych i jego zastosowań, ale ogólna koncepcja jest taka, aby unikać trwałego przechowywania danych, które opiera się na montowaniu na dysku lokalnym.

Wzorce przechowywania danych w Kubernetesie

Ponadto często skuteczne jest zapewnienie tymczasowej warstwy buforowania, która służy jako tymczasowy magazyn plików dla aplikacji, ale aplikacje nie powinny polegać na tej warstwie jako źródle prawdy.

Stanowe przechowywanie aplikacji

Chociaż w większości przypadków przydatne jest utrzymywanie aplikacji w stanie bezstanowym, aplikacje przeznaczone do przechowywania danych — takie jak bazy danych, składnice obiektów, składnice klucz-wartość — muszą być stanowe. Przyjrzyjmy się, dlaczego te aplikacje są wdrażane na platformie Kubernetes. Weźmy jako przykład MinIO, ale podobne zasady dotyczą każdego innego dużego systemu pamięci masowej natywnego w chmurze.

Aplikacje natywne w chmurze zostały zaprojektowane tak, aby w pełni wykorzystywać elastyczność właściwą kontenerom. Oznacza to, że nie przyjmują żadnych założeń dotyczących środowiska, w którym zostaną wdrożone. Na przykład MinIO wykorzystuje wewnętrzny mechanizm kodowania kasującego, aby zapewnić systemowi wystarczającą odporność, aby mógł działać nawet w przypadku awarii połowy dysków. MinIO zarządza również integralnością i bezpieczeństwem danych, korzystając z opatentowanego hashowania i szyfrowania po stronie serwera.

W przypadku takich zastosowań skoncentrowanych na chmurze lokalne woluminy trwałe (PV) są najwygodniejsze jako magazyn kopii zapasowych. Lokalna fotowoltaika zapewnia możliwość przechowywania surowych danych, podczas gdy aplikacje działające na tych fotowoltaikach niezależnie zbierają informacje w celu skalowania danych i zarządzania rosnącym zapotrzebowaniem na dane.

Podejście to jest znacznie prostsze i znacznie bardziej skalowalne niż fotowoltaiki oparte na CSI, które wprowadzają do systemu własne warstwy zarządzania danymi i redundancję; chodzi o to, że te warstwy zwykle powodują konflikt z aplikacjami zaprojektowanymi jako stanowe.

Pewny ruch w kierunku oddzielenia danych od obliczeń

W tym artykule mówiliśmy o tym, jak aplikacje są przeorientowane tak, aby działały bez zapisywania stanu, czyli innymi słowy, przechowywanie danych jest oddzielone od przetwarzania. Podsumowując, spójrzmy na kilka prawdziwych przykładów tego trendu.

Iskra, wiodąca platforma do analizy danych, tradycyjnie ma charakter stanowy i jest wdrażana w systemie HDFS. Jednak w miarę jak Spark wkracza w świat skoncentrowany na chmurze, platforma jest coraz częściej używana w trybie bezstanowym przy użyciu `s3a`. Spark używa protokołu s3a do przesyłania stanu do innych systemów, podczas gdy same kontenery Spark działają całkowicie bezstanowo. W szczególności inni główni gracze korporacyjni w dziedzinie analityki dużych zbiorów danych: Vertica, Teradane, Zielona śliwka Przechodzą też do pracy z rozdzieleniem przechowywania danych i obliczeń na nich.

Podobne wzorce można zobaczyć także na innych dużych platformach analitycznych m.in. Presto, Tensorflow to R, Jupyter. Przenosząc stan do zdalnych systemów przechowywania w chmurze, zarządzanie aplikacją i jej skalowanie staje się znacznie łatwiejsze. Ponadto ułatwia przenoszenie aplikacji do różnych środowisk.

Źródło: www.habr.com

Dodaj komentarz