Migracja monolitycznej strony internetowej do mikroserwisów w Google Kubernetes Engine

1. Wprowadzenie

Jakie korzyści płyną z przejścia z aplikacji monolitycznej na architekturę mikroserwisów? Podzielenie aplikacji na mikroserwisy daje opisane poniżej korzyści, z których większość wywodzi się z faktu, że mikroserwisy są ze sobą luźno sprzężone.

  • Mikroserwisy można testować i wdrażać niezależnie. Im mniejsza jest jednostka wdrożenia, tym łatwiej ją wdrożyć.
  • Mogą być implementowane w różnych językach i na różnych platformach. Dla poszczególnych mikroserwisów można wybrać najlepszą technologię na potrzeby konkretnego przypadku użycia.
  • Mogą być zarządzane przez różne zespoły. Dzięki istnieniu granic między mikroserwisami łatwiej jest przydzielić zespół do 1 lub kilku mikroserwisów.
  • Przejście na technologię mikroserwisów przyczynia się do rozluźnienia zależności między zespołami. Poszczególne zespoły muszą się zajmować tylko interfejsami API tych mikroserwisów, z którymi łączą je współzależności. Członkowie zespołów nie muszą wiedzieć, jak te mikroserwisy zostały zaimplementowane, jakie są ich cykle wydań itd.
  • Prostsze jest też projektowanie reakcji na awarie. Dzięki istnieniu wyraźnych granic między usługami łatwiej można określić, jakie czynności należy wykonać w przypadku wyłączenia usługi.

W porównaniu z monolitami mikroserwisy mają też swoje wady. Oto kilka z nich:

  • Aplikacja bazująca na mikroserwisach to sieć różnych usług, które często wchodzą ze sobą w nieoczekiwane interakcje, dlatego ogólna złożoność takiego systemu staje się coraz większa.
  • W przeciwieństwie do komponentów aplikacji monolitycznych mikroserwisy komunikują się przez sieć. W pewnych okolicznościach może to powodować problemy z zabezpieczeniami. Istio rozwiązuje ten problem przez automatyczne szyfrowanie ruchu między mikroserwisami.
  • Osiągnięcie takiego samego poziomu wydajności, jakim charakteryzują się aplikacje monolityczne, może okazać się trudne z powodu występowania opóźnień między usługami.
  • Zachowanie całego systemu jest wynikiem nie tylko zachowania pojedynczej usługi, ale wielu z nich oraz występujących między nimi interakcji. Z tego powodu trudniej jest zrozumieć, w jaki sposób system zachowa się w środowisku produkcyjnym (jaka będzie jego dostrzegalność). Istio oferuje rozwiązanie także tego problemu.

W tym module uruchomimy mikroserwisy w Google Kubernetes Engine (GKE). Kubernetes to platforma umożliwiająca hostowanie, skalowanie i wdrażanie kontenerów oraz zarządzanie nimi. Kontenery to przenośny sposób pakowania i uruchamiania kodu. Są one szczególnie przydatne w modelu mikroserwisów, w którym poszczególne mikroserwisy działają we własnych kontenerach.

W tym module wdrożymy istniejącą aplikację monolityczną w klastrze Google Kubernetes Engine, a następnie podzielimy ją na mikroserwisy.

Schemat architektury naszych mikroserwisów

Zaczniemy od podzielenia monolitu kolejno na 3 mikroserwisy. Będą one nosiły nazwy Orders (Zamówienia), Products (Produkty) i Frontend. Za pomocą Cloud Build tworzymy obraz Dockera dla każdego mikroserwisu, który aktywujemy w Cloud Shell. Następnie wdrożymy i udostępnimy mikroserwisy w Google Kubernetes Engine (GKE) z usługą Kubernetes typu LoadBalancer. Wykonamy to zadanie dla każdej usługi z jednoczesną ich refaktoryzacją z naszego monolitu. Podczas trwania tego procesu będą działały zarówno mikroserwisy, jak i monolit, aż do samego końca, kiedy monolit zostanie ostatecznie usunięty.

