Nasze wnioski z roku migracji GitLab.com do Kubernetes

Notatka. przeł.: Adopcja Kubernetesa w GitLab jest uważana za jeden z dwóch głównych czynników przyczyniających się do rozwoju firmy. Jednak do niedawna infrastruktura serwisu internetowego GitLab.com była budowana na maszynach wirtualnych, a dopiero około rok temu rozpoczęła się jej migracja na K8s, która wciąż nie została zakończona. Mamy przyjemność zaprezentować tłumaczenie najnowszego artykułu inżyniera GitLab SRE o tym, jak to się dzieje i jakie wnioski wyciągają inżynierowie biorący udział w projekcie.

Nasze wnioski z roku migracji GitLab.com do Kubernetes

Od około roku nasz dział infrastruktury migruje wszystkie usługi działające na GitLab.com do Kubernetes. W tym czasie napotkaliśmy wyzwania związane nie tylko z przeniesieniem usług na Kubernetes, ale także z zarządzaniem wdrożeniem hybrydowym w trakcie przejścia. Cenne wnioski, jakie wyciągnęliśmy, zostaną omówione w tym artykule.

Od samego początku istnienia GitLab.com jego serwery działały w chmurze na maszynach wirtualnych. Te maszyny wirtualne są zarządzane przez Chef i instalowane przy użyciu naszego oficjalny pakiet dla Linuksa. Strategia wdrożenia w przypadku konieczności aktualizacji aplikacji polega po prostu na aktualizacji floty serwerów w skoordynowany, sekwencyjny sposób przy użyciu potoku CI. Ta metoda - choć powolna i trochę nudny - zapewnia, że ​​GitLab.com stosuje te same praktyki instalacji i konfiguracji, co użytkownicy offline (samodzielnie zarządzane) Instalacje GitLab wykorzystujące do tego nasze pakiety Linux.

Używamy tej metody, ponieważ niezwykle ważne jest doświadczenie wszystkich smutków i radości, jakich doświadczają zwykli członkowie społeczności podczas instalowania i konfigurowania swoich kopii GitLab. To podejście sprawdzało się przez jakiś czas, jednak gdy liczba projektów na GitLabie przekroczyła 10 milionów, zdaliśmy sobie sprawę, że nie spełnia ono już naszych potrzeb w zakresie skalowania i wdrażania.

Pierwsze kroki z Kubernetesem i natywnym dla chmury GitLabem

Projekt powstał w 2017 roku Wykresy GitLaba w celu przygotowania GitLaba do wdrożenia w chmurze i umożliwienia użytkownikom instalacji GitLaba na klastrach Kubernetes. Wiedzieliśmy wtedy, że przeniesienie GitLaba do Kubernetesa zwiększy skalowalność platformy SaaS, uprości wdrożenia i poprawi efektywność zasobów obliczeniowych. Jednocześnie wiele funkcji naszej aplikacji było zależnych od zamontowanych partycji NFS, co spowalniało przejście z maszyn wirtualnych.

Przejście na rozwiązania chmurowe i Kubernetes pozwoliło naszym inżynierom zaplanować stopniowe przejście, podczas którego porzuciliśmy niektóre zależności aplikacji od pamięci sieciowej, jednocześnie kontynuując rozwój nowych funkcji. Odkąd zaczęliśmy planować migrację latem 2019 roku, wiele z tych ograniczeń zostało usuniętych, a proces migracji GitLab.com do Kubernetes jest już na zaawansowanym etapie!

Funkcje GitLab.com w Kubernetes

W przypadku GitLab.com używamy jednego regionalnego klastra GKE, który obsługuje cały ruch aplikacji. Aby zminimalizować złożoność (i tak już trudnej) migracji, skupiamy się na usługach, które nie opierają się na lokalnej pamięci masowej ani NFS. GitLab.com korzysta głównie z monolitycznej bazy kodu Rails i kierujemy ruch w oparciu o charakterystykę obciążenia do różnych punktów końcowych, które są izolowane w ich własnych pulach węzłów.

W przypadku frontendu typy te dzielą się na żądania do sieci, API, Git SSH/HTTPS i Registry. W przypadku backendu zadania w kolejce dzielimy według różnych cech w zależności od predefiniowane granice zasobów, które pozwalają nam ustawić cele poziomu usług (SLO) dla różnych obciążeń.

