1. Przegląd
W tym module poznasz funkcje i możliwości, które usprawniają proces tworzenia aplikacji w środowisku skonteneryzowanym dla inżynierów oprogramowania zajmujących się opracowywaniem aplikacji w NodeJS. Typowe tworzenie kontenerów wymaga od użytkownika znajomości szczegółów dotyczących kontenerów i procesu kompilacji kontenerów. Deweloperzy zwykle muszą też przerywać pracę i opuszczać IDE, aby testować i debugować aplikacje w środowiskach zdalnych. Dzięki narzędziom i technologiom wymienionym w tym samouczku deweloperzy mogą efektywnie pracować z aplikacjami w kontenerach bez opuszczania środowiska IDE.
Czego się nauczysz
W tym module poznasz metody tworzenia aplikacji w kontenerach w GCP, w tym:
- Tworzenie aplikacji startowej w Node.js
- Konfigurowanie aplikacji Node.js na potrzeby tworzenia kontenerów
- Kodowanie prostej usługi REST CRUD
- Wdrażanie w GKE
- Debugowanie stanu błędu
- Korzystanie z punktu przerwania lub logów
- Szybkie wdrażanie zmian z powrotem w GKE
- Opcjonalnie: integracja CloudSQL na potrzeby trwałości backendu
2. Konfiguracja i wymagania
Samodzielne konfigurowanie środowiska
- Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub użyj istniejącego. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.



- Nazwa projektu to wyświetlana nazwa uczestników tego projektu. Jest to ciąg znaków, który nie jest używany przez interfejsy API Google. Możesz go w dowolnym momencie zaktualizować.
- Identyfikator projektu musi być unikalny we wszystkich projektach Google Cloud i jest niezmienny (nie można go zmienić po ustawieniu). Konsola Cloud automatycznie generuje unikalny ciąg znaków. Zwykle nie musisz się nim przejmować. W większości modułów z kodem musisz odwoływać się do identyfikatora projektu (zwykle oznaczanego jako
PROJECT_ID). Jeśli Ci się nie podoba, wygeneruj inny losowy identyfikator lub spróbuj użyć własnego i sprawdź, czy jest dostępny. Po utworzeniu projektu jest on „zamrażany”. - Istnieje też trzecia wartość, czyli numer projektu, którego używają niektóre interfejsy API. Więcej informacji o tych 3 wartościach znajdziesz w dokumentacji.
- Następnie musisz włączyć płatności w konsoli Cloud, aby korzystać z zasobów i interfejsów API Google Cloud. Ukończenie tego laboratorium nie powinno wiązać się z dużymi kosztami, a nawet z żadnymi. Aby wyłączyć zasoby i uniknąć naliczenia opłat po zakończeniu tego samouczka, postępuj zgodnie z instrukcjami „czyszczenia” na końcu ćwiczenia. Nowi użytkownicy Google Cloud mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.
Uruchamianie edytora Cloud Shell
To laboratorium zostało zaprojektowane i przetestowane pod kątem używania w edytorze Google Cloud Shell. Aby uzyskać dostęp do edytora:
- uzyskać dostęp do projektu Google na stronie https://console.cloud.google.com;
- W prawym górnym rogu kliknij ikonę edytora Cloud Shell.

- U dołu okna otworzy się nowy panel.
- Kliknij przycisk Otwórz edytor.