636a2d58588b2b87.png

Czego się nauczysz

  • Jak podzielić monolit na mikroserwisy
  • Jak utworzyć klaster Google Kubernetes Engine
  • Jak utworzyć obraz Dockera
  • Jak wdrożyć obrazy Dockera w klastrach Kubernetes

Wymagania wstępne

  • Konto Google Cloud Platform z dostępem administracyjnym do tworzenia projektów lub projekt z rolą właściciela projektu
  • Podstawowa znajomość technologii Docker i Kubernetes

2. Konfiguracja środowiska

Samodzielne konfigurowanie środowiska

Jeśli nie masz jeszcze konta Google (Gmail lub Google Apps), musisz je utworzyć. Zaloguj się w konsoli Google Cloud Platform ( console.cloud.google.com) i utwórz nowy projekt:

53dad2cefdae71da.png

Screenshot from 2016-02-10 12:45:26.png

Zapamiętaj identyfikator projektu, czyli unikalną nazwę we wszystkich projektach Google Cloud (podana powyżej nazwa jest już zajęta i nie będzie działać w Twoim przypadku). W dalszej części tego laboratorium będzie on nazywany PROJECT_ID.

Następnie musisz włączyć płatności w konsoli deweloperów, aby korzystać z zasobów Google Cloud i włączyć interfejs Container Engine API.

Wykonanie tego samouczka nie powinno kosztować więcej niż kilka dolarów, ale może okazać się droższe, jeśli zdecydujesz się wykorzystać więcej zasobów lub pozostawisz je uruchomione (patrz sekcja „Czyszczenie” na końcu tego dokumentu). Cennik Google Kubernetes Engine znajdziesz tutaj.

Nowi użytkownicy Google Cloud Platform mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.

Google Cloud Shell

Z Google Cloud i Kubernetes można korzystać zdalnie na laptopie, ale w tym ćwiczeniu programistycznym będziemy używać Google Cloud Shell, czyli środowiska wiersza poleceń działającego w chmurze.

Ta maszyna wirtualna oparta na Debianie zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera również stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i usprawnia proces uwierzytelniania. Oznacza to, że do ukończenia tego ćwiczenia potrzebujesz tylko przeglądarki (działa ona na Chromebooku).

  1. Aby aktywować Cloud Shell w konsoli Cloud, kliknij Aktywuj Cloud Shell fEbHefbRynwXpq1vj2wJw6Dr17O0np8l-WOekxAZYlZQIORsWQE_xJl-cNhogjATLn-YxLVz8CgLvIW1Ncc0yXKJsfzJGMYgUeLsVB7zSwz7p6ItNgx4tXqQjag7BfWPcZN5kP-X3Q (udostępnienie środowiska i połączenie się z nim powinno zająć tylko kilka chwil).

I5aEsuNurCxHoDFjZRZrKBdarPPKPoKuExYpdagmdaOLKe7eig3DAKJitIKyuOpuwmrMAyZhp5AXpmD_k66cBuc1aUnWlJeSfo_aTKPY9aNMurhfegg1CYaE11jdpSTYNNIYARe01A

Screen Shot 2017-06-14 at 10.13.43 PM.png

Po połączeniu z Cloud Shell zobaczysz, że uwierzytelnianie zostało już przeprowadzone, a projekt jest już ustawiony na Twój identyfikator projektu PROJECT_ID.

gcloud auth list

Wynik polecenia

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Wynik polecenia

[core]
project = <PROJECT_ID>

Jeśli z jakiegoś powodu projekt nie jest ustawiony, po prostu wydaj to polecenie:

gcloud config set project <PROJECT_ID>

Szukasz urządzenia PROJECT_ID? Sprawdź, jakiego identyfikatora użyto w krokach konfiguracji, lub wyszukaj go w panelu konsoli Cloud:

R7chO4PKQfLC3bvFBNZJALLTUiCgyLEq_67ECX7ohs_0ZnSjC7GxDNxWrJJUaoM53LnqABYamrBJhCuXF-J9XBzuUgaz7VvaxNrkP2TAn93Drxccyj2-5zz4AxL-G3hzxZ4PsM5HHQ