Wszystkie te usługi GitLab.com są konfigurowane przy użyciu niezmodyfikowanego wykresu GitLab Helm. Konfiguracja odbywa się na podwykresach, które można selektywnie włączać w miarę stopniowej migracji usług do klastra. Mimo że zdecydowaliśmy się nie uwzględniać w migracji niektórych naszych usług stanowych, takich jak Redis, Postgres, GitLab Pages i Gitaly, wykorzystanie Kubernetesa pozwala nam radykalnie zmniejszyć liczbę maszyn wirtualnych, którymi obecnie zarządza Chef.

Widoczność konfiguracji Kubernetes i zarządzanie nią

Wszystkimi ustawieniami zarządza sam GitLab. W tym celu wykorzystywane są trzy projekty konfiguracyjne oparte na Terraform i Helm. Staramy się używać samego GitLaba, gdy tylko jest to możliwe, do uruchomienia GitLaba, ale do zadań operacyjnych mamy osobną instalację GitLaba. Jest to konieczne, aby mieć pewność, że podczas wdrażania i aktualizacji GitLab.com nie będziesz zależny od dostępności GitLab.com.

Chociaż nasze potoki dla klastra Kubernetes działają na osobnej instalacji GitLab, istnieją kopie lustrzane repozytoriów kodu, które są publicznie dostępne pod następującymi adresami:

  • k8s-workloads/gitlab-com — Framework konfiguracyjny GitLab.com dla wykresu GitLab Helm;
  • k8s-workloads/gitlab-helmfiles - Zawiera konfiguracje usług, które nie są bezpośrednio powiązane z aplikacją GitLab. Obejmują one konfiguracje rejestrowania i monitorowania klastrów, a także zintegrowane narzędzia, takie jak PlantUML;
  • Infrastruktura Gitlab-com — Konfiguracja Terraform dla Kubernetes i starszej infrastruktury maszyn wirtualnych. Tutaj konfigurujesz wszystkie zasoby niezbędne do uruchomienia klastra, w tym sam klaster, pule węzłów, konta usług i rezerwacje adresów IP.

Nasze wnioski z roku migracji GitLab.com do Kubernetes
Widok publiczny jest pokazywany po wprowadzeniu zmian. krótkie podsumowanie z linkiem do szczegółowej różnicy, którą SRE analizuje przed wprowadzeniem zmian w klastrze.

W przypadku SRE link prowadzi do szczegółowej różnicy w instalacji GitLab, która jest używana do produkcji i do której dostęp jest ograniczony. Umożliwia to pracownikom i społeczności bez dostępu do projektu operacyjnego (który jest dostępny tylko dla SRE) przeglądanie proponowanych zmian w konfiguracji. Łącząc publiczną instancję GitLab dla kodu z prywatną instancją dla potoków CI, utrzymujemy pojedynczy przepływ pracy, zapewniając jednocześnie niezależność od GitLab.com w zakresie aktualizacji konfiguracji.

Czego dowiedzieliśmy się podczas migracji

Podczas przeprowadzki zdobyliśmy doświadczenie, które wykorzystujemy przy nowych migracjach i wdrożeniach w Kubernetesie.

1. Zwiększone koszty wynikające z ruchu pomiędzy strefami dostępności

Nasze wnioski z roku migracji GitLab.com do Kubernetes
Dzienne statystyki ruchu wychodzącego (w bajtach dziennie) dla floty repozytoriów Git na GitLab.com

Google dzieli swoją sieć na regiony. Te z kolei podzielone są na strefy dostępności (AZ). Hosting Git wiąże się z dużą ilością danych, dlatego ważne jest dla nas kontrolowanie ruchu wychodzącego z sieci. W przypadku ruchu wewnętrznego wyjście jest bezpłatne tylko wtedy, gdy pozostaje w tej samej strefie dostępności. W chwili pisania tego tekstu udostępniamy około 100 TB danych w typowy dzień roboczy (i to dotyczy tylko repozytoriów Git). Usługi, które znajdowały się na tych samych maszynach wirtualnych w naszej starej topologii opartej na maszynach wirtualnych, działają teraz w różnych zasobnikach Kubernetes. Oznacza to, że część ruchu, który wcześniej był lokalny dla maszyny wirtualnej, może potencjalnie przemieszczać się poza strefy dostępności.

