Southbridge w Czelabińsku i Bitrix w Kubernetes

W Czelabińsku odbywają się meetupy administratorów systemów Sysadminka, a na ostatnim z nich wygłaszałem referat na temat naszego rozwiązania dla aplikacji na 1C-Bitrix w Kubernetes.

Bitrix, Kubernetes, Ceph — świetna mieszanka?

Opowiem, jak z tego wszystkiego zbudowaliśmy działające rozwiązanie.

Zaczynamy!

Southbridge w Czelabińsku i Bitrix w Kubernetes

Meetup odbył się 18 kwietnia w Czelabińsku. O naszych meetupach można poczytać w Timepad i zobaczyć na YouTube.

Jeśli chcesz do nas przyjść z referatem lub jako słuchacz — zapraszam, pisz na vadim.isakanov@gmail.com i w Telegramie t.me/vadimisakanov.

Mój referat

Southbridge w Czelabińsku i Bitrix w Kubernetes

Slajdy

Rozwiązanie „Bitrix w Kubernetes, wersja Southbridge 1.0”

Opowiem o naszym rozwiązaniu w formacie „dla tych, którzy zaczynają z Kubernetes”, jak to było przedstawione na meetupie. Ale zakładam, że słowa Bitrix, Docker, Kubernetes, Ceph są wam znane przynajmniej na poziomie artykułów w Wikipedii.

Co tak naprawdę jest już gotowe o Bitrix w Kubernetes?

W całym Internecie jest bardzo mało informacji o aplikacjach działających na Bitrix w Kubernetes.
Znalazłem tylko takie materiały:

Referat Aleksandra Serbuli, 1C-Bitrix, oraz Antona Tuzlukowa z Qsoft:

Odtwarzaj wideo

Zalecałem go wysłuchać.

Opracowanie własnego rozwiązania od użytkownika serkyron na Hubie.
Znalazłem jeszcze takie rozwiązanie.

Iiiii… w zasadzie to wszystko.

Ostrzegam, że jakość pracy rozwiązań zgodnie z powyższymi linkami nie była przez nas sprawdzana 🙂
Przygotowując nasze rozwiązanie, rozmawiałem z Aleksandrem Serbulą, wtedy jego referat jeszcze nie istniał, dlatego w moich slajdach jest punkt „Bitrix nie korzysta z Kubernetes”.

Ale za to jest już wiele gotowych obrazów Docker do pracy z Bitrix w Docker: https://hub.docker.com/search?q=bitrix&type=image

Czy to wystarczy do stworzenia pełnoprawnego rozwiązania dla Bitrix w Kubernetes?
Nie. Jest wiele problemów, które trzeba rozwiązać.

Jakie są problemy z Bitrix w Kubernetes?

Pierwszy — gotowe obrazy z Dockerhub nie nadają się do Kubernetes

Jeśli chcemy zbudować architekturę mikroserwisową (a w Kubernetes zazwyczaj tego chcemy), aplikację w Kubernetes należy dzielić na kontenery i dążyć do tego, aby każdy kontener realizował jedną małą funkcję (i robił to dobrze). Dlaczego tylko jedną? Krótko mówiąc — im prostsze, tym bardziej niezawodne.
Jeśli dłużej — proszę zobaczyć ten artykuł i wideo: https://habr.com/ru/company/southbridge/blog/426637/

Obrazy Docker w Dockerhub są głównie budowane na zasadzie „wszystko w jednym”, dlatego musieliśmy jednak stworzyć własną wersję i nawet obrazy robić od podstaw.

Po drugie — kod strony jest edytowany z panelu administracyjnego

Utworzono nową sekcję na stronie — zaktualizowano kod (dodano katalog o nazwie nowej sekcji).

Zmieniono właściwości komponentu z panelu administracyjnego — kod się zmienił.

Kubernetes „domyślnie” nie potrafi tego obsługiwać, kontenery muszą być niemutowalne (Stateless).

