Most południowy w Czelabińsku i Bitrix w Kubernetes
W Czelabińsku odbywają się spotkania administratorów systemu Sysadminka, na ostatnim zdałem relację na temat naszego rozwiązania do uruchamiania aplikacji na 1C-Bitrix w Kubernetesie.
Bitrix, Kubernetes, Ceph – świetna mieszanka?
Opowiem Ci, jak z tego wszystkiego stworzyliśmy działające rozwiązanie.
Chodźmy!
Spotkanie odbyło się 18 kwietnia w Czelabińsku. O naszych spotkaniach możecie przeczytać na: Timepad i spójrz na Youtube.
Jeśli chcesz przyjść do nas z reportażem lub jako słuchacz - zapraszamy, napisz [email chroniony] oraz na Telegramie t.me/vadimisakanov.
Rozwiązanie „Bitrix w Kubernetesie, wersja Southbridge 1.0”
O naszym rozwiązaniu będę opowiadać w formacie „dla manekinów w Kubernetesie”, tak jak to miało miejsce na spotkaniu. Zakładam jednak, że znasz słowa Bitrix, Docker, Kubernetes, Ceph przynajmniej na poziomie artykułów w Wikipedii.
Co jest gotowe w Bitrix w Kubernetes?
W całym Internecie jest bardzo mało informacji na temat działania aplikacji Bitrix w Kubernetesie.
Znalazłem tylko takie materiały:
Raport Aleksandra Serbula, 1C-Bitrix i Antona Tuzlukowa z Qsoft:
Uprzedzam, że nie sprawdzaliśmy jakości rozwiązań z linków powyżej :)
Nawiasem mówiąc, przygotowując nasze rozwiązanie, rozmawiałem z Alexandrem Serbulem, wtedy jego raport jeszcze się nie pojawił, więc na moich slajdach jest pozycja „Bitrix nie korzysta z Kubernetesa”.
Czy to wystarczy, aby stworzyć kompletne rozwiązanie dla Bitrix w Kubernetesie?
NIE. Istnieje duża liczba problemów, które należy rozwiązać.
Jakie są problemy z Bitrixem w Kubernetesie?
Po pierwsze, gotowe obrazy z Dockerhuba nie nadają się do Kubernetesa
Jeśli chcemy zbudować architekturę mikrousług (a w Kubernetesie zwykle to robimy), musimy podzielić naszą aplikację Kubernetes na kontenery i sprawić, aby każdy kontener wykonywał jedną małą funkcję (i robił to dobrze). Dlaczego tylko jeden? Krótko mówiąc, im prostsze, tym bardziej niezawodne.
Aby być bardziej szczegółowym, obejrzyj ten artykuł i film: https://habr.com/ru/company/southbridge/blog/426637/
Obrazy Dockera w Dockerhub są zbudowane głównie na zasadzie „wszystko w jednym”, więc nadal musieliśmy stworzyć własny rower, a nawet stworzyć obrazy od podstaw.
Po drugie – edycja kodu strony odbywa się z poziomu panelu administracyjnego
Utworzyliśmy nową sekcję na stronie - zaktualizowano kod (dodano katalog z nazwą nowej sekcji).
Jeśli zmieniłeś właściwości komponentu z panelu administracyjnego, kod się zmienił.
Kubernetes „domyślnie” nie może z tym pracować; kontenery muszą być bezstanowe.
Powód: każdy kontener (pod) w klastrze przetwarza tylko część ruchu. Jeśli zmienisz kod tylko w jednym kontenerze (podu), to kod będzie inny w różnych podach, strona będzie działać inaczej, a różnym użytkownikom będą się wyświetlać różne wersje witryny. Nie możesz tak żyć.
Po trzecie - musisz rozwiązać problem z wdrożeniem
Jeśli mamy monolit i jeden „klasyczny” serwer, wszystko jest dość proste: wdrażamy nową bazę kodu, migrujemy bazę danych, przełączamy ruch na nową wersję kodu. Przełączanie następuje natychmiast.
Jeśli mamy witrynę w Kubernetesie, pociętą na mikroserwisy, kontenerów z kodem jest mnóstwo – och. Trzeba zebrać kontenery z nową wersją kodu, wdrożyć je zamiast starych, poprawnie przeprowadzić migrację bazy danych i najlepiej zrobić to niezauważenie przez odwiedzających. Na szczęście pomaga nam w tym Kubernetes, obsługujący całą masę różnego rodzaju wdrożeń.
Po czwarte - musisz rozwiązać problem przechowywania statyki
Jeśli Twoja witryna ma „tylko” 10 gigabajtów i wdrożysz ją w całości w kontenerach, otrzymasz 10 gigabajtowych kontenerów, których wdrożenie zajmie całą wieczność.
Musisz przechowywać „najcięższe” części witryny poza kontenerami i pojawia się pytanie, jak to zrobić poprawnie
Czego brakuje w naszym rozwiązaniu?
Cały kod Bitrix nie jest podzielony na mikrofunkcje/mikrousługi (aby rejestracja była osobna, moduł sklepu internetowego był osobny itp.). W każdym kontenerze przechowujemy całą bazę kodu.
Nie przechowujemy również bazy danych w Kubernetesie (nadal wdrażałem rozwiązania z bazą danych w Kubernetesie dla środowisk deweloperskich, ale już nie produkcyjnych).
Administratorzy witryny nadal będą zauważali, że witryna działa na platformie Kubernetes. Funkcja „kontrola systemu” nie działa poprawnie, aby edytować kod strony z poziomu panelu administracyjnego, należy najpierw kliknąć przycisk „Chcę edytować kod”.
Zidentyfikowano problemy, określono potrzebę wdrożenia mikrousług, cel jest jasny - uzyskać działający system do uruchamiania aplikacji na Bitrixie w Kubernetesie, zachowując zarówno możliwości Bitrixa, jak i zalety Kubernetesa. Zacznijmy wdrażanie.
Architektura
Istnieje wiele „działających” podów z serwerem internetowym (pracownikami).
Jeden pod zadaniami cron (wymagany jest tylko jeden).
Jedna aktualizacja umożliwiająca edycję kodu strony z panelu administracyjnego (również wymagana jest tylko jedna).
Rozwiązujemy pytania:
Gdzie przechowywać sesje?
Gdzie przechowywać pamięć podręczną?
Gdzie przechowywać statykę, a nie umieszczać gigabajtów statyki w kilku kontenerach?
Jak będzie działać baza danych?
Obraz Dockera
Zaczynamy od zbudowania obrazu Dockera.
Idealną opcją jest to, że mamy jeden uniwersalny image, na jego podstawie otrzymujemy workery pody, pody z Crontaskami oraz upgrade pody.
Obejmuje nginx, Apache/php-fpm (można wybrać podczas kompilacji), msmtp do wysyłania poczty i cron.
Podczas asemblowania obrazu cała baza kodu witryny jest kopiowana do katalogu /app (z wyjątkiem tych części, które przeniesiemy do osobnego współdzielonego magazynu).
Mikrousługi, usługi
kapsuły robocze:
Kontener z nginx + kontener Apache/php-fpm + msmtp
Nie udało się przenieść msmtp do osobnego mikroserwisu, Bitrix zaczyna się oburzać, że nie może bezpośrednio wysyłać poczty
Każdy kontener ma kompletną bazę kodu.
Zakaz zmiany kodu w kontenerach.
cron pod:
kontener z Apache, php, cron
zawiera pełną bazę kodu
zakaz zmiany kodu w kontenerach
uaktualnij pod:
kontener nginx + kontener Apache/php-fpm + msmtp
Nie ma zakazu zmiany kodu w kontenerach
przechowywanie sesji
Pamięć podręczna Bitrix
Kolejna ważna rzecz: hasła do łączenia się ze wszystkim, od bazy danych po pocztę, przechowujemy w tajemnicach Kubernetes. Dostajemy bonus: hasła są widoczne tylko dla tych, którym dajemy dostęp do sekretów, a nie dla każdego, kto ma dostęp do bazy kodów projektu.
Przechowywanie statyki
Możesz użyć wszystkiego: ceph, nfs (ale nie zalecamy nfs do produkcji), pamięci sieciowej od dostawców usług w chmurze itp.
Magazyn będzie musiał być podłączony w kontenerach do katalogu /upload/ witryny i innych katalogów z zawartością statyczną.
Baza danych
Dla uproszczenia zalecamy przeniesienie bazy danych poza Kubernetes. Baza w Kubernetesie to osobne złożone zadanie, które sprawi, że schemat będzie o rząd wielkości bardziej skomplikowany.
Przechowywanie sesji
Używamy memcached :)
Dobrze radzi sobie z przechowywaniem sesji, jest klastrowany i jest obsługiwany „natywnie” jako session.save_path w php. System taki był wielokrotnie testowany w klasycznej architekturze monolitycznej, kiedy budowaliśmy klastry z dużą liczbą serwerów WWW. Do wdrożenia używamy Helm.
$ helm install stable/memcached --name session
php.ini - tutaj obraz zawiera ustawienia przechowywania sesji w memcached
Użyliśmy zmiennych środowiskowych do przekazania danych o hostach za pomocą memcached https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/.
Pozwala to na użycie tego samego kodu w środowiskach deweloperskich, scenicznych, testowych, prod (nazwy hostów memcachowanych w nich będą różne, dlatego musimy przekazać unikalną nazwę hosta dla sesji do każdego środowiska).
Pamięć podręczna Bitrix
Potrzebujemy odpornej na awarie pamięci masowej, do której wszystkie moduły będą mogły zapisywać i odczytywać dane.
Używamy również memcached.
To rozwiązanie jest zalecane przez sam Bitrix.
$ helm install stable/memcached --name cache
bitrix/.settings_extra.php - tutaj w Bitrix określa się, gdzie przechowywana jest pamięć podręczna
Używamy również zmiennych środowiskowych.
Krontaski
Istnieją różne podejścia do uruchamiania Crontasks w Kubernetes.
oddzielne wdrożenie z modułem do uruchamiania Crontasks
cronjob do wykonywania crontasks (jeśli jest to aplikacja internetowa - za pomocą wget https://$host$cronjobnamelub kubectl exec w jednym z zasobników roboczych itp.)
itd.
Można się spierać o najbardziej poprawny, ale w tym przypadku wybraliśmy opcję „oddzielne wdrożenie z podami dla Crontasks”
Jak to jest zrobione:
dodaj zadania cron poprzez ConfigMap lub poprzez plik config/addcron
w jednym przypadku uruchamiamy kontener identyczny z workerem + umożliwiamy w nim wykonywanie zadań koronnych
zastosowano tę samą bazę kodową, dzięki ujednoliceniu montaż kontenera jest prosty
Co dobrego dostajemy:
mamy działające Crontaski w środowisku identycznym ze środowiskiem deweloperskim (docker)
Crontaski nie muszą być „przepisywane” dla Kubernetesa, działają w tej samej formie i w tej samej bazie kodu co wcześniej
Zadania cron mogą dodawać wszyscy członkowie zespołu z uprawnieniami do zatwierdzania gałęzi produkcyjnej, a nie tylko administratorzy
Southbridge K8SWdrażaj moduł i edytuj kod z panelu administracyjnego
Mówiliśmy o aktualizacji w ramach?
Jak pokierować tam ruchem?
Hurra, napisaliśmy do tego moduł w PHP :) To mały, klasyczny moduł dla Bitrixa. Nie jest ona jeszcze udostępniona publicznie, ale planujemy ją otworzyć.
Moduł instaluje się jak zwykły moduł w Bitrixie:
I wygląda to tak:
Umożliwia ustawienie pliku cookie identyfikującego administratora witryny i umożliwiającego Kubernetesowi wysyłanie ruchu do modułu aktualizacji.
Po zakończeniu zmian należy kliknąć git push, zmiany w kodzie zostaną wysłane do git, następnie system zbuduje obraz z nową wersją kodu i „wdroży” go w klastrze, zastępując stare pody .
Tak, to trochę oparcie, ale jednocześnie utrzymujemy architekturę mikroserwisów i nie odbieramy użytkownikom Bitrix ulubionej możliwości poprawienia kodu z poziomu panelu administracyjnego. W końcu jest to opcja, można rozwiązać problem edycji kodu w inny sposób.
Wykres steru
Do tworzenia aplikacji na platformie Kubernetes zazwyczaj używamy menedżera pakietów Helm.
Dla naszego rozwiązania Bitrix w Kubernetes Sergey Bondarev, nasz wiodący administrator systemu, napisał specjalny wykres Helm.
Tworzy workery, ugrade, cron pody, konfiguruje wejścia, usługi i przesyła zmienne z sekretów Kubernetes do podów.
Przechowujemy kod w Gitlabie, a także uruchamiamy kompilację Helma z Gitlaba.
Helm umożliwia także „płynne” wycofywanie zmian, jeśli nagle coś pójdzie nie tak podczas wdrażania. Miło jest, gdy nie wpadasz w panikę „napraw kod przez FTP, bo padł prod”, ale Kubernetes robi to automatycznie i bez przestojów.
Wdrożyć
Tak, jesteśmy fanami Gitlab i Gitlab CI, używamy go :)
Podczas zatwierdzania w Gitlabie w repozytorium projektu Gitlab uruchamia potok, który wdraża nową wersję środowiska.
Etapy:
build (budowanie nowego obrazu Dockera)
testować (testować)
oczyścić (usunąć środowisko testowe)
push (wysyłamy do rejestru Dockera)
wdrożyć (aplikację wdrażamy na Kubernetesie poprzez Helm).
Hurra, gotowe, wdrażamy!
Cóż, lub zadaj pytania, jeśli takie istnieją.
Co więc zrobiliśmy
Z technicznego punktu widzenia:
zadokowany Bitrix;
„pociąć” Bitrix na pojemniki, z których każdy wykonuje minimum funkcji;
osiągnięty stan bezpaństwowy kontenerów;
rozwiązano problem z aktualizacją Bitrixa w Kubernetesie;
wszystkie funkcje Bitrixa nadal działały (prawie wszystkie);
Pracowaliśmy nad wdrożeniem na Kubernetes i wycofywaniem pomiędzy wersjami.
Z biznesowego punktu widzenia:
tolerancja na błędy;
Narzędzia Kubernetes (łatwa integracja z Gitlab CI, bezproblemowe wdrożenie itp.);
tajne hasła (widoczne tylko dla osób, którym bezpośrednio przyznano dostęp do haseł);
Wygodne jest tworzenie dodatkowych środowisk (do celów deweloperskich, testowych itp.) w ramach jednej infrastruktury.