Regionalne klastry GKE umożliwiają łączenie wielu stref dostępności w celu zapewnienia nadmiarowości. Rozważamy taką możliwość podzielić regionalny klaster GKE na klastry jednostrefowe dla usług generujących duże natężenie ruchu. Zmniejszy to koszty wyjścia, zachowując redundancję na poziomie klastra.

2. Limity, żądania zasobów i skalowanie

Nasze wnioski z roku migracji GitLab.com do Kubernetes
Liczba replik przetwarzających ruch produkcyjny w witrynie rejestru.gitlab.com. Szczyt ruchu około 15:00 UTC.

Nasza historia migracji rozpoczęła się w sierpniu 2019 r., kiedy przeprowadziliśmy migrację naszej pierwszej usługi, GitLab Container Registry, do Kubernetes. Ta usługa o znaczeniu krytycznym i generująca duży ruch była dobrym wyborem w przypadku pierwszej migracji, ponieważ jest to aplikacja bezstanowa z niewielką liczbą zależności zewnętrznych. Pierwszym problemem, jaki napotkaliśmy, była duża liczba eksmitowanych podów z powodu braku pamięci w węzłach. Z tego powodu musieliśmy zmienić żądania i limity.

Odkryto, że w przypadku aplikacji, w której zużycie pamięci wzrasta z czasem, niskie wartości żądań (rezerwowanie pamięci dla każdego podu) w połączeniu z „hojnym” twardym limitem użycia doprowadziły do ​​nasycenia (nasycenie) węzłów i wysoki poziom eksmisji. Aby uporać się z tym problemem, tak było zdecydowano o zwiększeniu żądań i obniżeniu limitów. Odciążyło to węzły i zapewniło cykl życia podów, który nie wywierał zbyt dużego nacisku na węzeł. Teraz rozpoczynamy migrację od hojnych (i prawie identycznych) wartości żądań i limitów, dostosowując je w razie potrzeby.

3. Metryki i logi

Nasze wnioski z roku migracji GitLab.com do Kubernetes
Dział infrastruktury koncentruje się na opóźnieniach, wskaźnikach błędów i nasyceniu zainstalowanymi rozwiązaniami cele poziomu usług (SLO) powiązane z ogólna dostępność naszego systemu.

W ciągu ostatniego roku jednym z kluczowych wydarzeń w pionie infrastruktury były usprawnienia w zakresie monitorowania i współpracy z SLO. SLO pozwoliły nam wyznaczyć cele dla poszczególnych usług, które szczegółowo monitorowaliśmy podczas migracji. Jednak nawet przy tej lepszej obserwowalności nie zawsze można natychmiast wykryć problemy za pomocą metryk i alertów. Na przykład, koncentrując się na opóźnieniach i wskaźnikach błędów, nie uwzględniamy w pełni wszystkich przypadków użycia usługi podlegającej migracji.

Ten problem wykryto niemal natychmiast po migracji niektórych obciążeń do klastra. Stało się to szczególnie dotkliwe, gdy musieliśmy sprawdzić funkcje, dla których liczba żądań była niewielka, ale które miały bardzo specyficzne zależności konfiguracyjne. Jedną z kluczowych lekcji płynących z migracji była konieczność uwzględnienia podczas monitorowania nie tylko metryk, ale także logów i „długiego ogona” (to jest o taka ich dystrybucja na wykresie - ok. tłumacz.) błędy. Teraz dla każdej migracji dołączamy szczegółową listę zapytań do logów (zapytania dziennika) i zaplanuj jasne procedury wycofywania zmian, które w przypadku pojawienia się problemów można przenieść z jednej zmiany na następną.

