1. Обзор
В этой лабораторной работе демонстрируются функции и возможности, разработанные для оптимизации рабочего процесса разработки для инженеров-программистов, занимающихся разработкой приложений NodeJS в контейнеризированной среде. Типичная разработка в контейнерах требует от пользователя понимания деталей контейнеров и процесса сборки контейнеров. Кроме того, разработчикам обычно приходится прерывать свой рабочий процесс, выходя из IDE для тестирования и отладки своих приложений в удаленных средах. С помощью инструментов и технологий, упомянутых в этом руководстве, разработчики могут эффективно работать с контейнеризированными приложениями, не покидая свою IDE.
Что вы узнаете
В этой лабораторной работе вы изучите методы разработки с использованием контейнеров в GCP, в том числе:
- Создание стартового приложения Nodejs
- Настройка приложения Nodejs для разработки в контейнерах
- Разработка простого REST-сервиса для операций CRUD (операции чтения-выполнения)
- Развертывание в GKE
- Отладка состояния ошибки
- Использование точек останова / логов
- Горячее развертывание изменений обратно в GKE
- Дополнительно: интеграция CloudSQL для сохранения данных на бэкэнде.
2. Настройка и требования
Настройка среды для самостоятельного обучения
- Войдите в консоль Google Cloud и создайте новый проект или используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .



- Название проекта — это отображаемое имя участников данного проекта. Это строка символов, не используемая API Google, и вы можете изменить её в любое время.
- Идентификатор проекта должен быть уникальным для всех проектов Google Cloud и неизменяемым (его нельзя изменить после установки). Консоль Cloud автоматически генерирует уникальную строку; обычно вам неважно, какая она. В большинстве практических заданий вам потребуется указать идентификатор проекта (обычно он обозначается как
PROJECT_ID), поэтому, если он вам не нравится, сгенерируйте другой случайный идентификатор или попробуйте свой собственный и посмотрите, доступен ли он. Затем он "замораживается" после создания проекта. - Существует третье значение — номер проекта , который используется некоторыми API. Подробнее обо всех трех значениях можно узнать в документации .
- Далее вам потребуется включить оплату в консоли Cloud, чтобы использовать ресурсы/API Cloud. Выполнение этого практического задания не должно стоить дорого, если вообще что-либо. Чтобы отключить ресурсы и избежать дополнительных расходов после завершения этого урока, следуйте инструкциям по «очистке», приведенным в конце практического задания. Новые пользователи Google Cloud имеют право на бесплатную пробную версию стоимостью 300 долларов США .
Запустить редактор Cloudshell
Данная лабораторная работа разработана и протестирована для использования с редактором Google Cloud Shell. Для доступа к редактору,
- Получите доступ к своему проекту Google по адресу https://console.cloud.google.com .
- В правом верхнем углу нажмите на значок редактора облачной оболочки.

- В нижней части вашего окна откроется новое окно.
- Нажмите кнопку «Открыть редактор».