- Edytor otworzy się z eksploratorem po prawej stronie i edytorem w środkowej części.
- U dołu ekranu powinien być też dostępny panel terminala.
- 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)')
Konfigurowanie klastra GKE i bazy danych
- Pobierz skrypt konfiguracji i ustaw go jako wykonywalny.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/nodejs/setup.sh
chmod +x setup.sh
wdrożyć 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 przygotuje tę infrastrukturę.
- Otwórz plik
setup.shi edytuj wartości haseł, które są obecnie ustawione na CHANGEME. - Uruchom skrypt konfiguracyjny, aby utworzyć klaster GKE i bazę danych Cloud SQL, które będą używane w tym laboratorium.
./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 wczytanie 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. Tworzenie nowej aplikacji startowej
- Inicjowanie aplikacji
Utwórz plik package.json, uruchamiając to 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 dodać polecenie startowe do skryptu "start": "node src/index.js",. Po zmianie skrypty powinny wyglądać jak fragment kodu poniżej:
"scripts": {
"start": "node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
- Dodaj zależność Express
Dodawany przez nas kod również korzysta z express, więc dodajmy tę zależność do pliku package.json. Po wprowadzeniu wszystkich zmian 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.
Generowanie manifestów
Skaffold udostępnia zintegrowane narzędzia, które upraszczają tworzenie kontenerów. W tym kroku zainicjujesz narzędzie Skaffold, które automatycznie utworzy podstawowe pliki YAML Kubernetes. Aby rozpocząć proces, wykonaj polecenie poniżej.
W terminalu wykonaj to polecenie:
skaffold init --generate-manifests
Gdy pojawi się odpowiedni komunikat:
- Wpisz 8080 jako port.
- Wpisz y, aby zapisać konfigurację.
Do obszaru roboczego zostaną dodane 2 pliki: skaffold.yaml i deployment.yaml.
Aktualizowanie nazwy aplikacji
Wartości domyślne uwzględnione w konfiguracji nie pasują obecnie do nazwy aplikacji. Zaktualizuj pliki, aby odwoływały się do nazwy aplikacji, a nie do wartości domyślnych.
- Zmiana wpisów w konfiguracji Skaffold
- Otwórz:
skaffold.yaml - Wybierz nazwę obrazu, która jest obecnie ustawiona jako
package-json-image. - Kliknij prawym przyciskiem myszy i wybierz Zmień wszystkie wystąpienia.
- Wpisz nową nazwę w formacie
mynodejsapp.
- Zmiana wpisów w konfiguracji Kubernetes
- Otwórz plik
deployment.yaml - Wybierz nazwę obrazu, która jest obecnie ustawiona jako
package-json-image. - Kliknij prawym przyciskiem myszy i wybierz Zmień wszystkie wystąpienia.
- Wpisz nową nazwę w formacie
mynodejsapp.
Zwróć uwagę, że w pliku skaffold.yaml sekcja build używa buildpacks do umieszczania aplikacji w kontenerze. Ten kod nie ma pliku Dockerfile, a deweloper nie musi znać Dockera, aby umieścić tę aplikację w kontenerze.
Ta konfiguracja Skaffold automatycznie włącza też szybką synchronizację między edytorem a działającym kontenerem. Aby włączyć szybką synchronizację, nie musisz niczego dodatkowo konfigurować.
4. Omówienie procesu tworzenia
W tej sekcji wykonasz kilka czynności za pomocą wtyczki Cloud Code, aby poznać podstawowe procesy i sprawdzić konfigurację aplikacji startowej.
Cloud Code jest zintegrowany z narzędziem Skaffold, aby usprawnić proces programowania. Gdy w kolejnych krokach wdrożysz aplikację w GKE, Cloud Code i Skaffold automatycznie skompilują obraz kontenera, wypchną go do Container Registry, a następnie wdrożą aplikację w GKE. Dzieje się to w sposób niewidoczny, co pozwala deweloperowi skupić się na innych aspektach. Cloud Code usprawnia też proces programowania, zapewniając tradycyjne funkcje debugowania i szybkiej synchronizacji w przypadku programowania opartego na kontenerach.
Wdrażanie 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. Jeśli pojawi się taka prośba, wybierz Yes (Tak), aby użyć bieżącego kontekstu Kubernetes.

- Gdy po raz pierwszy uruchomisz to polecenie, u góry ekranu pojawi się pytanie, czy chcesz użyć bieżącego kontekstu Kubernetes. Aby zaakceptować i użyć bieżącego kontekstu, kliknij „Yes” (Tak).

- Następnie pojawi się pytanie o to, którego repozytorium kontenerów chcesz użyć. Naciśnij Enter, aby zaakceptować podaną wartość domyślną.

- Wybierz kartę Wyjście w dolnym panelu, aby wyświetlić postęp i powiadomienia.

- Aby wyświetlić dodatkowe szczegóły i logi przesyłane strumieniowo na żywo z kontenerów, w menu po prawej stronie wybierz „Kubernetes: Run/Debug - Detailed” (Kubernetes: uruchamianie/debugowanie – szczegółowe).

- Aby wrócić do widoku uproszczonego, wybierz „Kubernetes: Uruchom/Debuguj” z menu rozwijanego.
- Po zakończeniu kompilacji i testów na karcie Wyniki pojawi się komunikat
Resource deployment/mynodejsapp status completed successfullyoraz adres URL: „Forwarded URL from service demo-app: 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 etykiecie narzędzia wybierz Otwórz podgląd w przeglądarce.
Odpowiedź będzie następująca:
{"message":"Greetings from Node"}
Gorące przeładowanie
- Wejdź na
src/index.js. Edytuj kod wiadomości powitalnej na'Hello from Node'
Zauważ, że w oknie Output, w 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 przejdziesz do widoku
Kubernetes: Run/Debug - Detailed, zauważysz, że rozpoznaje on zmiany w pliku i ponownie uruchamia 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 Codew menu u dołu i wybierzDebug on Kubernetes, aby uruchomić aplikację w trybiedebug.
- W widoku
Kubernetes Run/Debug - DetailedoknaOutputzauważ, że Skaffold wdroży tę aplikację w trybie debugowania. - Tworzenie i wdrażanie aplikacji zajmie kilka minut. Tym razem zobaczysz dołączony debuger.
Port forwarding pod/mynodejsapp-6bbcf847cd-vqr6v in namespace default, remote port 9229 -> http://127.0.0.1:9229 [mynodejsapp]Debugger attached.
- Dolny pasek stanu zmieni kolor z niebieskiego na pomarańczowy, co oznacza, że jest w trybie debugowania.
- W widoku
Kubernetes Run/Debugzobaczysz, że uruchomiono 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 ***********************************
Wykorzystywanie punktów przerwania
- Otwórz
src/index.js - Znajdź zdanie
var message="Greetings from Node"; - Dodaj punkt przerwania do tego wiersza, klikając puste miejsce po lewej stronie numeru wiersza. Pojawi się czerwony wskaźnik, który oznacza, że punkt przerwania został ustawiony.
- Odśwież przeglądarkę i zwróć uwagę, że debuger zatrzymuje proces w punkcie przerwania i umożliwia zbadanie zmiennych i stanu aplikacji, która jest uruchomiona zdalnie w GKE.
- Klikaj w sekcji zmiennych, aż znajdziesz zmienną
"message". - Wykonaj wiersz, klikając Krok dalej
. - Obserwuj, jak bieżąca wartość zmiennej
"message"zmienia się na"Greetings from Node". - Kliknij dwukrotnie nazwę zmiennej „target” i w wyskakującym okienku zmień wartość na inną, np.
"Hello from Node". - Kliknij przycisk Dalej w panelu sterowania debugowaniem.
- Sprawdź odpowiedź w przeglądarce, w której powinna się teraz wyświetlać wpisana przez Ciebie zaktualizowana wartość.
- Zatrzymaj tryb „Debugowanie”, naciskając przycisk zatrzymania
, i usuń punkt przerwania, klikając go ponownie.
5. Tworzenie prostej usługi REST CRUD
Na tym etapie aplikacja jest w pełni skonfigurowana pod kątem tworzenia skonteneryzowanych aplikacji, a Ty znasz już podstawowy przepływ pracy programisty w Cloud Code. W kolejnych sekcjach przećwiczysz zdobytą wiedzę, dodając punkty końcowe usługi REST, które łączą się z zarządzaną bazą danych w Google Cloud.
Konfigurowanie zależności
Kod aplikacji używa bazy danych do przechowywania danych usługi REST. Upewnij się, że zależności są dostępne, dodając w pliku package.json ten kod:
- Dodaj do pliku
package.jsonjeszcze 2 zależności:pgisequelize, aby utworzyć aplikację CRUD Postgres. Sekcja zależności po opublikowaniu zmian będzie wyglądać tak:
"dependencies": {
"express": "^4.16.4",
"pg": "^8.7.3",
"sequelize": "^6.17.0"
}
Kodowanie usługi REST
- Dodawanie do tej aplikacji kodu aplikacji CRUD
wget -O app.zip https://github.com/GoogleCloudPlatform/container-developer-workshop/raw/main/labs/nodejs/app.zip
unzip app.zip
Ten kod ma
- folder models z modelem encji dla
item; - folder controllers z kodem, który wykonuje operacje CRUD;
- folder routes, który kieruje określone wzorce adresów URL do różnych wywołań;
- folder config ze szczegółami połączenia z bazą danych;
- Zwróć uwagę, że konfiguracja bazy danych w pliku
db.config.jsodnosi się do zmiennych środowiskowych, które należy podać, aby połączyć się z bazą danych. Musisz też przeanalizować żądanie przychodzące pod kątem kodowania adresu URL. - Dodaj poniższy fragment kodu w
src/index.js, aby móc połączyć się 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);
- Edytuj wdrożenie w pliku
deployment.yaml, aby dodać zmienne środowiskowe, które będą zawierać informacje o połączeniu z bazą danych.
Zaktualizuj wpis specyfikacji na końcu pliku, aby pasował do tej definicji:
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 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
Wdrażanie i weryfikowanie aplikacji
- W panelu u dołu edytora Cloud Shell kliknij
Cloud Code, a następnie u góry ekranu kliknijDebug on Kubernetes. - Po zakończeniu kompilacji i testów na karcie Wyniki pojawi się komunikat
Resource deployment/mynodejsapp status completed successfullyoraz adres URL: „Forwarded URL from service mynodejsapp: http://localhost:8080”. - Dodaj kilka produktów.
W terminalu Cloud Shell uruchom te 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"
- Sprawdź żądanie GET, uruchamiając $URL/items w przeglądarce. Polecenie curl możesz też uruchomić z poziomu wiersza poleceń.
curl -X GET $URL/items
- Test Delete: teraz spróbuj usunąć element, uruchamiając to polecenie: W razie potrzeby zmień wartość identyfikatora produktu.
curl -X DELETE $URL/items/1
This throws an error message
{"message":"Could not delete Item with id=[object Object]"}
Identyfikowanie i rozwiązywanie problemu
- Uruchom ponownie aplikację w trybie debugowania i znajdź problem. Oto kilka porad:
- Wiemy, że z poleceniem DELETE jest coś nie tak, ponieważ nie zwraca ono oczekiwanego wyniku. Punkt przerwania należy ustawić w metodzie
itemcontroller.js->exports.delete. - Uruchom wykonywanie krok po kroku i obserwuj zmienne na każdym etapie, aby zobaczyć wartości zmiennych lokalnych w oknie po lewej stronie.
- Aby obserwować konkretne wartości, np.
request.params, dodaj tę zmienną do okna Obserwowanie.
- Zwróć uwagę, że wartość przypisana do
idtoundefined. Aby rozwiązać problem, zmień kod.
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 spróbuj usunąć plik.
- Zakończ sesję debugowania, klikając czerwony kwadrat na pasku narzędzi debugowania
.
6. Czyszczenie
Gratulacje! W tym module udało Ci się utworzyć od podstaw nową aplikację Node.js i skonfigurować ją do pracy w trybie wdrożenia na gorąco z kontenerami. Następnie wdrożyliśmy i debugowaliśmy aplikację w zdalnym klastrze GKE, korzystając z tego samego przepływu pracy dewelopera, który jest stosowany w tradycyjnych stosach aplikacji.
Aby zwolnić miejsce po ukończeniu modułu:
- Usuwanie plików użytych w laboratorium
cd ~ && rm -rf mynodejsapp && rm -f setup.sh
- Usuwanie projektu w celu usunięcia całej powiązanej infrastruktury i zasobów