Przyczyna: każdy kontener (pod) w klastrze obsługuje tylko część ruchu. Jeśli zmienisz kod tylko w jednym kontenerze (podzie), to w różnych podach kod będzie różny, strona będzie działać w sposób zróżnicowany, różnym użytkownikom będą pokazywane różne wersje strony. Tak żyć nie można.

Po trzecie — trzeba rozwiązać kwestię z wdrożeniem.

Jeśli mamy monolit i jeden „klasyczny” serwer, wszystko jest całkiem proste: wdrażamy nową bazę kodu, przeprowadzamy migrację BD, przekierowujemy ruch na nową wersję kodu. Przełączenie następuje natychmiastowo.
Jeśli mamy stronę na Kubernetes, podzieloną na mikrousługi, kontenerów z kodem jest dużo — oj. Trzeba zbudować kontenery z nową wersją kodu, wdrożyć je zamiast starych, prawidłowo wykonać migrację BD i w idealnym przypadku zrobić to niezauważalnie dla odwiedzających. Na szczęście Kubernetes wspiera nas w tym, zapewniając wiele różnych rodzajów wdrożenia.

Po czwarte — trzeba rozwiązać kwestię przechowywania statyki.

Jeśli Twoja strona waży „zaledwie” 10 gigabajtów i wdrożysz ją w całości w kontenerach, otrzymasz kontenery ważące 10 gigabajtów, które będą wdrażane w nieskończoność.
Najcięższe części strony trzeba przechowywać poza kontenerami, i pojawia się pytanie, jak to właściwie robić.

Czego nie ma w naszym rozwiązaniu.

Cały kod Bitrix nie jest podzielony na mikrofunkcje/mikrousługi (tak, aby rejestracja była osobno, moduł sklepu internetowego osobno itd.). Całą bazę kodu przechowujemy w każdym kontenerze w całości.

Bazy w Kubernetes również nie przechowujemy (realizowałem rozwiązania z bazą w Kubernetes dla środowisk deweloperów, ale nie dla produkcji).

Administratorzy strony zauważą, że strona działa w Kubernetes. Funkcja „sprawdzenie systemu” działa nieprawidłowo, aby edytować kod strony z panelu administracyjnego, najpierw trzeba nacisnąć przycisk „chcę edytować kod.”

Z problemami się uporaliśmy, ustaliliśmy konieczność wdrożenia mikroserwisowości, cel jest jasny – stworzyć działający system do pracy aplikacji na Bitrixie w Kubernetes, zachowując zarówno możliwości Bitrixa, jak i zalety Kubernetes. Zaczynamy wdrożenie.

Architektura