Cloud Shell domyślnie ustawia też niektóre zmienne środowiskowe, które mogą być przydatne podczas wykonywania kolejnych poleceń.

echo $GOOGLE_CLOUD_PROJECT

Wynik polecenia

<PROJECT_ID>
  1. Na koniec ustaw domyślną strefę i konfigurację projektu.
gcloud config set compute/zone us-central1-f

Możesz wybrać różne strefy. Więcej informacji znajdziesz w artykule Regiony i strefy.

3. Kopiowanie repozytorium źródłowego

Korzystamy z istniejącej aplikacji monolitycznej pochodzącej z fikcyjnej witryny e-commerce, w skład której wchodzi prosta strona powitalna, strona z produktami oraz strona z historią zamówień. Po sklonowaniu kodu źródłowego z repozytorium Git będzie można skoncentrować się na podzieleniu aplikacji na mikroserwisy i wdrożeniu ich w Google Kubernetes Engine (GKE).

Uruchom następujące polecenia, aby sklonować repozytorium Git do instancji Cloud Shell i przejść do odpowiedniego katalogu. Zainstalujemy też zależności NodeJS umożliwiające przetestowanie monolitu przed wdrożeniem. Działanie tego skryptu może potrwać kilka minut.

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices
./setup.sh

Spowoduje to sklonowanie repozytorium GitHub, przejście do katalogu i zainstalowanie zależności potrzebnych do lokalnego uruchomienia aplikacji. Działanie tego skryptu może potrwać kilka minut.

4. Tworzenie klastra GKE

Skoro masz już działające środowisko programistyczne, potrzebujesz teraz klastra Kubernetes, w którym wdrożysz swój monolit, a na koniec także mikroserwisy. Zanim utworzymy klaster, musimy się upewnić, że włączono odpowiednie interfejsy API. Uruchom następujące polecenie, aby włączyć interfejs API kontenerów umożliwiający skorzystanie z Google Kubernetes Engine:

gcloud services enable container.googleapis.com

Teraz możemy utworzyć klaster. Uruchom poniższe polecenie, aby utworzyć klaster GKE o nazwie fancy-cluster3 węzłami.

gcloud container clusters create fancy-cluster --num-nodes 3

Tworzenie klastra może potrwać kilka minut. Po zakończeniu wykonywania tego polecenia uruchom następujące polecenie, aby wyświetlić 3 instancje robocze znajdujące się w klastrze:

gcloud compute instances list

Dane wyjściowe:

NAME                                          ZONE        MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
gke-fancy-cluster-default-pool-ad92506d-1ng3  us-east4-a  n1-standard-1               10.150.0.7   XX.XX.XX.XX    RUNNING
gke-fancy-cluster-default-pool-ad92506d-4fvq  us-east4-a  n1-standard-1               10.150.0.5   XX.XX.XX.XX    RUNNING
gke-fancy-cluster-default-pool-ad92506d-4zs3  us-east4-a  n1-standard-1               10.150.0.6   XX.XX.XX.XX    RUNNING

Klaster Kubernetes oraz związane z nim informacje możesz również wyświetlić w konsoli Google Cloud. W lewym górnym rogu kliknij przycisk menu, przewiń w dół do Kubernetes Engine i kliknij Klastry. Zobaczysz klaster o nazwie fancy-cluster.

795c794b03c5d2b0.png

6b394dfb8a6031f2.png

Gratulacje! Właśnie udało Ci się utworzyć pierwszy klaster Kubernetes.

5. Wdrażanie istniejącego monolitu

Ponieważ najważniejszym zadaniem do wykonania w tym module jest podzielenie monolitu na mikroserwisy, najpierw musisz uruchomić aplikację monolityczną. Uruchom następujący skrypt, aby wdrożyć aplikację monolitową w klastrze GKE na potrzeby tego modułu:

cd ~/monolith-to-microservices
./deploy-monolith.sh

