Urządzenie Helm i jego pułapki

Urządzenie Helm i jego pułapki
Koncepcja przewoźnika towarowego Typhon, Anton Swanepoel

Nazywam się Dmitry Sugrobov, jestem programistą w Leroy Merlin. W tym artykule opowiem do czego potrzebny jest Helm, jak ułatwia pracę z Kubernetesem, co zmieniło się w trzeciej wersji i jak go wykorzystać do aktualizacji aplikacji w środowisku produkcyjnym bez przestojów.

To streszczenie na podstawie wystąpienia na konferencji Konferencja @Kubernetes by Rozwiązania chmurowe Mail.ru – jeśli nie chcesz czytać, obejrzyj wideo.

Dlaczego używamy Kubernetesa w produkcji

Leroy Merlin jest liderem na rynku handlu detalicznego DIY w Rosji i Europie. Nasza firma ma ponad stu programistów, 33 000 pracowników wewnętrznych i ogromną liczbę osób odwiedzających hipermarkety i stronę internetową. Aby uszczęśliwić ich wszystkich, postanowiliśmy zastosować standardowe podejście branżowe. Twórz nowe aplikacje z wykorzystaniem architektury mikroserwisowej; używać pojemników do izolowania środowisk i zapewnienia właściwej dostawy; i użyj Kubernetes do orkiestracji. Cena korzystania z orkiestratorów szybko spada: na rynku rośnie liczba inżynierów biegłych w tej technologii, pojawiają się dostawcy oferujący Kubernetes jako usługę.

Wszystko, co robi Kubernetes, można oczywiście zrobić na inne sposoby, na przykład zakrywając Jenkinsa i docker-compose skryptami, ale po co komplikować życie, skoro jest gotowe i niezawodne rozwiązanie? Dlatego przyjechaliśmy na Kubernetes i już od roku używamy go w produkcji. Obecnie mamy dwadzieścia cztery klastry Kubernetes, z których najstarszy ma ponad rok i zawiera około dwustu podów.

Przekleństwo dużych plików YAML w Kubernetesie

Aby uruchomić mikroserwis w Kubernetesie utworzymy co najmniej pięć plików YAML: dla Deployment, Service, Ingress, ConfigMap, Secrets – i wyślemy je do klastra. Dla kolejnej aplikacji napiszemy ten sam pakiet ościeży, przy trzeciej napiszemy kolejną i tak dalej. Jeśli pomnożymy liczbę dokumentów przez liczbę środowisk, otrzymamy już setki plików, i to nie biorąc pod uwagę jeszcze środowisk dynamicznych.

Urządzenie Helm i jego pułapki
Adam Reese, główny opiekun Helma, przedstawił koncepcję „Cykl deweloperski w Kubernetesie", który wygląda tak:

  1. Kopiuj YAML - kopiuje plik YAML.
  2. Wklej YAML - wklej.
  3. Napraw wcięcia - napraw wcięcia.
  4. Powtórz - powtórz jeszcze raz.

Opcja działa, ale trzeba wielokrotnie kopiować pliki YAML. Aby zmienić ten cykl, wynaleziono Helm.

Co to jest Helm

Po pierwsze, Helm - menedżer pakietów, który pomaga znaleźć i zainstalować potrzebne programy. Aby zainstalować np. MongoDB, nie musisz wchodzić na oficjalną stronę i pobierać plików binarnych, wystarczy uruchomić komendę helm install stable/mongodb.

Po drugie, Helm - silnik szablonów, pomaga parametryzować pliki. Wróćmy do sytuacji z plikami YAML w Kubernetesie. Łatwiej jest napisać ten sam plik YAML, dodać do niego kilka symboli zastępczych, w które Helm podstawi wartości. Oznacza to, że zamiast dużego zestawu rusztowań pojawi się zestaw szablonów, w które we właściwym czasie zostaną podstawione wymagane wartości.

Po trzecie, Helm - mistrz wdrażania. Dzięki niemu możesz instalować, przywracać i aktualizować aplikacje. Zastanówmy się, jak to zrobić.

Urządzenie Helm i jego pułapki

Jak używać Helma do wdrażania własnych aplikacji

