Informacje o tym ćwiczeniu (w Codelabs)
1. Omówienie
W tym module przedstawiamy funkcje i możliwości zaprojektowane w celu usprawnienia procesu programowania dla inżynierów, których zadaniem jest tworzenie aplikacji w języku Python w skonteneryzowanym środowisku. Typowe tworzenie kontenerów wymaga, aby użytkownik znał szczegóły kontenerów i proces ich tworzenia. Poza tym deweloperzy zwykle muszą przerwać przepływ pracy, wychodząc z IDE, aby przetestować i debugować aplikacje w środowiskach zdalnych. Dzięki narzędziom i technologiom wspomnianym w tym samouczku deweloperzy mogą wydajnie pracować z aplikacjami skonteneryzowanymi bez opuszczania IDE.
Czego się nauczysz
W tym module nauczysz się, jak tworzyć aplikacje z wykorzystaniem kontenerów w GCP, takich jak:
- Tworzenie nowej aplikacji startowej w języku Python
- Omów proces programowania.
- Opracuj prostą usługę przechowywania CRUD
- Wdrażanie w GKE
- Debugowanie stanu błędu
- Wykorzystanie punktu przerwania / logów
- Wdrażanie zmian z powrotem w GKE
2. Konfiguracja i wymagania
Samodzielne konfigurowanie środowiska
- Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub wykorzystaj już istniejący. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.
- Nazwa projektu jest wyświetlaną nazwą uczestników tego projektu. To ciąg znaków, który nie jest używany przez interfejsy API Google. W każdej chwili możesz ją zmienić.
- Identyfikator projektu jest unikalny we wszystkich projektach Google Cloud i nie można go zmienić (po jego ustawieniu nie można go zmienić). Cloud Console automatycznie wygeneruje unikalny ciąg znaków. zwykle nieważne, co ona jest. W większości ćwiczeń z programowania konieczne jest odwołanie się do identyfikatora projektu (zwykle nazywa się on
PROJECT_ID
). Jeśli nie podoba Ci się wygenerowany identyfikator, możesz wygenerować kolejny losowy. Możesz też spróbować własnych sił i sprawdzić, czy jest dostępna. Potem nie będzie można go zmienić. Pozostanie ono przez czas trwania projektu. - Dostępna jest trzecia wartość, numer projektu, z którego korzystają niektóre interfejsy API. Więcej informacji o wszystkich 3 wartościach znajdziesz w dokumentacji.
- Następnie musisz włączyć płatności w Cloud Console, aby korzystać z zasobów Cloud/interfejsów API. Ukończenie tego ćwiczenia z programowania nie powinno kosztować zbyt wiele. Aby wyłączyć zasoby, aby nie naliczać opłat po zakończeniu tego samouczka, możesz usunąć utworzone zasoby lub cały projekt. Nowi użytkownicy Google Cloud mogą skorzystać z programu bezpłatnego okresu próbnego o wartości 300 USD.
Uruchom edytor Cloud Shell
Ten moduł został opracowany i przetestowany pod kątem użycia z edytorem Google Cloud Shell. Aby uzyskać dostęp do edytora:
- wejdź na stronę swojego projektu Google na https://console.cloud.google.com.
- W prawym górnym rogu kliknij ikonę edytora Cloud Shell.
- Na dole okna otworzy się nowy panel
- Kliknij przycisk Otwórz edytor
- Edytor otworzy się z eksploratorem po prawej stronie i edytorem w obszarze środkowym.
- Okienko terminala powinno być też dostępne u dołu ekranu
- Jeśli terminal NIE jest otwarty, użyj kombinacji klawiszy „Ctrl+”, aby otworzyć nowe okno terminala
Konfiguracja środowiska
W Cloud Shell ustaw identyfikator i numer projektu. Zapisz je jako zmienne PROJECT_ID
i PROJECT_ID
.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
--format='value(projectNumber)')
Udostępnij infrastrukturę używaną w tym module
W tym module wdrożysz kod w GKE i uzyskasz dostęp do danych przechowywanych w bazie danych Spanner. Jako IDE będziesz też używać stacji roboczych Cloud. Poniższy skrypt konfiguracji przygotowuje dla Ciebie tę infrastrukturę.
- Pobierz skrypt konfiguracji i uruchom go.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/python/setup_with_cw.sh
chmod +x setup_with_cw.sh
- Otwórz plik
setup_with_cw.sh
i zmień wartości haseł, które są obecnie ustawione na CHANGEME - Uruchom skrypt konfiguracji, aby utworzyć klaster GKE i bazę danych Spanner, których użyjesz w tym module
./setup_with_cw.sh &
Klaster Cloud Workstations
- Otwórz Cloud Workstations w konsoli Cloud. Poczekaj, aż klaster zmieni stan na
READY
.
Tworzenie konfiguracji stacji roboczych
- Jeśli sesja Cloud Shell została odłączona, kliknij „Połącz ponownie” a następnie uruchom polecenie wiersza poleceń gcloud, aby ustawić identyfikator projektu. Zanim uruchomisz polecenie, zastąp przykładowy identyfikator projektu poniżej identyfikatorem projektu qwiklabs.
gcloud config set project qwiklabs-gcp-project-id
- Pobierz i uruchom poniższy skrypt w terminalu, aby utworzyć konfigurację Cloud Workstations.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/python/workstation_config_setup.sh
chmod +x workstation_config_setup.sh
./workstation_config_setup.sh
- Sprawdź wyniki w sekcji Konfiguracje. Przejście w stan GOTOWY zajmie 2 minuty.
- Otwórz w konsoli Cloud Workstations i utwórz nową instancję.
- Zmień nazwę na
my-workstation
i wybierz istniejącą konfigurację:codeoss-python
.
- Sprawdź wyniki w sekcji Stacje robocze.
Uruchom stację roboczą
- Uruchom i uruchom stację roboczą. Uruchamianie stacji roboczej może potrwać kilka minut.
- Zezwalaj na pliki cookie innych firm, klikając ikonę na pasku adresu.
- Kliknij „Witryna nie działa?”.
- Kliknij przycisk „Zezwalaj na pliki cookie”.
- Po uruchomieniu stacji roboczej pojawi się okno Code OSS IDE. Kliknij „Oznacz jako gotowe”. na pierwszej stronie wprowadzającej do IDE stacji roboczej
3. Tworzenie nowej aplikacji startowej w języku Python
W tej sekcji utworzysz nową aplikację w języku Python.
- Otwórz nowy terminal.
- Utwórz nowy katalog i otwórz go jako obszar roboczy
mkdir music-service && cd music-service
code-oss-cloud-workstations -r --folder-uri="$PWD"
Jeśli widzisz ten komunikat, kliknij przycisk Zezwalaj, aby skopiować i wkleić do stacji roboczej.
- Utwórz plik o nazwie
requirements.txt
i skopiuj do niego tę zawartość
Flask
gunicorn
google-cloud-spanner
ptvsd==4.3.2
- Utwórz plik o nazwie
app.py
i wklej do niego ten kod
import os
from flask import Flask, request, jsonify
from google.cloud import spanner
app = Flask(__name__)
@app.route("/")
def hello_world():
message="Hello, World!"
return message
if __name__ == '__main__':
server_port = os.environ.get('PORT', '8080')
app.run(debug=False, port=server_port, host='0.0.0.0')
- Utwórz plik o nazwie
Dockerfile
i wklej do niego poniższy kod
FROM python:3.8
ARG FLASK_DEBUG=0
ENV FLASK_DEBUG=$FLASK_DEBUG
ENV FLASK_APP=app.py
WORKDIR /app
COPY requirements.txt .
RUN pip install --trusted-host pypi.python.org -r requirements.txt
COPY . .
ENTRYPOINT ["python3", "-m", "flask", "run", "--port=8080", "--host=0.0.0.0"]
Uwaga: FLASK_DEBUG=1 umożliwia automatyczne ponowne ładowanie zmian kodu w aplikacji w Pythonie na kolbę. Ten plik Dockerfile pozwala przekazać tę wartość jako argument kompilacji.
Generuj pliki manifestu
Wykonaj w terminalu to polecenie, aby wygenerować domyślny plik skaffold.yaml i deploy.yaml.
- Zainicjuj Skaffold za pomocą tego polecenia
skaffold init --generate-manifests
Gdy pojawi się prośba, użyj strzałek, aby poruszać kursorem, a spację, aby wybrać opcje.
Wybierz:
8080
za porty
, aby zapisać konfigurację.
Aktualizowanie konfiguracji Skaffold
- Zmień domyślną nazwę aplikacji
- Otwórz:
skaffold.yaml
- Wybierz nazwę obrazu, który jest obecnie ustawiony jako
dockerfile-image
- Kliknij prawym przyciskiem myszy i wybierz Zmień wszystkie wystąpienia
- Wpisz nową nazwę jako
python-app
- Zmodyfikuj sekcję kompilacji, tak aby była
- dodaj
docker.buildArgs
, aby wjechać do firmyFLASK_DEBUG=1
- Zsynchronizuj ustawienia, aby wczytać wszelkie zmiany w plikach
*.py
z IDE do uruchomionego kontenera
Po wprowadzeniu zmian sekcja kompilacji w pliku skaffold.yaml
będzie wyglądać tak:
build:
artifacts:
- image: python-app
docker:
buildArgs:
FLASK_DEBUG: "1"
dockerfile: Dockerfile
sync:
infer:
- '**/*.py'
Zmodyfikuj plik konfiguracji Kubernetes
- Zmiana nazwy domyślnej
- Otwórz plik
deployment.yaml
- Wybierz nazwę obrazu, który jest obecnie ustawiony jako
dockerfile-image
- Kliknij prawym przyciskiem myszy i wybierz Zmień wszystkie wystąpienia
- Wpisz nową nazwę jako
python-app
4. Omówienie procesu programowania
Dzięki dodanej logice biznesowej możesz teraz wdrożyć i przetestować aplikację. W następnej sekcji dowiesz się, jak korzystać z wtyczki Cloud Code. Integruje się ona między innymi ze skaffold, aby usprawnić proces programowania. Gdy wdrożysz obraz kontenera w GKE za pomocą poniższych kroków, Cloud Code i Skaffold automatycznie skompilują obraz kontenera, wypchnie go do Container Registry, a następnie wdroży aplikację your
w GKE. Dzieje się to za kulisami, odbierając szczegóły od procesu deweloperskiego.
Logowanie się do Google Cloud
- Kliknij ikonę Cloud Code i wybierz opcję „Sign in to Google Cloud” (Zaloguj się w Google Cloud):
- Kliknij „Przejdź do logowania”.
- Sprawdź dane wyjściowe w terminalu i otwórz link:
- Zaloguj się danymi logowania uczniów Qwiklabs.
- Wybierz „Zezwól”:
- Skopiuj kod weryfikacyjny i wróć na kartę Workstations.
- Wklej kod weryfikacyjny i naciśnij Enter.
Dodaj klaster Kubernetes
- Dodaj klaster
- Wybierz Google Kubernetes Engine:
- Wybierz projekt.
- Wybierz „python-cluster” utworzony podczas początkowej konfiguracji.
- Klaster pojawi się na liście klastrów Kubernetes w sekcji Cloud Code. Tutaj możesz poruszać się po klastrze i go poznawać.
Ustaw identyfikator bieżącego projektu za pomocą wiersza poleceń gcloud
- Skopiuj identyfikator projektu powiązany z tym modułem ze strony qwiklabs.
- W terminalu uruchom polecenie interfejsu wiersza poleceń gcloud, aby ustawić identyfikator projektu. Zastąp przykładowy identyfikator projektu przed uruchomieniem polecenia. Zanim wykonasz poniższe polecenie, ZASTĄP identyfikator projektu.
gcloud config set project qwiklabs-gcp-project-id
Wdróż w Kubernetes
- W panelu u dołu edytora Cloud Shell wybierz Cloud Code .
- W panelu, który pojawi się u góry, kliknij Uruchom w Kubernetes. W razie potrzeby wybierz Tak, aby użyć bieżącego kontekstu Kubernetes.
To polecenie uruchamia kompilację kodu źródłowego, a następnie uruchamia testy. Kompilacja i testy potrwają kilka minut. Te testy obejmują testy jednostkowe oraz etap weryfikacji, który sprawdza reguły ustawione dla środowiska wdrożenia. Ten etap weryfikacji jest już skonfigurowany i dzięki temu ostrzeżemy Cię o problemach z wdrożeniem, nawet jeśli nadal pracujesz w środowisku programistycznym.
- Przy pierwszym uruchomieniu polecenia u góry ekranu pojawi się prompt z pytaniem, czy chcesz uzyskać bieżący kontekst Kubernetes. Wybierz „Tak”. aby zaakceptować i wykorzystać bieżący kontekst.
- Pojawi się pytanie, którego rejestru kontenerów użyć. Naciśnij Enter, aby zaakceptować podaną wartość domyślną
- Wybierz „Dane wyjściowe”. w panelu u dołu, aby wyświetlić postęp i powiadomienia. Za pomocą menu wybierz „Kubernetes: Run/Debug”.
- Wybierz „Kubernetes: Run/Debug - detail”. w menu kanału po prawej stronie, aby wyświetlić dodatkowe szczegóły i logi, które są przesyłane na żywo z kontenerów.
Po zakończeniu kompilacji i testów w dziennikach karty Dane wyjściowe w sekcji „Kubernetes: Run/Debug” pojawi się adres URL http://localhost: 8080 widok.
- W terminalu Cloud Code najedź kursorem na pierwszy adres URL w danych wyjściowych (http://localhost:8080), a następnie w wyświetlonej wskazówce narzędzia wybierz Otwórz podgląd w przeglądarce.
- Otworzy się nowa karta przeglądarki i wyświetli się na niej wiadomość:
Hello, World!
Ponowne załadowanie „na gorąco”
- Otwórz plik
app.py
. - Zmień wiadomość powitalną na
Hello from Python
Od razu zauważysz, że w oknie Output
, widoku Kubernetes: Run/Debug
obserwator synchronizuje zaktualizowane pliki z kontenerem w Kubernetes.
Update initiated Build started for artifact python-app Build completed for artifact python-app Deploy started Deploy completed Status check started Resource pod/python-app-6f646ffcbb-tn7qd status updated to In Progress Resource deployment/python-app status updated to In Progress Resource deployment/python-app status completed successfully Status check succeeded ...
- Jeśli przełączysz się na widok
Kubernetes: Run/Debug - Detailed
, zauważysz, że rozpoznaje zmiany w plikach, a następnie skompiluje i ponownie wdroży aplikację
files modified: [app.py]
Syncing 1 files for gcr.io/veer-pylab-01/python-app:3c04f58-dirty@sha256:a42ca7250851c2f2570ff05209f108c5491d13d2b453bb9608c7b4af511109bd
Copying files:map[app.py:[/app/app.py]]togcr.io/veer-pylab-01/python-app:3c04f58-dirty@sha256:a42ca7250851c2f2570ff05209f108c5491d13d2b453bb9608c7b4af511109bd
Watching for changes...
[python-app] * Detected change in '/app/app.py', reloading
[python-app] * Restarting with stat
[python-app] * Debugger is active!
[python-app] * Debugger PIN: 744-729-662
- Aby zobaczyć zaktualizowane wyniki, odśwież kartę przeglądarki, w której były poprzednie wyniki.
Debugowanie
- Otwórz widok debugowania i zatrzymaj bieżący wątek
. Jeśli pojawi się prośba, możesz wyczyścić dane po każdym uruchomieniu.
- Kliknij
Cloud Code
w dolnym menu i wybierzDebug on Kubernetes
, aby uruchomić aplikację w trybiedebug
.
- W widoku
Kubernetes Run/Debug - Detailed
oknaOutput
zwróć uwagę, że skaffold wdroży tę aplikację w trybie debugowania.
- Po zakończeniu procesu. Dołączenie debugera to:
Attached debugger to container "python-app-8476f4bbc-h6dsl" successfully.
, na karcie Wyniki są wyświetlany adres URL http://localhost:8080.
Port forwarding pod/python-app-8bd64cf8b-cskfl in namespace default, remote port 5678 -> http://127.0.0.1:5678
- Kolor dolnego paska stanu zmieni się z niebieskiego na pomarańczowy, co oznacza, że urządzenie działa w trybie debugowania.
- Zwróć uwagę na to, że w widoku
Kubernetes Run/Debug
został uruchomiony kontener z możliwością debugowania.
**************URLs***************** Forwarded URL from service python-app: http://localhost:8080 Debuggable container started pod/python-app-8bd64cf8b-cskfl:python-app (default) Update succeeded ***********************************
Wykorzystuj punkty przerwania
- Otwórz plik
app.py
. - Znajdź instrukcję, która brzmi:
return message
- Dodaj do tego wiersza punkt przerwania, klikając puste miejsce po lewej stronie numeru wiersza. Pojawi się czerwony wskaźnik informujący o ustawieniu punktu przerwania
- Przy pierwszym uruchomieniu pojawi się pytanie, gdzie w kontenerze znajduje się źródło. Ta wartość jest powiązana z katalogami w pliku Dockerfile.
Naciśnij Enter, aby zaakceptować domyślną wartość
Skompilowanie i wdrożenie aplikacji zajmie kilka minut.
- Załaduj ponownie przeglądarkę. Pamiętaj, że debuger zatrzymuje proces w punkcie przerwania i umożliwia zbadanie zmiennych oraz stanu aplikacji uruchomionej zdalnie w GKE.
- Kliknij w dół do sekcji ZMIENNE
- Kliknij przycisk Lokalne. Znajdziesz tam zmienną
"message"
. - Kliknij dwukrotnie zmienną o nazwie „wiadomość”. i w wyskakującym okienku zmień wartość na inną, np.
"Greetings from Python"
. - Kliknij przycisk Dalej w panelu sterowania debugowania
.
- Sprawdź odpowiedź w przeglądarce, w której wyświetla się wprowadzona przed chwilą zaktualizowana wartość.
- Zatrzymaj „Debugowanie” naciśnij przycisk zatrzymania
i usuń punkt przerwania, ponownie klikając go.
5. Opracowanie usługi spoczynku CRUD
Na tym etapie Twoja aplikacja jest w pełni skonfigurowana do programowania skonteneryzowanego i masz już za sobą podstawowy przepływ pracy programistyczny w Cloud Code. W kolejnych sekcjach przećwiczysz zdobyte informacje, dodając punkty końcowe usługi spoczynkowej łączące się z zarządzaną bazą danych w Google Cloud.
Zakoduj resztę usługi
Poniższy kod tworzy prostą usługę spoczynku, która używa Spannera jako bazy danych jako kopii zapasowej aplikacji. Utwórz aplikację, kopiując do niej poniższy kod.
- Utwórz główną aplikację, zastępując fragment
app.py
następującą treścią:
import os
from flask import Flask, request, jsonify
from google.cloud import spanner
app = Flask(__name__)
instance_id = "music-catalog"
database_id = "musicians"
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
@app.route('/singer', methods=['POST'])
def create():
try:
request_json = request.get_json()
singer_id = request_json['singer_id']
first_name = request_json['first_name']
last_name = request_json['last_name']
def insert_singers(transaction):
row_ct = transaction.execute_update(
f"INSERT Singers (SingerId, FirstName, LastName) VALUES" \
f"({singer_id}, '{first_name}', '{last_name}')"
)
print("{} record(s) inserted.".format(row_ct))
database.run_in_transaction(insert_singers)
return {"Success": True}, 200
except Exception as e:
return e
@app.route('/singer', methods=['GET'])
def get_singer():
try:
singer_id = request.args.get('singer_id')
def get_singer():
first_name = ''
last_name = ''
with database.snapshot() as snapshot:
results = snapshot.execute_sql(
f"SELECT SingerId, FirstName, LastName FROM Singers " \
f"where SingerId = {singer_id}",
)
for row in results:
first_name = row[1]
last_name = row[2]
return (first_name,last_name )
first_name, last_name = get_singer()
return {"first_name": first_name, "last_name": last_name }, 200
except Exception as e:
return e
@app.route('/singer', methods=['PUT'])
def update_singer_first_name():
try:
singer_id = request.args.get('singer_id')
request_json = request.get_json()
first_name = request_json['first_name']
def update_singer(transaction):
row_ct = transaction.execute_update(
f"UPDATE Singers SET FirstName = '{first_name}' WHERE SingerId = {singer_id}"
)
print("{} record(s) updated.".format(row_ct))
database.run_in_transaction(update_singer)
return {"Success": True}, 200
except Exception as e:
return e
@app.route('/singer', methods=['DELETE'])
def delete_singer():
try:
singer_id = request.args.get('singer')
def delete_singer(transaction):
row_ct = transaction.execute_update(
f"DELETE FROM Singers WHERE SingerId = {singer_id}"
)
print("{} record(s) deleted.".format(row_ct))
database.run_in_transaction(delete_singer)
return {"Success": True}, 200
except Exception as e:
return e
port = int(os.environ.get('PORT', 8080))
if __name__ == '__main__':
app.run(threaded=True, host='0.0.0.0', port=port)
Dodaj konfiguracje bazy danych
Aby połączyć się z usługą Spanner w bezpieczny sposób, skonfiguruj aplikację pod kątem korzystania z tożsamości zadań. Dzięki temu aplikacja może działać jako własne konto usługi i mieć indywidualne uprawnienia podczas uzyskiwania dostępu do bazy danych.
- Zaktualizuj urządzenie
deployment.yaml
. Dodaj następujący kod na końcu pliku (pamiętaj, aby zachować wcięcia tabulacji w przykładzie poniżej)
serviceAccountName: python-ksa
nodeSelector:
iam.gke.io/gke-metadata-server-enabled: "true"
Po wprowadzeniu zmian sekcja specyfikacji powinna wyglądać tak
spec: containers: - name: python-app image: python-app serviceAccountName: python-ksa nodeSelector: iam.gke.io/gke-metadata-server-enabled: "true"
Wdróż i zweryfikuj aplikację
- W panelu u dołu edytora Cloud Shell kliknij
Cloud Code
, a następnie wybierzDebug on Kubernetes
u góry ekranu. - Po zakończeniu kompilacji i testów na karcie Dane wyjściowe pojawi się komunikat
Resource deployment/python-app status completed successfully
i wyświetli się adres URL: „Przekierowany adres URL z usługi python-app: http://localhost:8080” - Dodaj kilka wpisów.
W terminalu Cloud Shell uruchom poniższe polecenie
curl -X POST http://localhost:8080/singer -H 'Content-Type: application/json' -d '{"first_name":"Cat","last_name":"Meow", "singer_id": 6}'
- Przetestuj metodę GET, uruchamiając poniższe polecenie w terminalu
curl -X GET http://localhost:8080/singer?singer_id=6
- Testowanie usuwania: teraz spróbuj usunąć wpis, uruchamiając następujące polecenie. W razie potrzeby zmień wartość parametru item-id.
curl -X DELETE http://localhost:8080/singer?singer_id=6
This throws an error message
500 Internal Server Error
Zidentyfikuj i rozwiąż problem
- Włącz tryb debugowania i znajdź problem. Oto kilka porad:
- Wiemy, że coś jest nie tak z funkcją DELETE, ponieważ nie zwraca ona oczekiwanych wyników. Punkt przerwania należy więc ustawić w metodzie
delete_singer
w metodzieapp.py
. - Uruchom wykonanie krok po kroku i obserwuj zmienne w każdym kroku, aby obserwować wartości zmiennych lokalnych w lewym oknie.
- Aby obserwować określone wartości, takie jak
singer_id
irequest.args
, dodaj te zmienne do okna odtwarzania filmu.
- Zwróć uwagę, że atrybut
singer_id
ma wartośćNone
. Zmień kod, aby rozwiązać problem.
Poprawiony fragment kodu będzie wyglądać tak.
@app.route('/delete-singer', methods=['DELETE', 'GET']) def delete_singer(): try: singer_id = request.args.get('singer_id')
- Po ponownym uruchomieniu aplikacji przetestuj ją jeszcze raz, próbując ją usunąć.
- Zatrzymaj sesję debugowania, klikając czerwony kwadrat
na pasku narzędzi debugowania
6. Czyszczenie
Gratulacje! W tym module udało Ci się utworzyć od zera nową aplikację w Pythonie i skonfigurować ją tak, aby wydajnie współpracowała z kontenerami. Następnie wdrożono i debugowałeś(-aś) aplikację w zdalnym klastrze GKE, postępując zgodnie z procedurą programistyczną obowiązującą w tradycyjnych stosach aplikacji.
Aby posprzątać po ukończeniu modułu:
- Usuń pliki używane w module
cd ~ && rm -rf ~/music-service
- Usuń projekt, aby usunąć całą powiązaną infrastrukturę i zasoby