Uzyskiwanie dostępu do monolitu

Aby znaleźć zewnętrzny adres IP aplikacji monolitycznej, uruchom to polecenie:

kubectl get service monolith

Zostaną wyświetlone dane wyjściowe podobne do tych:

NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
monolith     10.3.251.122    203.0.113.0     80:30877/TCP     3d

UWAGA: w tym celu trzeba skonfigurować zewnętrzny system równoważenia obciążenia i adres IP, więc może to trochę potrwać. Jeśli w danych wyjściowych zewnętrzny adres IP jest określony jako

<pending> poczekaj kilka minut i spróbuj ponownie;

Skopiuj wyświetlony zewnętrzny adres IP monolitu. Wpisz ten adres URL (na przykład http://203.0.113.0) w przeglądarce, aby sprawdzić, czy do monolitu można uzyskać dostęp.

9ed25c3f0cbe62fa.png

Powinna pojawić się strona powitalna witryny monolitowej taka jak widoczna na powyższej ilustracji. Strona powitalna jest stroną statyczną, która później będzie udostępniana przez mikroserwis Frontend. Twój monolit działa teraz całkowicie w klastrze Kubernetes.

6. Przeniesienie usługi Orders do mikroserwisu

Kiedy witryna monolitowa działa już w GKE, możemy rozpocząć dzielenie usług na poszczególne mikroserwisy. Zazwyczaj planuje się, które usługi powinny zostać podzielone na mniejsze kawałki. Najczęściej taki podział jest zgodny z konkretnymi częściami aplikacji, takimi jak obszary biznesowe. Na potrzeby demonstracji utworzyliśmy prosty przykład i wydzieliliśmy z niego poszczególne usługi według obsługiwanych obszarów biznesowych: Zamówienia, Produkty i Frontend. Kod został już przeniesiony, więc skupimy się na tworzeniu i wdrażaniu usług w Google Kubernetes Engine (GKE).

Tworzenie nowego mikroserwisu do obsługi zamówień

Najpierw wydzielimy usługę Orders (Zamówienia). Korzystając z udostępnionej oddzielnej bazy kodu, utworzymy osobny kontener Dockera dla tej usługi.

Tworzenie kontenera Dockera za pomocą Google Cloud Build

Ponieważ baza kodu została już przeniesiona, pierwszym krokiem będzie utworzenie kontenera Dockera z usługą Order za pomocą Google Cloud Build.

Ten proces składa się zwykle z 2 kroków obejmujących utworzenie kontenera Dockera i przeniesienie go do rejestru w celu zapisania obrazu pobieranego potem przez GKE. Możemy jednak ułatwić sobie zadanie i skorzystać z Google Cloud Build, aby za pomocą jednego polecenia utworzyć kontener Dockera oraz umieścić obraz w Google Cloud Container Registry. Dzięki temu, wykonując jedno polecenie, możemy utworzyć obraz i przenieść go do rejestru kontenerów. Aby prześledzić proces ręcznego tworzenia pliku Dockera i jego przenoszenia, przejdź tutaj.

Google Cloud Build skompresuje pliki znajdujące się w katalogu i przeniesie je do zasobnika Google Cloud Storage. Następnie w procesie kompilacji wszystkie pliki z zasobnika razem z plikiem Dockerfile zostaną użyte do uruchomienia procesu kompilacji Dockera. Ponieważ dla obrazu Dockera określiliśmy flagę --tag z hostem gcr.io, wynikowy obraz Dockera zostanie przeniesiony do Google Cloud Container Registry.

Uruchom następujące polecenie, aby utworzyć kontener Dockera i przenieść go do Google Container Registry:

cd ~/monolith-to-microservices/microservices/src/orders
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/orders:1.0.0 .

Ten proces może potrwać kilka minut, a po jego zakończeniu w terminalu pojawią się dane wyjściowe podobne do tych poniżej:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ID                                    CREATE_TIME                DURATION  SOURCE                                                                                  IMAGES                              STATUS
1ae295d9-63cb-482c-959b-bc52e9644d53  2019-08-29T01:56:35+00:00  33S       gs://<PROJECT_ID>_cloudbuild/source/1567043793.94-abfd382011724422bf49af1558b894aa.tgz  gcr.io/<PROJECT_ID>/orders:1.0.0  SUCCESS

Aby wyświetlić historię kompilacji lub obserwować ten proces w czasie rzeczywistym, otwórz konsolę Google Cloud. W lewym górnym rogu kliknij przycisk menu i przewiń w dół do sekcji Narzędzia → Cloud Build, a następnie kliknij Historia. Tutaj znajdziesz listę wszystkich utworzonych do tej pory kompilacji. Na razie powinna być tam widoczna tylko 1 kompilacja utworzona przed chwilą.

4c753ede203255f6.png

Po kliknięciu identyfikatora kompilacji zostaną wyświetlone wszystkie szczegóły kompilacji, w tym dane wyjściowe dzienników.

Aby wyświetlić utworzony obraz kontenera, na stronie szczegółów kompilacji kliknij nazwę obrazu w sekcji informacji o kompilacji.

6e88ed1643dfe629.png

Wdrażanie kontenera w GKE

Po skonteneryzowaniu witryny i przeniesieniu kontenera do Google Container Registry nadszedł czas na wdrożenie w Kubernetes.

Kubernetes prezentuje aplikacje jako pody, czyli jednostki reprezentujące kontener (lub grupę ściśle połączonych kontenerów). Pod to najmniejsza możliwa do wdrożenia jednostka w Kubernetes. W tym samouczku poszczególne pody zawierają tylko kontenery mikroserwisów.

Aby móc wdrażać aplikacje w klastrze GKE i nimi zarządzać, należy skomunikować się z systemem zarządzania klastrami Kubernetes. Zwykle robi się to za pomocą narzędzia wiersza poleceń kubectl w Cloud Shell.

Najpierw utworzymy zasób Deployment. Deployment zarządza wieloma kopiami aplikacji nazywanymi replikami i planuje ich uruchamianie w poszczególnych węzłach w klastrze. W tym przypadku Deployment uruchomi tylko jeden pod Twojej aplikacji. Aby wszystko działało bezproblemowo, zasoby Deployment tworzą kontroler ReplicaSet. ReplicaSet odpowiada za to, aby zawsze działała określona liczba replik.

Widoczne poniżej polecenie kubectl create deployment powoduje utworzenie w klastrze Kubernetes zasobu Deployment o nazwie orders1 repliką.

Uruchom to polecenie, aby wdrożyć swoją aplikację:

kubectl create deployment orders --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/orders:1.0.0

Sprawdzanie wdrożenia

Aby sprawdzić, czy zasób Deployment został utworzony, uruchom to polecenie. Zmiana stanu poda na Uruchomiono może chwilę potrwać:

kubectl get all

Dane wyjściowe:

NAME                            READY   STATUS    RESTARTS   AGE
pod/monolith-779c8d95f5-dxnzl   1/1     Running   0          15h
pod/orders-5bc6969d76-kdxkk     1/1     Running   0          21s
NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
service/kubernetes   ClusterIP      10.39.240.1     <none>         443/TCP        19d
service/monolith     LoadBalancer   10.39.241.130   34.74.209.57   80:30412/TCP   15h
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/monolith   1/1     1            1           15h
deployment.apps/orders     1/1     1            1           21s
NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/monolith-779c8d95f5   1         1         1       15h
replicaset.apps/orders-5bc6969d76     1         1         1       21s

Dane wyjściowe pokazują kilka elementów. Widać zasób Deployment, który jest aktualny, kontroler ReplicaSet z pożądaną liczbą podów równą 1 oraz działający pod. Wygląda na to, że udało się utworzyć wszystkie elementy.

Udostępnij kontener GKE

Wdrożyliśmy naszą aplikację w GKE, ale nie mamy możliwości uzyskania do niej dostępu spoza klastra. Domyślnie kontenery działające w GKE nie są dostępne z internetu, ponieważ nie mają zewnętrznych adresów IP. Należy bezpośrednio udostępnić aplikację dla ruchu z internetu za pomocą zasobu Service. Zasób Service udostępnia dla podów aplikacji obsługę sieci i adresu IP. GKE tworzy dla aplikacji zewnętrzny adres IP oraz system równoważenia obciążenia (podlega opłacie).

Po wdrożeniu usługi Orders została ona wewnętrznie udostępniona na porcie 8081 za pomocą wdrożenia Kubernetes. Aby udostępnić tę usługę zewnętrznie, musimy utworzyć usługę Kubernetes typu LoadBalancer, która skieruje ruch zewnętrzny z portu 80 na wewnętrzny port 8081 dla usługi Orders. Aby udostępnić stronę w internecie, uruchom następujące polecenie:

kubectl expose deployment orders --type=LoadBalancer --port 80 --target-port 8081

Uzyskiwanie dostępu do zasobu Service

GKE przypisuje zewnętrzny adres IP do zasobu Service, a nie do Deployment. Aby dowiedzieć się, jaki jest zewnętrzny adres IP udostępniony przez GKE dla aplikacji, możesz sprawdzić zasób Service za pomocą polecenia kubectl get service:

kubectl get service orders

Dane wyjściowe:

NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
orders       10.3.251.122    203.0.113.0     80:30877/TCP     3d

Skopiuj wyświetlony zewnętrzny adres IP aplikacji. Zapisz go, ponieważ będzie on potrzebny w następnym kroku, w którym zmodyfikujemy monolit, aby wskazywał na nową usługę Orders.

Ponowne konfigurowanie monolitu

Ponieważ z monolitu usunięto usługę Orders, należy go zmodyfikować w taki sposób, aby wskazywał na nowy zewnętrzny mikroserwis Orders.

Rozdzielanie monolitu polega na usunięciu fragmentów kodu z pojedynczej bazy kodu i umieszczeniu ich w wielu mikroserwisach, które są następnie oddzielnie wdrażane. Mikroserwis działa na innym serwerze, dlatego nie możemy już przywoływać adresów URL usług w postaci ścieżek bezwzględnych – musimy zastosować przekierowanie na nowy adres serwera mikroserwisu zamówień. Pamiętaj, że konieczne będzie wyłączenie usługi monolitu na pewien czas, aby zaktualizować adresy URL poszczególnych usług, które zostały usunięte z monolitu. Weź to pod uwagę, gdy planujesz przenoszenie mikroserwisów i monolitu do środowiska produkcyjnego w czasie migracji do mikroserwisów.

Musimy zaktualizować plik konfiguracyjny monolitu tak, aby wskazywał na nowy adres IP mikroserwisu Orders. W edytorze nano zastąp lokalny adres URL adresem IP nowego mikroserwisu Orders. Aby edytować

cd ~/monolith-to-microservices/react-app
nano .env.monolith

Po otwarciu w edytorze Twój plik powinien wyglądać tak:

REACT_APP_ORDERS_URL=/service/orders
REACT_APP_PRODUCTS_URL=/service/products

Zapisz adres REACT_APP_ORDERS_URL w nowym formacie, zastępując go adresem IP mikroserwisu Orders. Całość powinna wyglądać tak jak poniżej:

REACT_APP_ORDERS_URL=http://<ORDERS_IP_ADDRESS>/api/orders
REACT_APP_PRODUCTS_URL=/service/products

Naciśnij kolejno CTRL+O, ENTERCTRL+X, aby zapisać plik w edytorze nano.

Możesz przetestować nowy mikroserwis, przechodząc do adresu URL ustawionego w tym pliku. Strona internetowa powinna zwrócić odpowiedź JSON z mikroserwisu Orders.

Teraz musimy ponownie utworzyć frontend monolitu i powtórzyć proces kompilacji, aby utworzyć kontener dla monolitu i ponownie wdrożyć go w klastrze GKE. Uruchom następujące polecenia, aby zakończyć te kroki:

Ponownie utwórz pliki konfiguracyjne monolitu

npm run build:monolith

Tworzenie kontenera Dockera za pomocą Google Cloud Build

cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 .

Wdrażanie kontenera w GKE

kubectl set image deployment/monolith monolith=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0

Sprawdź, czy aplikacja może się komunikować z nowym mikroserwisem Orders. W tym celu przejdź do swojej aplikacji monolitycznej w przeglądarce i spróbuj wyświetlić stronę Orders (Zamówienia). Wszystkie identyfikatory zamówień powinny się kończyć ciągiem -MICROSERVICE, jak poniżej:

1cdd60bb0d4d1148.png

7. Migracja usługi Products do mikroserwisu

Tworzenie nowego mikroserwisu Products

Możemy kontynuować proces odłączania usług, migrując tym razem usługę Products. Postąpimy tak samo jak w poprzednim kroku. Uruchom następujące polecenia, aby utworzyć kontener Dockera, wdrożyć go i udostępnić za pomocą usługi Kubernetes.

Tworzenie kontenera Dockera za pomocą Google Cloud Build

cd ~/monolith-to-microservices/microservices/src/products
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/products:1.0.0 .

Wdrażanie kontenera w GKE

kubectl create deployment products --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/products:1.0.0

Udostępnij kontener GKE

kubectl expose deployment products --type=LoadBalancer --port 80 --target-port 8082

Znajdź publiczny adres IP usługi Products w taki sam sposób jak w przypadku usługi Orders za pomocą tego polecenia:

kubectl get service products

Dane wyjściowe:

NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
products     10.3.251.122    203.0.113.0     80:30877/TCP     3d

Zapisz adres IP, ponieważ będzie on potrzebny w następnym kroku, w którym ponownie skonfigurujemy monolit, aby wskazywał na nowy mikroserwis Products.

Ponowne konfigurowanie monolitu

W edytorze nano zastąp lokalny adres URL adresem IP nowego mikroserwisu produktów:

cd ~/monolith-to-microservices/react-app
nano .env.monolith

Po otwarciu w edytorze Twój plik powinien wyglądać tak:

REACT_APP_ORDERS_URL=http://<ORDERS_IP_ADDRESS>/api/orders
REACT_APP_PRODUCTS_URL=/service/products

Zastąp REACT_APP_PRODUCTS_URL nowym formatem, zastępując go adresem IP mikroserwisu produktów. Całość powinna wyglądać tak jak poniżej:

REACT_APP_ORDERS_URL=http://<ORDERS_IP_ADDRESS>/api/orders
REACT_APP_PRODUCTS_URL=http://<PRODUCTS_IP_ADDRESS>/api/products

Naciśnij kolejno CTRL+O, ENTERCTRL+X, aby zapisać plik w edytorze nano.

Możesz przetestować nowy mikroserwis, przechodząc do adresu URL ustawionego w tym pliku. Strona internetowa powinna zwrócić odpowiedź JSON z mikroserwisu Products.

Teraz musimy ponownie utworzyć frontend monolitu i powtórzyć proces kompilacji, aby utworzyć kontener dla monolitu i ponownie wdrożyć go w klastrze GKE. Uruchom następujące polecenia, aby zakończyć te kroki:

Ponownie utwórz pliki konfiguracyjne monolitu

npm run build:monolith

Tworzenie kontenera Dockera za pomocą Google Cloud Build

cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:3.0.0 .

Wdrażanie kontenera w GKE

kubectl set image deployment/monolith monolith=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:3.0.0

Sprawdź, czy aplikacja może się komunikować z nowym mikroserwisem Products. W tym celu przejdź do swojej aplikacji monolitycznej w przeglądarce i spróbuj wyświetlić stronę Products (Produkty). Wszystkie nazwy produktów powinny mieć prefiks MS-, jak poniżej:

5389b29f4b8c7c69.png

8. Przeniesienie frontendu do mikroserwisu

Ostatnim krokiem w procesie migracji jest przeniesienie kodu frontendu do mikroserwisu i wyłączenie monolitu. Zakończenie tego kroku będzie oznaczać pomyślną migrację monolitu do architektury mikroserwisów.

Tworzenie nowego mikroserwisu frontendu

Aby utworzyć nowy mikroserwis frontendu, zastosuj taką samą procedurę jak w ostatnich 2 krokach.

Poprzednio podczas rekompilacji monolitu aktualizowaliśmy konfigurację, aby wskazywała na monolit, ale teraz musimy użyć tej samej konfiguracji dla mikroserwisu frontendu. Uruchom te polecenia, aby skopiować pliki konfiguracyjne adresów URL mikroserwisów do bazy kodu mikroserwisu frontendu:

cd ~/monolith-to-microservices/react-app
cp .env.monolith .env
npm run build

Po zakończeniu działania tych poleceń wykonaj takie same czynności jak w poprzednich krokach. Uruchom następujące polecenia, aby utworzyć kontener Dockera, wdrożyć go i udostępnić za pomocą usługi Kubernetes.

Tworzenie kontenera Dockera za pomocą Google Cloud Build

cd ~/monolith-to-microservices/microservices/src/frontend
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/frontend:1.0.0 .

Wdrażanie kontenera w GKE

kubectl create deployment frontend --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/frontend:1.0.0

Udostępnij kontener GKE

kubectl expose deployment frontend --type=LoadBalancer --port 80 --target-port 8080

Usuwanie monolitu

Teraz gdy wszystkie usługi działają jako mikroserwisy, możemy usunąć aplikację monolityczną. Pamiętaj, że w przypadku rzeczywistej migracji konieczne byłoby również dokonanie zmian DNS itd., aby istniejące nazwy domen wskazywały nowy mikroserwis frontendu naszej aplikacji. Aby usunąć monolit, uruchom te polecenia:

kubectl delete deployment monolith
kubectl delete service monolith

Sprawdzanie efektów pracy

Jeśli wszystko zostało wykonane prawidłowo, stary adres IP usługi monolitu nie powinien teraz działać, a pod nowym adresem IP usługi frontendu powinna być hostowana nowa aplikacja. Aby wyświetlić listę wszystkich usług i adresów IP, użyj tego polecenia:

kubectl get services

Dane wyjściowe powinny wyglądać podobnie do tych:

NAME         TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
frontend     LoadBalancer   10.39.246.135   35.227.21.154    80:32663/TCP   12m
kubernetes   ClusterIP      10.39.240.1     <none>           443/TCP        18d
orders       LoadBalancer   10.39.243.42    35.243.173.255   80:32714/TCP   31m
products     LoadBalancer   10.39.250.16    35.243.180.23    80:32335/TCP   21m

Skopiuj wyświetlony zewnętrzny adres IP mikroserwisu frontendu. Wpisz ten adres URL (na przykład http://203.0.113.0) w przeglądarce, aby sprawdzić, czy można uzyskać dostęp do frontendu. Twoja witryna powinna wyglądać tak samo jak przed podzieleniem monolitu na mikroserwisy.

9. Czyszczenie

Gdy wszystko będzie gotowe, najprostszym sposobem na wyczyszczenie wszystkich wykonanych działań jest usunięcie projektu. Usunięcie projektu spowoduje usunięcie wszystkich zasobów utworzonych w ramach tego laboratorium, aby uniknąć nieoczekiwanych opłat cyklicznych. Wykonaj to polecenie w Cloud Shell, gdzie PROJECT_ID to pełny identyfikator projektu, a nie tylko jego nazwa.

gcloud projects delete [PROJECT_ID]

Gdy pojawi się odpowiedni komunikat, potwierdź usunięcie, wpisując „Y”.

10. Gratulacje!

Udało Ci się podzielić aplikację monolityczną na mikroserwisy i wdrożyć je w Google Kubernetes Engine.

Następne kroki

Aby dowiedzieć się więcej o Kubernetes, zapoznaj się z tymi samouczkami:

Dodatkowe materiały