Zainstalujmy klienta Helm na Twoim komputerze, postępując zgodnie z oficjalnymi instrukcjami instrukcje. Następnie utworzymy zestaw plików YAML. Zamiast podawać konkretne wartości, pozostawimy symbole zastępcze, które Helm w przyszłości wypełni informacjami. Zbiór takich plików nazywany jest wykresem Helma. Można go wysłać do klienta konsoli Helm na trzy sposoby:

  • wskazać folder z szablonami;
  • spakuj archiwum do pliku .tar i wskaż go;
  • umieść szablon w zdalnym repozytorium i dodaj łącze do repozytorium w kliencie Helm.

Potrzebujesz także pliku z wartościami - wartości.yaml. Dane stamtąd zostaną wstawione do szablonu. Stwórzmy to i my.

Urządzenie Helm i jego pułapki
Druga wersja Helma posiada dodatkową aplikację serwerową - Tiller. Zawiesza się poza Kubernetesem i czeka na żądania od klienta Helm, a po wywołaniu podstawia wymagane wartości do szablonu i wysyła je do Kubernetesa.

Urządzenie Helm i jego pułapki
Helm 3 jest prostszy: zamiast przetwarzać szablony na serwerze, informacje są teraz przetwarzane całkowicie po stronie klienta Helm i wysyłane bezpośrednio do API Kubernetes. To uproszczenie poprawia bezpieczeństwo klastra i ułatwia schemat wdrożenia.

Jak to wszystko działa

Uruchom polecenie helm install. Wskażmy nazwę wydania aplikacji i podajmy ścieżkę do wartości.yaml. Na koniec wskażemy repozytorium, w którym znajduje się wykres oraz nazwę wykresu. W tym przykładzie są to odpowiednio „lmru” i „bestchart”.

helm install --name bestapp --values values.yaml lmru/bestchart

Polecenie może zostać wykonane tylko raz, zamiast tego zostanie wykonane ponownie install potrzebuję użyć upgrade. Dla uproszczenia zamiast dwóch poleceń można uruchomić polecenie upgrade z dodatkowym kluczem --install. Po pierwszym uruchomieniu Helm wyśle ​​polecenie zainstalowania wydania i zaktualizuje je w przyszłości.

helm upgrade --install bestapp --values values.yaml lmru/bestchart

Pułapki związane z wdrażaniem nowych wersji aplikacji za pomocą Helma

Na tym etapie historii gram z publicznością w „Kto chce zostać milionerem” i zastanawiamy się, jak nakłonić Helma do zaktualizowania wersji aplikacji. Obejrzyj wideo.

Kiedy uczyłem się, jak działa Helm, zaskoczyło mnie dziwne zachowanie podczas próby aktualizacji wersji uruchomionych aplikacji. Zaktualizowałem kod aplikacji, przesłałem nowy obraz do rejestru Dockera, wysłałem polecenie wdrożenia - i nic się nie stało. Poniżej znajduje się kilka nie do końca udanych sposobów aktualizacji aplikacji. Studiując każdy z nich bardziej szczegółowo, zaczynasz rozumieć wewnętrzną strukturę instrumentu i przyczyny tego nieoczywistego zachowania.

Metoda 1. Nie zmieniaj informacji od ostatniego uruchomienia

Jak to się mówi Oficjalna strona Helm: „Wykresy Kubernetes mogą być duże i złożone, dlatego Helm stara się niczego nie dotykać za bardzo”. Dlatego jeśli zaktualizujesz najnowszą wersję obrazu aplikacji w rejestrze dokera i uruchomisz polecenie helm upgrade, to nic się nie stanie. Helm pomyśli, że nic się nie zmieniło i nie ma potrzeby wysyłania polecenia do Kubernetesa w celu aktualizacji aplikacji.

Tutaj i poniżej najnowszy tag jest pokazany wyłącznie jako przykład. Jeśli określisz ten tag, Kubernetes będzie pobierał obraz z rejestru dokera za każdym razem, niezależnie od parametru imagePullPolicy. Stosowanie najnowszych produktów jest niepożądane i powoduje skutki uboczne.

Metoda 2. Zaktualizuj LABEL na obrazie

Jak napisano w tym samym dokumentacja, „Helm zaktualizuje aplikację tylko wtedy, gdy uległa ona zmianie od czasu ostatniej wersji”. Logiczną opcją wydaje się aktualizacja LABEL w samym obrazie okna dokowanego. Jednak Helm nie zagląda do obrazów aplikacji i nie ma pojęcia o jakichkolwiek zmianach w nich. Odpowiednio, podczas aktualizacji etykiet na obrazie Helm nie będzie o nich wiedział, a polecenie aktualizacji aplikacji nie zostanie wysłane do Kubernetesa.