- В начале редактора справа будет изображен исследователь, а в центре — сам редактор.
- В нижней части экрана также должна быть доступна панель терминала.
- Если терминал НЕ открыт, используйте комбинацию клавиш `Ctrl+`, чтобы открыть новое окно терминала.
Настройте gcloud
В Cloud Shell укажите идентификатор проекта и регион, в который вы хотите развернуть приложение. Сохраните их как переменные PROJECT_ID и REGION .
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
Настройка кластера GKE и базы данных.
- Скачайте установочный скрипт и сделайте его исполняемым.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/nodejs/setup.sh
chmod +x setup.sh
Обеспечьте наличие инфраструктуры, используемой в этой лаборатории.
В этой лабораторной работе вы развернете код в GKE и получите доступ к данным, хранящимся в базе данных Spanner. Приведенный ниже скрипт настройки подготовит для вас эту инфраструктуру.
- Откройте файл
setup.shи отредактируйте значения паролей, которые в данный момент установлены на CHANGEME. - Запустите скрипт настройки, чтобы развернуть кластер GKE и базу данных CloudSQL, которые вы будете использовать в этой лабораторной работе.
./setup.sh
- В Cloud Shell создайте новую директорию с именем
mynodejsapp
mkdir mynodejsapp
- Перейдите в этот каталог и откройте его как рабочую область. Это перезагрузит редактор, создав конфигурацию рабочей области в только что созданной папке.
cd mynodejsapp && cloudshell workspace .
- Установите Node и NPM с помощью 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. Создайте новое стартовое приложение.
- Инициализируйте приложение.
Создание файла package.json путем выполнения следующей команды.
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"
}
- Добавить точку входа
Отредактируйте этот файл, добавив команду запуска в скрипт "start": "node src/index.js", . После внесения изменений скрипты должны выглядеть как в приведенном ниже фрагменте кода:
"scripts": {
"start": "node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
- Добавьте зависимость Express.
Код, который мы собираемся добавить, также использует express поэтому давайте добавим эту зависимость в файл package.json . Таким образом, после всех изменений файл package.json должен выглядеть так, как показано ниже.
{
"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"
}
}
- Создайте файл index.js.
Создайте исходный каталог с именем src.
Создайте файл src/index.js со следующим кодом.
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}/`);
});
Обратите внимание, что для параметра PORT установлено значение 8080
Создать манифесты
Skaffold предоставляет интегрированные инструменты для упрощения разработки контейнеров. На этом шаге вы инициализируете Skaffold, который автоматически создаст базовые YAML-файлы Kubernetes. Выполните команду ниже, чтобы начать процесс.
Выполните следующую команду в терминале.
skaffold init --generate-manifests
При появлении запроса:
- Введите 8080 для порта.
- Введите y для сохранения конфигурации.
В рабочую область добавлены два файла: skaffold.yaml и deployment.yaml
Обновить название приложения
Значения по умолчанию, указанные в конфигурации, в настоящее время не соответствуют названию вашего приложения. Обновите файлы, чтобы они ссылались на название вашего приложения, а не на значения по умолчанию.
- Измените записи в конфигурации Skaffold.
- Откройте
skaffold.yaml - Выберите имя изображения, которое в данный момент задано как
package-json-image - Щелкните правой кнопкой мыши и выберите «Изменить все вхождения».
- Введите новое имя как
mynodejsapp
- Измените записи в конфигурации Kubernetes.
- Откройте файл
deployment.yaml - Выберите имя изображения, которое в данный момент задано как
package-json-image - Щелкните правой кнопкой мыши и выберите «Изменить все вхождения».
- Введите новое имя как
mynodejsapp
Обратите внимание, что в файле skaffold.yaml раздел build использует buildpacks для контейнеризации приложения. В этом коде нет Dockerfile, и разработчику не требуется никаких знаний о Docker для контейнеризации этого приложения.
Кроме того, данная конфигурация Skaffold автоматически включает синхронизацию между редактором и запущенным контейнером. Для включения синхронизации дополнительная настройка не требуется.
4. Обзор процесса разработки.
В этом разделе вы шаг за шагом изучите основные процессы с помощью плагина Cloud Code, а также проверите конфигурацию и настройку вашего стартового приложения.
Cloud Code интегрируется со Skaffold для оптимизации процесса разработки. При развертывании в GKE на следующих этапах Cloud Code и Skaffold автоматически создадут образ контейнера, загрузят его в реестр контейнеров, а затем развернут ваше приложение в GKE. Это происходит в фоновом режиме, абстрагируя детали от процесса разработки. Cloud Code также улучшает процесс разработки, предоставляя традиционные возможности отладки и синхронизации для разработки на основе контейнеров.
Развертывание в Kubernetes
- В нижней части окна редактора Cloud Shell выберите Cloud Code.

- В появившейся вверху панели выберите «Запустить в Kubernetes» . Если появится запрос, выберите «Да», чтобы использовать текущий контекст Kubernetes.

- При первом запуске команды в верхней части экрана появится запрос, спрашивающий, хотите ли вы использовать текущий контекст Kubernetes. Выберите «Да», чтобы принять запрос и использовать текущий контекст.

- Далее появится запрос о том, какой реестр контейнеров использовать. Нажмите Enter, чтобы принять предоставленное значение по умолчанию.

- Чтобы просмотреть ход выполнения и уведомления, выберите вкладку «Вывод» в нижней панели.

- Выберите «Kubernetes: Запуск/Отладка — Подробная информация» в раскрывающемся списке каналов справа, чтобы просмотреть дополнительные сведения и журналы, транслируемые в режиме реального времени из контейнеров.

- Вернитесь к упрощенному представлению, выбрав в раскрывающемся списке «Kubernetes: Run/Debug».
- После завершения сборки и тестирования на вкладке «Вывод» отображается сообщение:
Resource deployment/mynodejsapp status completed successfully, а также URL-адрес: «Перенаправленный URL-адрес из сервиса demo-app: http://localhost:8080». - В терминале Cloud Code наведите курсор на URL-адрес в выводе (http://localhost:8080), а затем во всплывающей подсказке выберите «Открыть предварительный просмотр веб-страницы».
Ответ будет следующим:
{"message":"Greetings from Node"}
Горячая перезарядка
- Перейдите в
src/index.js. Отредактируйте код, заменив приветственное сообщение на'Hello from Node'
Обратите внимание, что в окне Output , в представлении Kubernetes: Run/Debug , наблюдатель синхронизирует обновленные файлы с контейнером в 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
- Если вы переключитесь на
Kubernetes: Run/Debug - Detailedпросмотр, вы заметите, что он распознает изменения файлов и перезапускает узел.
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/
- Обновите страницу в браузере, чтобы увидеть обновленные результаты.
Отладка
- Перейдите в режим отладки и остановите текущий поток.
. - В нижнем меню нажмите на
Cloud Codeи выберитеDebug on Kubernetes, чтобы запустить приложение в режимеdebug.
- В окне «Подробный просмотр
OutputKubernetes Run/Debug - Detailedобратите внимание, что skaffold развернет это приложение в режиме отладки. - Сборка и развертывание приложения займут несколько минут. На этот раз вы заметите, что отладчик подключен.
Port forwarding pod/mynodejsapp-6bbcf847cd-vqr6v in namespace default, remote port 9229 -> http://127.0.0.1:9229 [mynodejsapp]Debugger attached.
- Цвет нижней строки состояния меняется с синего на оранжевый, указывая на то, что устройство находится в режиме отладки.
- В окне
Kubernetes Run/Debugобратите внимание, что запущен отлаживаемый контейнер.
**************URLs***************** Forwarded URL from service mynodejsapp-service: http://localhost:8080 Debuggable container started pod/mynodejsapp-deployment-6bc7598798-xl9kj:mynodejsapp (default) Update succeeded ***********************************
Используйте точки останова
- Откройте файл
src/index.js - Найдите оператор, который выглядит следующим образом
var message="Greetings from Node"; - Установите точку останова на этой строке, щелкнув по пустому месту слева от номера строки. Красный индикатор покажет, что точка останова установлена.
- Перезагрузите браузер и обратите внимание, что отладчик останавливает процесс в точке останова и позволяет вам исследовать переменные и состояние приложения, работающего удаленно в GKE.
- Прокрутите вниз в раздел переменных, пока не найдете переменную
"message". - Выполните строку, нажав кнопку «Шаг через».

- Обратите внимание, что текущее значение переменной
"message"изменилось на"Greetings from Node" - Дважды щелкните по имени переменной "target" и во всплывающем окне измените значение на что-нибудь другое, например,
"Hello from Node" - Нажмите кнопку «Продолжить» на панели управления отладкой.
- Проверьте ответ в браузере, где теперь отображается обновленное значение, которое вы только что ввели.
- Остановите режим отладки, нажав кнопку «Стоп».
и снимите точку останова, снова щелкнув по ней.
5. Разработка простого REST-сервиса с операциями CRUD.
На этом этапе ваше приложение полностью настроено для контейнерной разработки, и вы прошли базовый рабочий процесс разработки с помощью Cloud Code. В следующих разделах вы попрактикуетесь в применении полученных знаний, добавив конечные точки REST-сервиса, подключающиеся к управляемой базе данных в Google Cloud.
Настройка зависимостей
Код приложения использует базу данных для сохранения данных REST-сервиса. Убедитесь в наличии зависимостей, добавив следующее в файл package.json
- Добавьте еще две зависимости:
pgиsequelizeв файлpackage.json, чтобы создать CRUD-приложение на базе PostgreSQL. После внесения изменений раздел зависимостей будет выглядеть следующим образом.
"dependencies": {
"express": "^4.16.4",
"pg": "^8.7.3",
"sequelize": "^6.17.0"
}
Напишите код для REST-сервиса
- Добавьте код CRUD-приложения в это приложение.
wget -O app.zip https://github.com/GoogleCloudPlatform/container-developer-workshop/raw/main/labs/nodejs/app.zip
unzip app.zip
Этот код имеет
- Папка models содержит модель сущности для
item - Папка controllers содержит код, выполняющий операции CRUD (операции чтения-вывода, чтения-записи, удаления и сохранения).
- Папка маршрутов , которая перенаправляет определенные шаблоны URL-адресов на различные вызовы.
- Папка config с информацией о подключении к базе данных.
- Обратите внимание, что конфигурация базы данных в файле
db.config.jsотносится к переменным среды, которые необходимо указать для подключения к базе данных. Также необходимо проверить входящий запрос на кодировку URL. - Добавьте следующий фрагмент кода в
src/index.js, чтобы иметь возможность подключаться к CRUD-коду из вашего основного JavaScript-файла, непосредственно перед последним разделом, начинающимся сapp.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);
- Отредактируйте файл
deployment.yaml, добавив переменные среды для предоставления информации о подключении к базе данных.
Обновите запись спецификации в конце файла, чтобы она соответствовала следующему определению.
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
- Замените значение DB_HOST адресом вашей базы данных.
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
Развертывание и проверка приложения
- В нижней части окна редактора Cloud Shell выберите
Cloud Code, а затем в верхней части экрана выберитеDebug on Kubernetes. - После завершения сборки и тестирования на вкладке «Вывод» отображается сообщение:
Resource deployment/mynodejsapp status completed successfully, а также указан URL-адрес: «Перенаправленный URL-адрес из сервиса mynodejsapp: http://localhost:8080». - Добавьте пару предметов.
В терминале CloudShell выполните следующие команды.
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"
- Проверьте правильность выполнения запроса GET, запустив команду `$URL/items` в браузере. Также можно запустить curl из командной строки.
curl -X GET $URL/items
- Тестовое удаление: Теперь попробуйте удалить элемент, запустив команду. При необходимости измените значение item-id.
curl -X DELETE $URL/items/1
This throws an error message
{"message":"Could not delete Item with id=[object Object]"}
Выявите и устраните проблему.
- Перезапустите приложение в режиме отладки и найдите проблему. Вот несколько советов:
- Мы знаем, что что-то не так с оператором DELETE, поскольку он не возвращает желаемый результат. Поэтому вам следует установить точку останова в методе
exports.deleteв файлеitemcontroller.js. - Выполните пошаговое выполнение программы и наблюдайте за переменными на каждом шаге, чтобы увидеть значения локальных переменных в левом окне.
- Чтобы отслеживать определенные значения, такие как
request.paramsдобавьте эту переменную в окно «Отслеживание».
- Обратите внимание, что значение, присвоенное переменной
id,undefined. Измените код, чтобы исправить эту проблему.
Исправленный фрагмент кода будет выглядеть так.
// Delete a Item with the specified id in the request
exports.delete = (req, res) => {
const id = req.params.id;
- После перезапуска приложения проверьте еще раз, попробовав удалить файл.
- Остановите сеанс отладки, нажав на красный квадрат на панели инструментов отладки.

6. Уборка
Поздравляем! В этой лабораторной работе вы создали новое приложение Nodejs с нуля и настроили его для работы в режиме «горячего развертывания» с использованием контейнеров. Затем вы развернули и отладили свое приложение в удаленном кластере GKE, следуя тому же процессу разработки, что и в традиционных стеках приложений.
После завершения лабораторной работы необходимо провести уборку:
- Удалите файлы, использованные в лабораторной работе.
cd ~ && rm -rf mynodejsapp && rm -f setup.sh
- Удалите проект, чтобы удалить всю связанную с ним инфраструктуру и ресурсы.