Równoległa obsługa tych samych żądań w starej infrastrukturze maszyn wirtualnych i nowej infrastrukturze opartej na Kubernetes stanowiła wyjątkowe wyzwanie. W przeciwieństwie do migracji typu „lift-and-shift”. (szybki transfer aplikacji „tak jak jest” do nowej infrastruktury; więcej szczegółów można przeczytać np. tutaj - około. tłumacz.), równoległa praca na „starych” maszynach wirtualnych i Kubernetesie wymaga, aby narzędzia monitorujące były kompatybilne z obydwoma środowiskami i potrafiły łączyć metryki w jeden widok. Ważne jest, abyśmy korzystali z tych samych pulpitów nawigacyjnych i zapytań do dzienników, aby zapewnić spójną obserwowalność w okresie przejściowym.

4. Przełączenie ruchu do nowego klastra

W przypadku GitLab.com część serwerów jest przeznaczona dla etap kanaryjski. Canary Park obsługuje nasze projekty wewnętrzne i może również włączone przez użytkowników. Ale jest przeznaczony przede wszystkim do testowania zmian wprowadzonych w infrastrukturze i aplikacji. Pierwsza migrowana usługa rozpoczęła się od zaakceptowania ograniczonej ilości ruchu wewnętrznego i nadal używamy tej metody, aby upewnić się, że poziomy docelowego poziomu usług zostały spełnione przed wysłaniem całego ruchu do klastra.

W przypadku migracji oznacza to, że najpierw żądania do projektów wewnętrznych wysyłane są do Kubernetesa, a następnie stopniowo przekierowujemy resztę ruchu do klastra zmieniając wagę dla backendu poprzez HAProxy. Podczas migracji z VM do Kubernetes stało się jasne, że bardzo korzystne jest posiadanie łatwego sposobu na przekierowanie ruchu pomiędzy starą i nową infrastrukturą, a co za tym idzie, utrzymanie starej infrastruktury w gotowości do wycofania w ciągu pierwszych kilku dni po migracji.

5. Pojemność rezerwowa zasobników i ich wykorzystanie

Niemal natychmiast zidentyfikowano następujący problem: pody dla usługi Rejestru uruchamiały się szybko, ale uruchamianie podów dla Sidekiq trwało aż dwie minuty. Długi czas uruchamiania zasobników Sidekiq stał się problemem, gdy rozpoczęliśmy migrację obciążeń do Kubernetes dla pracowników, którzy musieli szybko przetwarzać zadania i szybko je skalować.

W tym przypadku lekcja była taka, że ​​choć poziome autoskalery podów (HPA) Kubernetesa dobrze radzą sobie ze wzrostem ruchu, ważne jest, aby wziąć pod uwagę charakterystykę obciążeń i przydzielić wolną moc obliczeniową do podów (zwłaszcza gdy popyt jest nierównomiernie rozłożony). W naszym przypadku nastąpił nagły wzrost liczby zadań, co doprowadziło do szybkiego skalowania, co doprowadziło do nasycenia zasobów procesora, zanim zdążyliśmy skalować pulę węzłów.

Zawsze istnieje pokusa, aby wycisnąć jak najwięcej z klastra, jednak po początkowych problemach z wydajnością zaczynamy teraz od hojnego budżetu poda i później go zmniejszamy, uważnie obserwując SLO. Uruchamianie podów dla usługi Sidekiq znacznie przyspieszyło i obecnie trwa średnio około 40 sekund. Od skrócenia czasu uruchamiania kapsuł zwyciężył zarówno GitLab.com, jak i nasi użytkownicy samodzielnie zarządzanych instalacji pracujących z oficjalnym wykresem GitLab Helm.

wniosek

Po migracji każdej usługi cieszyliśmy się korzyściami płynącymi z wykorzystania Kubernetes w środowisku produkcyjnym: szybsze i bezpieczniejsze wdrażanie aplikacji, skalowanie i wydajniejsza alokacja zasobów. Co więcej, zalety migracji wykraczają poza usługę GitLab.com. Każde ulepszenie oficjalnego wykresu Helm przynosi korzyści jego użytkownikom.

Mam nadzieję, że podobała Wam się historia naszych przygód migracyjnych na Kubernetesie. Kontynuujemy migrację wszystkich nowych usług do klastra. Dodatkowe informacje można znaleźć w następujących publikacjach:

PS od tłumacza

Przeczytaj także na naszym blogu:

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

Dodaj komentarz