Metoda 3: Użyj klucza --force

Urządzenie Helm i jego pułapki
Przejdźmy do instrukcji i poszukajmy wymaganego klucza. Klucz ma największy sens --force. Pomimo oczywistej nazwy zachowanie różni się od oczekiwanego. Zamiast wymuszać aktualizację aplikacji, jej prawdziwym celem jest przywrócenie wersji, która ma status FAILED. Jeśli nie używasz tego klawisza, musisz wykonywać polecenia sekwencyjnie helm delete && helm install --replace. Zamiast tego sugeruje się użycie klucza --force, co automatyzuje sekwencyjne wykonywanie tych poleceń. Więcej informacji w tym prośba o pociągnięcie. Aby poinformować Helm o konieczności aktualizacji wersji aplikacji, ten klucz niestety nie będzie działać.

Metoda 4. Zmień etykiety bezpośrednio w Kubernetesie

Urządzenie Helm i jego pułapki
Aktualizowanie etykiety bezpośrednio w klastrze za pomocą polecenia kubectl edit - kiepski pomysł. Działanie to doprowadzi do niespójności informacji pomiędzy uruchomioną aplikacją a tą, która została pierwotnie wysłana do wdrożenia. Zachowanie Helma podczas wdrażania różni się w tym przypadku od jego wersji: Helm 2 nie zrobi nic, a Helm 3 wdroży nową wersję aplikacji. Aby zrozumieć dlaczego, musisz zrozumieć, jak działa Helm.

Jak działa Helm?

Aby ustalić, czy aplikacja uległa zmianie od czasu jej ostatniej wersji, Helm może użyć:

  • uruchomienie aplikacji w Kubernetesie;
  • nowe wartości.yaml i aktualny wykres;
  • Wewnętrzne informacje o wydaniu Helma.

Dla ciekawszych: gdzie Helm przechowuje wewnętrzne informacje o wydaniach?Wykonując polecenie helm history, otrzymamy wszystkie informacje o wersjach zainstalowanych za pomocą Helma.

Urządzenie Helm i jego pułapki
Znajdują się tam również szczegółowe informacje o przesłanych szablonach i wartościach. Możemy o to poprosić:

Urządzenie Helm i jego pułapki
W drugiej wersji Helma informacja ta znajduje się w tej samej przestrzeni nazw, w której działa Tiller (domyślnie kube-system), w ConfigMap, oznaczona etykietą „OWNER=TILLER”:

Urządzenie Helm i jego pułapki
Kiedy pojawiła się trzecia wersja Helma, informacje zostały przeniesione do sekretów i do tej samej przestrzeni nazw, w której działała aplikacja. Dzięki temu możliwe stało się jednoczesne uruchamianie kilku aplikacji w różnych przestrzeniach nazw o tej samej nazwie wydania. W drugiej wersji był to poważny problem, gdy przestrzenie nazw są odizolowane, ale mogą na siebie wpływać.

Urządzenie Helm i jego pułapki

Drugi Helm, próbując zrozumieć, czy potrzebna jest aktualizacja, korzysta tylko z dwóch źródeł informacji: tego, co jest mu obecnie dostarczane, oraz wewnętrznych informacji o wydaniach, które znajdują się w ConfigMap.

Urządzenie Helm i jego pułapki
Trzeci Helm wykorzystuje trójstronną strategię scalania: oprócz tych informacji uwzględnia także aplikację działającą obecnie w Kubernetesie.

Urządzenie Helm i jego pułapki
Z tego powodu stara wersja Helma nic nie zrobi, ponieważ nie uwzględnia informacji o aplikacji w klastrze, ale Helm 3 odbierze zmiany i wyśle ​​nową aplikację do wdrożenia.

Metoda 5. Użyj przełącznika --recreate-pods

Z kluczem --recreate-pods za pomocą klucza możesz osiągnąć to, co pierwotnie planowałeś --force. Kontenery uruchomią się ponownie i zgodnie z polityką imagePullPolicy: Always dla najnowszego tagu (więcej na ten temat w przypisie powyżej), Kubernetes pobierze i uruchomi nową wersję obrazu. Nie zostanie to zrobione w najlepszy sposób: bez uwzględnienia StrategyType wdrożenia, nagle wyłączy wszystkie stare instancje aplikacji i zacznie uruchamiać nowe. Podczas ponownego uruchamiania system nie będzie działał, użytkownicy ucierpią.