Wiele «roboczych» podów z serwerem WWW (worker'y).
Jeden pod z zadaniami cron (może być tylko jeden).
Jeden upgrade pod do edytowania kodu strony z panelu administracyjnego (też musi być tylko jeden).

Southbridge w Czelabińsku i Bitrix w Kubernetes

Rozwiązujemy kwestie:

  • Gdzie przechowywać sesje?
  • Gdzie przechowywać cache?
  • Gdzie przechowywać statykę, nie można trzymać gigabajtów statyki w masie kontenerów?
  • Jak będzie działać baza danych?

Obraz Docker

Zaczynamy od budowy obrazu Docker.

Idealna opcja – mamy jeden uniwersalny obraz, na jego podstawie uzyskujemy zarówno worker pody, jak i pody z zadaniami cron oraz upgrade pody.

Zrobiliśmy właśnie taki obraz..

Zawiera nginx, apache/php-fpm (można wybrać podczas budowy), msmtp do wysyłania poczty oraz cron.

Podczas budowy obrazu do katalogu /app kopiowana jest pełna baza kodu strony (z wyjątkiem tych części, które przeniesiemy do oddzielnego wspólnego storage).

Mikroserwisowość, usługi

worker pody:

  • Kontener z nginx + kontener apache/php-fpm + msmtp
  • msmtp nie udało się przenieść do oddzielnego mikroserwisu, Bitrix zaczyna protestować, że nie może bezpośrednio wysłać poczty
  • W każdym kontenerze jest pełna baza kodu.
  • Zakaz zmiany kodu w kontenerach.

cron pod:

  • kontener z apache, php, cron
  • w komplecie pełna baza kodu
  • zakaz zmiany kodu w kontenerach

upgrade pod:

  • kontener z nginx + kontener apache/php-fpm + msmtp
  • brak zakazu zmiany kodu w kontenerach

przechowywanie sesji

przechowywanie cache Bitrix

Jeszcze ważne: hasła do wszystkiego, od bazy danych do poczty, przechowujemy w tajemnicach Kubernetes. Zyskujemy bonus, hasła są widoczne tylko dla tych, którym dajemy dostęp do tajemnic, a nie dla wszystkich, którzy mają dostęp do bazy kodu projektu.

Przechowywanie statyki

Można użyć czegokolwiek: ceph, nfs (ale nfs nie polecamy do produkcji), przechowywanie sieciowe od „chmurowych” dostawców itp.

Przechowywanie należy podłączyć w kontenerach do katalogu /upload/ strony oraz innych katalogów ze statyką.

Baza danych.

Dla uproszczenia zalecamy przenieść bazę poza Kubernetes. Baza w Kubernetes – to oddzielne, skomplikowane zadanie, znacznie skomplikuje schemat.

Przechowywanie sesji

Używamy memcached 🙂

Dobrze radzi sobie z przechowywaniem sesji, jest sklastrowany, „natywnie” wspierany jako session.save_path w php. Taki system był wielokrotnie wykorzystywany jeszcze w klasycznej architekturze monolitycznej, kiedy budowaliśmy klastry z dużą liczbą serwerów www. Do wdrożeń używamy helm.

$ helm install stable/memcached --name session

php.ini — tutaj w obrazie ustawione są konfiguracje dla przechowywania sesji w memcached

Użyliśmy zmiennych środowiskowych do przesyłania danych o hostach z memcached https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/.
To pozwala na użycie tego samego kodu w środowiskach dev, stage, test, prod (nazwy hostów memcached w nich będą się różnić, dlatego do każdego środowiska musimy przesłać unikalne nazwy hostów dla sesji).
Magazyn cache Bitrix

Potrzebujemy odpornego na awarie magazynu, do którego wszystkie pody mogłyby pisać i z którego mogłyby czytać.

Również używamy memcached.
To rozwiązanie jest zalecane przez samego Bitrixa.

$ helm install stable/memcached --name cache

bitrix/.settings_extra.php — tutaj w Bitrixie ustalamy, gdzie przechowujemy cache

Również używamy zmiennych środowiskowych.

Cron tasks

Istnieją różne podejścia do wykonywania zadań cron w Kubernetes.

  • oddzielne wdrożenie z podami do wykonywania zadań cron
  • cronjob do wykonywania zadań cron (jeśli to aplikacja webowa — z wget https://$host$cronjobname, lub kubectl exec do wnętrza jednego z worker podów, itp.)
  • etc.

Można dyskutować o najodpowiedniejszym, ale w tym przypadku wybraliśmy opcję „oddzielne wdrożenie z podami do zadań cron”

Jak to zrobiono:

  • zabieramy zadania cron przez ConfigMap lub przez plik config/addcron
  • uruchamiamy kontener, identyczny do worker-podu, w jednej instancji + zezwalamy na wykonywanie zadań cron w nim
  • używana jest ta sama baza kodu, dzięki ujednoliceniu budowa kontenera jest prosta

Co dobrego uzyskujemy:

  • mamy działające zadania cron w środowisku identycznym do środowiska deweloperów (docker)
  • zadania cron nie muszą być „przepisywane” na Kubernetes, one działają w tej samej formie i w tej samej bazie kodu, co wcześniej
  • do zadań cron mogą dodawać wszyscy członkowie zespołu z prawami commit do gałęzi produkcyjnej, a nie tylko administratorzy

Moduł Southbridge K8SDeploy i edytowanie kodu z panelu administracyjnego

Mówiliśmy o upgrade podów?
A jak kierować tam ruch?
Hurra, napisaliśmy do tego moduł w php 🙂 To mały klasyczny moduł dla Bitrixa. Jeszcze nie jest dostępny publicznie, ale planujemy go udostępnić.
Moduł instalowany jest jak zwykły moduł w Bitrixie:

Southbridge w Czelabińsku i Bitrix w Kubernetes

I wygląda to tak:

Southbridge w Czelabińsku i Bitrix w Kubernetes

Umożliwia ustawienie cookie, które identyfikuje administratora strony i pozwala Kubernetesowi kierować ruch do podu aktualizacyjnego.

Po zakończeniu zmian należy nacisnąć git push, zmiany w kodzie zostaną wysłane do git, a następnie system zbuduje obraz z nową wersją kodu i „rozpowszechni” go w klastrze, zastępując stare pody.

Tak, trochę na siłę, ale przy tym zachowujemy architekturę mikroserwisów i nie odbieramy użytkownikom Bitrixa ulubionej możliwości poprawienia kodu z panelu administracyjnego. W końcu to opcja, problem z poprawą kodu można rozwiązać inaczej.

Helm chart

Do budowy aplikacji w Kubernetes zazwyczaj używamy menedżera pakietów Helm.
Dla naszego rozwiązania Bitrix w Kubernetes, nasz główny administrator systemów, Sergey Bondarev, napisał specjalny chart Helm.

Wykonuje budowę workerów, ugrade, podów cron, konfiguruje ingressy, usługi, przekazuje zmienne z tajemnic Kubernetes do podów.

Kod przechowujemy w Gitlabie, a budowę Helmu również uruchamiamy z Gitlaba.

Krótko mówiąc, wygląda to tak

$ helm upgrade --install project .helm --set image=registrygitlab.local/k8s/bitrix -f .helm/values.yaml --wait --timeout 300 --debug --tiller-namespace=production

Helm umożliwia również „bezszwowy” rollback, jeśli coś pójdzie nie tak podczas wdrożenia. Miło, że to nie ty w panice „naprawiasz kod przez ftp, bo produkcja padła”, tylko Kubernetes robi to automatycznie, bez przestojów.

Wdrożenie

Tak, jesteśmy fanami Gitlab i Gitlab CI, używamy go 🙂
Przy commicie w Gitlabie w repozytorium projektu Gitlab uruchamia pipeline, który wykonuje wdrożenie nowej wersji środowiska.

Etapy:

  • build (budujemy nowy obraz Dockera)
  • test (testujemy)
  • clean up (usuwamy środowisko testowe)
  • push (wysyłamy go do rejestru Dockera)
  • deploy (wdrażamy aplikację w Kubernetes za pomocą Helmu).

Southbridge w Czelabińsku i Bitrix w Kubernetes

Hurra, gotowe, wdrażamy!
Albo zadawajmy pytania, jeśli są.

Więc, co zrobiliśmy

Z technicznego punktu widzenia:

  • zdockerowaliśmy Bitrix;
  • „przecięliśmy” Bitrix na kontenery, z których każdy wykonuje minimum funkcji;
  • osiągnęliśmy stan stateless kontenerów;
  • rozwiązaliśmy problem aktualizacji Bitrixa w Kubernetes;
  • wszystkie funkcje Bitrixa działały dalej (prawie wszystkie);
  • opracowaliśmy wdrożenie w Kubernetes i rollback między wersjami.

Z punktu widzenia biznesowego:

  • odporność na awarie;
  • narzędzia Kubernetes (prosta integracja z Gitlab CI, bezszwowe wdrożenie itd.);
  • hasła w tajemnicach (widoczne tylko dla tych, którzy mają bezpośredni dostęp do haseł);
  • łatwo jest tworzyć dodatkowe środowiska (do rozwoju, testów itp.) w ramach jednolitych zasobów.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster