1. Omówienie
W tym module prezentowane są funkcje i możliwości zaprojektowane w celu usprawnienia przepływu pracy programistów, których zadaniem jest tworzenie aplikacji NodeJS w środowisku skonteneryzowanym. 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 startowej aplikacji Nodejs
- Konfigurowanie aplikacji Nodejs na potrzeby tworzenia kontenerów
- Kodowanie prostego kodu CRUD Rest Service
- Wdrażanie w GKE
- Debugowanie stanu błędu
- Wykorzystanie punktu przerwania / logów
- Wdrażanie zmian z powrotem w GKE
- Opcjonalnie: integrowanie Cloud SQL w celu zapewnienia trwałości backendu
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 i w każdej chwili możesz go zaktualizować.
- Identyfikator projektu musi być unikalny we wszystkich projektach Google Cloud i nie można go zmienić (nie można go zmienić po ustawieniu). Cloud Console automatycznie wygeneruje unikalny ciąg znaków. zwykle nieważne, co ona jest. W większości ćwiczeń w Codelabs musisz odwoływać się do identyfikatora projektu (który zwykle nazywa się
PROJECT_ID
), więc jeśli Ci się nie podoba, wygeneruj kolejny losowy projekt lub wypróbuj swój własny identyfikator i sprawdź, czy jest dostępny. Potem urządzenie jest „zawieszone”. po utworzeniu projektu. - Występuje trzecia wartość – numer projektu – używany przez niektóre interfejsy API. Więcej informacji o wszystkich 3 wartościach znajdziesz w dokumentacji.
- Następnie musisz włączyć płatności w konsoli Cloud, aby móc korzystać z zasobów i interfejsów API Cloud. 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, wykonaj czynności „wyczyść” znajdziesz na końcu tego ćwiczenia. 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
Konfigurowanie gcloud
W Cloud Shell ustaw identyfikator projektu i region, w którym chcesz wdrożyć aplikację. Zapisz je jako zmienne PROJECT_ID
i REGION
.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
Skonfiguruj klaster i bazę danych GKE
- Pobierz skrypt konfiguracji i uruchom go.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/nodejs/setup.sh
chmod +x setup.sh
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. Poniższy skrypt konfiguracji przygotowuje dla Ciebie tę infrastrukturę.
- Otwórz plik
setup.sh
i zmień wartości haseł, które są obecnie ustawione na CHANGEME - Uruchom skrypt konfiguracji, aby utworzyć klaster GKE i bazę danych Cloud SQL, których użyjesz w tym module
./setup.sh
- W Cloud Shell utwórz nowy katalog o nazwie
mynodejsapp
mkdir mynodejsapp
- Przejdź do tego katalogu i otwórz go jako obszar roboczy. Spowoduje to ponowne załadowanie edytora przez utworzenie konfiguracji obszaru roboczego w nowo utworzonym folderze.
cd mynodejsapp && cloudshell workspace .
- Zainstaluj Node i NPM za pomocą NVM.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
# This loads nvm bash_completion
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
nvm install stable
nvm alias default stable
3. Utwórz nową aplikację startową
- Zainicjowanie aplikacji
Tworzę plik package.json
, uruchamiając następujące polecenie
npm init
Choose the entry point: (index.js) src/index.js and default values for the rest of the parameters. This will create the file with following contents
{ "name": "mynodejsapp", "version": "1.0.0", "description": "", "main": "src/index.js",, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
- Dodawanie punktu wejścia
Edytuj ten plik, aby uwzględnić polecenie start w skrypcie "start": "node src/index.js",
. Po zmianie skrypty powinny wyglądać tak, jak pokazano poniżej:
"scripts": {
"start": "node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
- Dodaj zależność ekspresową
Kod, który dodamy, również korzysta z zależności express
, więc dodajmy tę zależność do tego pliku package.json
. Po wszystkich zmianach plik package.json
powinien wyglądać tak jak poniżej.
{ "name": "mynodejsapp", "version": "1.0.0", "description": "", "main": "src/index.js", "scripts": { "start": "node src/index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Your Name", "license": "ISC", "dependencies": { "express": "^4.16.4" } }
- Tworzenie pliku index.js
Utwórz katalog źródłowy o nazwie src.
Utwórz plik src/index.js z tym kodem
const express = require('express');
const app = express();
const PORT = 8080;
app.get('/', (req, res) => {
var message="Greetings from Node";
res.send({ message: message });
});
app.listen(PORT, () => {
console.log(`Server running at: http://localhost:${PORT}/`);
});
Zwróć uwagę, że port ma wartość 8080
Generuj pliki manifestu
Skaffold udostępnia zintegrowane narzędzia, które upraszczają tworzenie kontenerów. W tym kroku zainicjujesz skaffold, który automatycznie utworzy podstawowe pliki YAML Kubernetes. Aby rozpocząć proces, wykonaj poniższe polecenie.
Wykonaj w terminalu to polecenie
skaffold init --generate-manifests
Gdy pojawi się komunikat:
- Wpisz 8080 jako numer portu
- Wpisz y, aby zapisać konfigurację.
Do obszaru roboczego zostaną dodane 2 pliki: skaffold.yaml
i deployment.yaml
Zaktualizuj nazwę aplikacji
Domyślne wartości uwzględnione w konfiguracji nie są obecnie zgodne z nazwą Twojej aplikacji. Zaktualizuj pliki, aby odwoływały się do nazwy aplikacji zamiast do wartości domyślnych.
- Zmień wpisy w konfiguracji Skaffold
- Otwórz:
skaffold.yaml
- Wybierz nazwę obrazu, który jest obecnie ustawiony jako
package-json-image
- Kliknij prawym przyciskiem myszy i wybierz Zmień wszystkie wystąpienia
- Wpisz nową nazwę jako
mynodejsapp
- Zmień wpisy w konfiguracji Kubernetes
- Otwórz plik
deployment.yaml
- Wybierz nazwę obrazu, który jest obecnie ustawiony jako
package-json-image
- Kliknij prawym przyciskiem myszy i wybierz Zmień wszystkie wystąpienia
- Wpisz nową nazwę jako
mynodejsapp
Zwróć uwagę, że w pliku skaffold.yaml
sekcja build
używa buildpacks
do skonteneryzowania aplikacji. Ten kod nie zawiera pliku Dockerfile, a deweloper nie potrzebuje dockera, aby skonteneryzować tę aplikację.
Ta konfiguracja skaffold włącza też automatycznie synchronizację na gorąco między edytorem a uruchomionym kontenerem. Włączenie synchronizacji „na gorąco” nie wymaga dodatkowej konfiguracji.
4. Omówienie procesu programowania
W tej sekcji zapoznasz się z kilkoma krokami korzystania z wtyczki Cloud Code, które pozwolą Ci poznać podstawowe procesy i sprawdzić konfigurację oraz konfigurację aplikacji startowej.
Cloud Code integruje się ze skaffold, aby usprawnić proces programowania. Gdy wdrożysz obraz kontenera w GKE w poniższych krokach, Cloud Code i Skaffold automatycznie skompilują obraz kontenera, wypchnie go do Container Registry, a następnie wdroży aplikację w GKE. Dzieje się to za kulisami, odbierając szczegóły od procesu deweloperskiego. Cloud Code usprawnia też proces programowania, udostępniając tradycyjne funkcje debugowania i synchronizacji przy użyciu kontenerów podczas programowania.
Wdróż w Kubernetes
- W panelu u dołu edytora Cloud Shell wybierz Cloud Code .
- W panelu, który się pojawi, kliknij Uruchom w Kubernetes. W razie potrzeby wybierz Tak, aby użyć bieżącego kontekstu Kubernetes.
- 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 kartę Wyniki w dolnym panelu, aby zobaczyć postęp i powiadomienia.
- 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.
- Wróć do widoku uproszczonego, wybierając „Kubernetes: Run/Debug”. z menu
- Po zakończeniu kompilacji i testów na karcie Dane wyjściowe będzie widoczny komunikat
Resource deployment/mynodejsapp status completed successfully
oraz adres URL: „Przekierowany adres URL z aplikacji demonstracyjnej usługi: http://localhost:8080”. - W terminalu Cloud Code najedź kursorem na 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.
Odpowiedź będzie:
{"message":"Greetings from Node"}
Ponowne załadowanie „na gorąco”
- Wejdź na
src/index.js
. Zmień kod wiadomości powitalnej na'Hello from Node'
Od razu zauważysz, że w oknie Output
, widoku Kubernetes: Run/Debug
obserwator synchronizuje zaktualizowane pliki z kontenerem w Kubernetes.
Update initiated File sync started for 1 files for gcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a File sync succeeded for 1 files for gcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a Update succeeded
- Jeśli przełączysz się na widok
Kubernetes: Run/Debug - Detailed
, zauważysz, że rozpozna on zmiany w plikach i ponownie uruchomi węzeł
files modified: [src/index.js] Copying files:map[src/index.js:[/workspace/src/index.js]]togcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a Syncing 1 files for gcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a Watching for changes... [mynodejsapp] [mynodejsapp]> mynodejsapp@1.0.0 start /workspace [mynodejsapp]> node src/index.js [mynodejsapp] [mynodejsapp]Server running at: http://localhost:8080/
- Aby zobaczyć zaktualizowane wyniki, odśwież przeglądarkę.
Debugowanie
- Otwórz widok debugowania i zatrzymaj bieżący wątek
.
- 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. - Skompilowanie i wdrożenie aplikacji może potrwać kilka minut. Tym razem będziesz mieć włączony debuger.
Port forwarding pod/mynodejsapp-6bbcf847cd-vqr6v in namespace default, remote port 9229 -> http://127.0.0.1:9229 [mynodejsapp]Debugger attached.
- 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 mynodejsapp-service: http://localhost:8080 Debuggable container started pod/mynodejsapp-deployment-6bc7598798-xl9kj:mynodejsapp (default) Update succeeded ***********************************
Wykorzystuj punkty przerwania
- Otwórz:
src/index.js
- Znajdź instrukcję, która brzmi:
var message="Greetings from Node";
- 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
- 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.
- Przejdź do sekcji zmiennych, aż znajdziesz zmienną
"message"
. - Wykonaj linię, naciskając przycisk Przejdź nad
- Obserwuj bieżącą zmianę zmiennej
"message"
na"Greetings from Node"
- Kliknij dwukrotnie zmienną o nazwie „target”. i w wyskakującym okienku zmień wartość na inną, np.
"Hello from Node"
. - 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 prostej usługi CRUD Rest Service
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.
Skonfiguruj zależności
Kod aplikacji używa bazy danych do utrwalania danych usługi reszty. Zapewnij dostępność zależności, dodając w pliku package.json
ten kod
- Dodaj jeszcze 2 zależności
pg
isequelize
do plikupackage.json
, aby utworzyć aplikację CRUD Postgres. Po wprowadzeniu zmian sekcja zależności będzie wyglądać tak.
"dependencies": {
"express": "^4.16.4",
"pg": "^8.7.3",
"sequelize": "^6.17.0"
}
Kodowanie usługi REST
- Dodaj kod CRUD do tej aplikacji
wget -O app.zip https://github.com/GoogleCloudPlatform/container-developer-workshop/raw/main/labs/nodejs/app.zip
unzip app.zip
Ten kod zawiera
- Folder models z modelem encji
item
- folder controllers z kodem, który wykonuje operacje CRUD
- trasuje folder, który kieruje określone wzorce adresów URL do różnych wywołań.
- folder config ze szczegółami połączenia z bazą danych
- Pamiętaj, że konfiguracja bazy danych w pliku
db.config.js
odnosi się do zmiennych środowiskowych, które muszą być podane, aby możliwe było połączenie z bazą danych. Musisz również przeanalizować przychodzące żądanie dotyczące kodowania adresów URL. - Dodaj w polu
src/index.js
ten fragment kodu, aby utworzyć połączenie z kodem CRUD z głównego pliku JavaScript tuż przed ostatnią sekcją, która zaczyna się odapp.listen(PORT, () => {
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(
bodyParser.urlencoded({
extended: true,
})
)
const db = require("../app/models");
db.sequelize.sync();
require("../app/routes/item.routes")(app);
- Zmodyfikuj wdrożenie w pliku
deployment.yaml
, aby dodać zmienne środowiskowe służące do dostarczania informacji o połączeniach z bazą danych.
Zaktualizuj wpis specyfikacji na końcu pliku, aby był zgodny z tą definicją
spec:
containers:
- name: mynodejsapp
image: mynodejsapp
env:
- name: DB_HOST
value: ${DB_INSTANCE_IP}
- name: DB_PORT
value: "5432"
- name: DB_USER
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: username
- name: DB_PASS
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: password
- name: DB_NAME
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: database
- Zastąp wartość DB_HOST adresem swojej bazy danych
export DB_INSTANCE_IP=$(gcloud sql instances describe mytest-instance \
--format=json | jq \
--raw-output ".ipAddresses[].ipAddress")
envsubst < deployment.yaml > deployment.new && mv deployment.new deployment.yaml
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 będzie widoczny komunikat
Resource deployment/mynodejsapp status completed successfully
oraz adres URL: „Przekierowany adres URL z usługi mynodejsapp: http://localhost:8080”. - Dodaj kilka elementów.
W terminalu Cloud Shell uruchom poniższe polecenia
URL=localhost:8080
curl -X POST $URL/items -d '{"itemName":"Body Spray", "itemPrice":3.2}' -H "Content-Type: application/json"
curl -X POST $URL/items -d '{"itemName":"Nail Cutter", "itemPrice":2.5}' -H "Content-Type: application/json"
- Przetestuj metodę GET, uruchamiając w przeglądarce parametr $URL/items. Możesz też uruchomić curl z wiersza poleceń
curl -X GET $URL/items
- Testowanie usuwania: teraz spróbuj usunąć element poprzez jego uruchomienie. W razie potrzeby zmień wartość parametru item-id.
curl -X DELETE $URL/items/1
This throws an error message
{"message":"Could not delete Item with id=[object Object]"}
Zidentyfikuj i rozwiąż problem
- Uruchom aplikację ponownie w trybie 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 ustawia się więc w metodzie
itemcontroller.js
->exports.delete
. - 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
request.params
, dodaj tę zmienną do okna odtwarzania filmu.
- Zwróć uwagę, że atrybut
id
ma wartośćundefined
. Zmień kod, aby rozwiązać problem.
Poprawiony fragment kodu będzie wyglądać tak.
// Delete a Item with the specified id in the request exports.delete = (req, res) => { const id = req.params.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ę Nodejs i skonfigurować ją do pracy w trybie wdrażania „gorące” 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 mynodejsapp && rm -f setup.sh
- Usuń projekt, aby usunąć całą powiązaną infrastrukturę i zasoby