W samym Kubernetesie podobny problem istniał też od dłuższego czasu. A teraz, 4 lata po otwarciu Kwestia, problem został rozwiązany i począwszy od wersji 1.15 Kubernetesa pojawia się możliwość ponownego uruchamiania podów.

Helm po prostu wyłącza wszystkie aplikacje i uruchamia w pobliżu nowe kontenery. Nie można tego zrobić na produkcji, aby nie spowodować przestoju aplikacji. Jest to potrzebne wyłącznie do celów programistycznych i można je wykonywać wyłącznie w środowiskach scenicznych.

Jak zaktualizować wersję aplikacji za pomocą Helma?

Zmienimy wartości wysłane do Helma. Zazwyczaj są to wartości, które podstawia się w miejsce znacznika image. W przypadku nowszych, które często wykorzystywane są w nieproduktywnych środowiskach, zmienną informacją jest adnotacja, która dla samego Kubernetesa jest bezużyteczna, a dla Helma będzie sygnałem o konieczności aktualizacji aplikacji. Opcje wypełniania wartości adnotacji:

  1. Losowa wartość używając standardowej funkcji - {{ randAlphaNum 6 }}.
    Jest zastrzeżenie: po każdym wdrożeniu z wykorzystaniem wykresu z taką zmienną wartość adnotacji będzie unikalna, a Helm będzie zakładał, że nastąpiły zmiany. Okazuje się, że zawsze zrestartujemy aplikację, nawet jeśli nie zmieniliśmy jej wersji. Nie jest to krytyczne, ponieważ nie będzie przestojów, ale nadal jest nieprzyjemne.
  2. Wklej aktualny Data i godzina - {{ .Release.Date }}.
    Wariant jest podobny do wartości losowej z trwale unikalną zmienną.
  3. Bardziej poprawnym sposobem jest użycie sumy kontrolne. To jest SHA obrazu lub SHA ostatniego zatwierdzenia w gicie - {{ .Values.sha }}.
    Należy je policzyć i wysłać do klienta Helm po stronie wywołującej, na przykład w Jenkins. Jeśli aplikacja uległa zmianie, suma kontrolna ulegnie zmianie. Dlatego Helm zaktualizuje aplikację tylko wtedy, gdy będzie to konieczne.

Podsumujmy nasze próby

  • Helm wprowadza zmiany w najmniej inwazyjny sposób, więc jakakolwiek zmiana na poziomie obrazu aplikacji w Docker Registry nie spowoduje aktualizacji: po wykonaniu polecenia nic się nie stanie.
  • klucz --force służy do przywracania problematycznych wersji i nie jest powiązany z wymuszonymi aktualizacjami.
  • klucz --recreate-pods na siłę zaktualizuje aplikacje, ale zrobi to w sposób wandalizm: gwałtownie wyłączy wszystkie kontenery. Użytkownicy ucierpią z tego powodu; nie powinieneś tego robić na produkcji.
  • Bezpośrednio wprowadź zmiany w klastrze Kubernetes za pomocą polecenia kubectl edit tego nie rób: złamiemy spójność, a zachowanie będzie się różnić w zależności od wersji Helma.
  • Wraz z wydaniem nowej wersji Helma pojawiło się wiele niuansów. Zagadnienia w repozytorium Helma opisane są jasnym językiem, pomogą zrozumieć szczegóły.
  • Dodanie edytowalnej adnotacji do wykresu sprawi, że będzie on bardziej elastyczny. Dzięki temu będziesz mógł poprawnie wdrożyć aplikację, bez przestojów.

Myśl o „pokoju na świecie”, która sprawdza się we wszystkich obszarach życia: przeczytaj instrukcję przed użyciem, a nie po. Tylko mając pełną informację będzie można zbudować niezawodne systemy i uszczęśliwić użytkowników.

Inne powiązane linki:

  1. Poznawać Ster 3
  2. Oficjalna strona Helma
  3. Repozytorium Helm w serwisie GitHub
  4. 25 Przydatnych narzędzi Kubernetes: wdrażanie i zarządzanie

Raport ten został po raz pierwszy zaprezentowany o godz Konferencja @Kubernetes przez rozwiązania chmurowe Mail.ru. Patrzeć wideo inne występy i subskrybuj ogłoszenia o wydarzeniach na Telegramie Wokół Kubernetesa w Grupie Mail.ru.

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

Dodaj komentarz