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 przynosi takie korzyści: większość z nich wynika z faktu, że mikroserwisy są luźno powiązane.

  • 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 podzielisz ją na mikroserwisy.

Schemat architektury naszych mikroserwisów

Zaczniemy od podzielenia monolitu na 3 mikroserwisy – po jednym naraz. Będą one nosiły nazwy Orders (Zamówienia), Products (Produkty) i Frontend. Za pomocą Cloud Build, który aktywuje się w Cloud Shell, dla każdego mikroserwisu tworzymy obraz Dockera. Następnie wdrożymy i udostępnimy nasze mikroserwisy w Google Kubernetes Engine (GKE) z usługą Kubernetes typu LoadBalancer. Zrobimy to w przypadku każdej usługi, jednocześnie refaktoryzując je z monolitu. Podczas tego procesu będą działały zarówno mikroserwisy, jak i monolit, aż do samego końca, kiedy monolit zostanie 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 (w Gmailu lub Google Apps), musisz je utworzyć. Zaloguj się w konsoli Google Cloud Platform ( console.cloud.google.com) i utwórz nowy projekt:

53dad2cefdae71da.png

Zrzut ekranu z 10.02.2016, 12:45:26.png

Zapamiętaj identyfikator projektu, unikalną nazwę we wszystkich projektach Google Cloud (powyższa nazwa jest już zajęta i nie będzie Ci odpowiadać). W dalszej części tego ćwiczenia w Codelabs będzie ona określana jako PROJECT_ID.

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

Wykonanie tych ćwiczeń w programie nie powinno kosztować więcej niż kilka dolarów, ale może być droższe, jeśli zdecydujesz się na więcej zasobów lub pozostawisz je włączone (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 o wartości 300 USD.

Google Cloud Shell

Google Cloud i Kubernetes możesz obsługiwać zdalnie z Twojego laptopa, ale w ramach tego ćwiczenia z programowania użyjemy Google Cloud Shell – środowiska wiersza poleceń działającego w chmurze.

Ta maszyna wirtualna oparta na Debianie zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i uwierzytelnianie. Oznacza to, że do tego ćwiczenia z programowania wystarczy przeglądarka (tak, działa ona na Chromebooku).

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

I5aEsuNurCxHoDFjZRZrKBdarPPKPoKuExYpdagmdaOLKe7eig3DAKJitIKyuOpuwmrMAyZhp5AXpmD_k66cBuc1aUnWlJeSfo_aTKPY9aNMurhfegg1CYaE11jdpSTYNNIYARe01A

Zrzut ekranu 2017-06-14 o 10.13.43 PM.png

Po nawiązaniu połączenia z Cloud Shell powinno pojawić się potwierdzenie, że użytkownik jest już uwierzytelniony, a projekt jest już ustawiony na PROJECT_ID.

gcloud auth list

Dane wyjściowe polecenia

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

Dane wyjściowe polecenia

[core]
project = <PROJECT_ID>

Jeśli z jakiegoś powodu projekt nie jest skonfigurowany, uruchom po prostu to polecenie:

gcloud config set project <PROJECT_ID>

Szukasz urządzenia PROJECT_ID? Sprawdź identyfikator użyty w krokach konfiguracji lub wyszukaj go w panelu Cloud Console:

R7chO4PKQfLC3bvFBNZJALLTUiCgyLEq_67ECX7ohs_0ZnSjC7GxDNxWrJJUaoM53LnqABYamrBJhCuXF-J9XBzuUgaz7VvaxNrkP2TAn93Drxccyj2-5zz4AxL-G3hzxZ4PsM5HHQ

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

echo $GOOGLE_CLOUD_PROJECT

Dane wyjściowe 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 również 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 skopiowanie repozytorium GitHub, przeniesienie do katalogu i zainstalowanie zależności niezbędnych 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, potrzebujemy klastra Kubernetes, w którym wdrożymy nasz monolit, a na końcu nasze mikroserwisy. Przed utworzeniem klastra musimy się upewnić, że są włączone odpowiednie interfejsy API. Uruchom to polecenie, aby włączyć interfejs API kontenerów i umożliwić korzystanie 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-cluster z 3 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 je, aby wyświetlić 3 instancje robocze klastra:

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. Kliknij przycisk menu w lewym górnym rogu, 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

W tym module skupiamy się na podzieleniu monolitu na mikroserwisy, dlatego musimy uruchomić aplikację monolityczną. Na potrzeby tego modułu uruchom następujący skrypt, aby wdrożyć aplikację monolityczną w klastrze GKE:

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

Dostęp do monolitu

Aby znaleźć zewnętrzny adres IP naszej aplikacji monolitycznej, uruchom następujące 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: muszą być do tego udostępnione zewnętrzny system równoważenia obciążenia oraz adres IP, więc może minąć trochę czasu, zanim stanie się to możliwe. Jeśli w danych wyjściowych zewnętrzny adres IP jest określony jako

<pending> daj mu 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. Migracja usługi Orders do mikroserwisu

Mamy już witrynę monolityczną działającą w GKE, więc możemy zacząć dzielić usługi 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. Dla celów demonstracyjnych utworzyliśmy prosty przykład. Zestawienie każdej usługi obejmuje domenę biznesową, zamówienia, produkty i frontend. Kod został już przeniesiony. Skupimy się na tworzeniu i wdrażaniu usług w Google Kubernetes Engine (GKE).

Mikroserwis tworzenia nowych zamówień

Najpierw przedstawimy usługę Orders (Zamówienia). Skorzystamy z udostępnionej oddzielnej bazy kodu i utworzymy dla tej usługi osobny kontener Dockera.

Tworzenie kontenera Dockera za pomocą Google Cloud Build

Ponieważ przenieśliśmy już bazę kodu, naszym pierwszym krokiem będzie utworzenie kontenera Dockera z naszą 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 życie – możemy za pomocą Google Cloud Build utworzyć kontener Dockera i umieścić obraz w Google Cloud Container Registry za pomocą jednego polecenia. 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 obejrzeć ten proces w czasie rzeczywistym, możesz otworzyć konsolę Google Cloud. Kliknij przycisk menu w lewym górnym rogu i przewiń w dół do sekcji Narzędzia → Cloud Build i 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 z informacjami o kompilacji kliknij jego nazwę w sekcji informacji o kompilacji.

6e88ed1643dfe629.png

Wdrażanie kontenera w GKE

Po umieszczeniu witryny w kontenerze 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 (wdrożenie). Deployment zarządza wieloma kopiami aplikacji nazywanymi replikami i planuje ich uruchamianie w poszczególnych węzłach w klastrze. W tym przypadku zasób Deployment uruchomi tylko 1 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.

Poniższe polecenie kubectl create deployment powoduje, że Kubernetes tworzy w klastrze wdrożenie o nazwie orders z 1 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ł prawidłowo 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 informacji. Widzimy 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 udostępniliśmy ją wewnętrznie na porcie 8081 w ramach 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 w usłudze 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 zasobu Deployment. Aby dowiedzieć się, jaki jest zewnętrzny adres IP udostępniony przez GKE dla aplikacji, możesz sprawdzić usługę 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 na potrzeby następnego kroku, kiedy zmienimy monolit tak, aby wskazywał naszą nową usługę Orders.

Ponowne konfigurowanie monolitu

Ponieważ usunęliśmy z monolitu usługę Orders, musimy go zmodyfikować w taki sposób, aby wskazywał na nowy zewnętrzny mikroserwis Orders.

Rozdzielając monolit, usuwamy fragmenty kodu z jednej bazy kodu i wdrażamy je oddzielnie. Ponieważ mikroserwis działa na innym serwerze, nie możemy już przywoływać adresów URL naszych usług w postaci ścieżek bezwzględnych. W takim przypadku musimy zastosować przekierowanie do nowego adresu serwera naszego mikroserwisu Order. Pamiętaj, że zaktualizowanie adresów URL każdej usługi monolitycznej będzie wymagało przerwy w działaniu usługi monolitycznej. Weź to pod uwagę, gdy planujesz przenoszenie mikroserwisów i monolitu do środowiska produkcyjnego w czasie migracji do mikroserwisów.

Musimy zaktualizować plik konfiguracyjny w monolicie, aby wskazywał nowy adres IP mikroserwisów Orders. W edytorze nano zastąp lokalny URL adresem IP naszego nowego mikroserwisu Orders. Uruchom to polecenie, 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

Zamień REACT_APP_ORDERS_URL na nowy format, 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 CTRL+O, naciśnij ENTER, a następnie CTRL+X, aby zapisać plik w edytorze nano.

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

Teraz musimy ponownie utworzyć frontend monolitu, powtórzyć proces kompilacji, aby utworzyć kontener dla monolitu, a następnie 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

Możesz sprawdzić, czy Twoja aplikacja łączy się teraz z nowym mikroserwisem Orders. W tym celu przejdź do 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

Mikroserwis tworzenia nowych produktów

Możemy nadal dzielić nasze usługi na kolejne usługi, przenosząc je w następnej kolejności. Zastosujemy taki sam proces 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 naszych usług w taki sam sposób jak w przypadku usługi Orders za pomocą następującego 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. Będzie on potrzebny w następnym kroku podczas ponownego konfigurowania naszego monolitu w taki sposób, aby wskazywał na nasz nowy mikroserwis Products.

Ponowne konfigurowanie monolitu

W edytorze nano zastąp lokalny URL adresem IP naszego 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

Zamień REACT_APP_PRODUCTS_URL na nowy format, 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 CTRL+O, naciśnij ENTER, a następnie CTRL+X, aby zapisać plik w edytorze nano.

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

Następnie musimy ponownie utworzyć frontend monolitu, powtórzyć proces kompilacji, aby utworzyć kontener dla monolitu, a następnie 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

Możesz sprawdzić, czy Twoja aplikacja łączy się teraz z nowym mikroserwisem Products, otwierając aplikację monolityczną w przeglądarce i przechodząc na stronę Products. Wszystkie nazwy produktów powinny mieć prefiks MS-, jak poniżej:

5389b29f4b8c7c69.png

8. Migracja 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, wykonaj te same czynności co w 2 ostatnich krokach.

Poprzednio podczas rekompilacji monolitu aktualizowaliśmy jego konfigurację tak, aby wskazywała na monolit, ale teraz musimy użyć tej samej konfiguracji dla naszego mikroserwisu frontendu. Uruchom następujące 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

Gdy to zrobisz, będziemy postępować tak samo jak w przypadku poprzednich kroków. 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 nasze 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. Uruchom następujące polecenia, aby usunąć monolit:

kubectl delete deployment monolith
kubectl delete service monolith

Sprawdzanie efektów pracy

Aby sprawdzić, czy wszystko działa, stary adres IP usługi monolitu nie powinien 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

Po określeniu zewnętrznego adresu IP mikroserwisu frontendu skopiuj adres IP. 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 być taka sama jak przed podzieleniem monolitu na mikroserwisy.

9. Czyszczenie

Najprostszym sposobem na usunięcie wszystkich wykonanych działań jest usunięcie projektu. Usunięcie projektu spowoduje usunięcie wszystkich zasobów utworzonych w ramach tego ćwiczenia z programowania, aby uniknąć nieoczekiwanych opłat cyklicznych. Wykonaj w Cloud Shell podane niżej polecenie, gdzie PROJECT_ID to pełny identyfikator projektu, a nie tylko jego nazwa.

gcloud projects delete [PROJECT_ID]

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

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 ćwiczeniami z programowania:

Dodatkowe materiały