1. Обзор
В этой лабораторной работе демонстрируются функции и возможности, предназначенные для оптимизации рабочего процесса разработки для инженеров-программистов, которым поручено разрабатывать приложения NodeJS в контейнерной среде. Типичная разработка контейнеров требует от пользователя понимания деталей контейнеров и процесса сборки контейнеров. Кроме того, разработчикам обычно приходится прерывать рабочий процесс, выходя из своей IDE для тестирования и отладки своих приложений в удаленных средах. С помощью инструментов и технологий, упомянутых в этом руководстве, разработчики могут эффективно работать с контейнерными приложениями, не выходя из своей IDE.
Что вы узнаете
В этой лабораторной работе вы изучите методы разработки с использованием контейнеров в Google Cloud, в том числе:
- Создание стартового приложения Nodejs
- Настройка приложения Nodejs для разработки контейнеров
- Кодирование простой службы отдыха CRUD
- Развертывание в GKE
- Отладка состояния ошибки
- Использование точки останова/логов
- Горячее развертывание изменений обратно в GKE
- Необязательно: интеграция CloudSQL для обеспечения устойчивости серверной части.
2. Настройка и требования
Самостоятельная настройка среды
- Войдите в Google Cloud Console и создайте новый проект или повторно используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .
- Имя проекта — это отображаемое имя для участников этого проекта. Это строка символов, не используемая API Google. Вы можете обновить его в любое время.
- Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (невозможно изменить после его установки). Cloud Console автоматически генерирует уникальную строку; обычно тебя не волнует, что это такое. В большинстве лабораторий кода вам потребуется указать идентификатор проекта (обычно он обозначается как
PROJECT_ID
). Если вам не нравится сгенерированный идентификатор, вы можете создать другой случайный идентификатор. Кроме того, вы можете попробовать свой собственный и посмотреть, доступен ли он. Его нельзя изменить после этого шага, и он останется в силе на протяжении всего проекта. - К вашему сведению, есть третье значение — номер проекта , который используют некоторые API. Подробнее обо всех трех этих значениях читайте в документации .
- Затем вам необходимо включить выставление счетов в Cloud Console, чтобы использовать облачные ресурсы/API. Прохождение этой лаборатории кода не должно стоить много, если вообще стоит. Чтобы отключить ресурсы и не взимать плату за пределами этого руководства, вы можете удалить созданные вами ресурсы или удалить весь проект. Новые пользователи 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 и получите доступ к данным, хранящимся в базе данных CloudSQL. Приведенный ниже сценарий установки подготовит для вас эту инфраструктуру.
- Загрузите сценарий установки и сделайте его исполняемым.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/nodejs/setup_with_cw.sh
chmod +x setup_with_cw.sh
- Откройте файл
setup_with_cw.sh
и отредактируйте значения паролей, для которых в данный момент установлено значение CHANGEME. - Запустите сценарий установки, чтобы настроить кластер GKE и базу данных CloudSQL, которые вы будете использовать в этой лабораторной работе.
./setup_with_cw.sh &
Кластер облачных рабочих станций
- Откройте облачные рабочие станции в облачной консоли. Подождите, пока кластер перейдет в состояние
READY
.
Создание конфигурации рабочих станций
- Если ваш сеанс Cloud Shell был отключен, нажмите «Повторно подключиться», а затем запустите команду gcloud cli, чтобы установить идентификатор проекта. Перед запуском команды замените приведенный ниже идентификатор примера проекта на идентификатор вашего проекта qwiklabs.
gcloud config set project qwiklabs-gcp-project-id
- Загрузите и запустите приведенный ниже скрипт в терминале, чтобы создать конфигурацию облачных рабочих станций.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/nodejs/workstation_config_setup.sh
chmod +x workstation_config_setup.sh
./workstation_config_setup.sh
- Проверьте результаты в разделе «Конфигурации». Переход в состояние ГОТОВНОСТЬ займет 2 минуты.
- Откройте Cloud Workstations в консоли и создайте новый экземпляр.
- Измените имя на
my-workstation
и выберите существующую конфигурацию:codeoss-js
.
- Проверьте результаты в разделе «Рабочие станции».
Запустить рабочую станцию
- Запустите и запустите рабочую станцию. Запуск рабочей станции займет пару минут.
- Разрешите сторонние файлы cookie, нажав на значок в адресной строке.
- Нажмите «Сайт не работает?».
- Нажмите «Разрешить файлы cookie».
- После запуска рабочей станции вы увидите Code OSS IDE. Нажмите «Отметить готово» на странице «Начало работы» в среде IDE рабочей станции.
3. Создание нового стартового приложения Nodejs.
В этом разделе вы создадите новое приложение Nodejs.
- Откройте новый терминал.
- В Cloud Shell создайте новый каталог с именем
mynodejsapp
mkdir mynodejsapp
Если вы видите это сообщение, нажмите кнопку «Разрешить», чтобы можно было скопировать и вставить на рабочую станцию.
- Перейдите в этот каталог и откройте его как рабочую область. Это перезагрузит редактор, создав конфигурацию рабочей области во вновь созданной папке.
cd mynodejsapp && code-oss-cloud-workstations -r --folder-uri="$PWD"
- Снова откройте новый терминал. Установите Node и NPM с помощью NVM.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/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
4. Создайте новое стартовое приложение.
- Инициализировать приложение
Создание файла package.json
с помощью следующей команды
npm init
Choose the `entry point: (index.js) src/index.js` and leave default values for the rest of the parameters. This will create the `package.json` 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" }
- Добавить точку входа
Откройте и отредактируйте файл package.json
в IDE, включив команду запуска в сценарий "start": "node src/index.js",
. После изменения скрипты должны выглядеть как фрагмент кода ниже:
"scripts": {
"start": "node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
- Добавьте экспресс-зависимость
Код, который мы собираемся добавить, также использует 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": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.3"
}
}
- Создайте файл 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 для контейнеризации этого приложения.
Кроме того, в этой конфигурации скаффолда автоматически включается горячая синхронизация между редактором и работающим контейнером. Для включения горячей синхронизации не требуется никакой дополнительной настройки.
5. Прогулка по процессу разработки
В этом разделе вы выполните несколько шагов с использованием плагина Cloud Code, чтобы изучить основные процессы и проверить конфигурацию и настройку вашего начального приложения.
Cloud Code интегрируется со skaffold, чтобы упростить процесс разработки. Когда вы выполните развертывание в GKE, выполнив следующие шаги, Cloud Code и Skaffold автоматически создадут образ вашего контейнера, отправят его в реестр контейнеров, а затем развернут ваше приложение в GKE. Это происходит «за кулисами», отвлекая детали от процесса разработки. Cloud Code также улучшает процесс разработки, предоставляя традиционные возможности отладки и горячей синхронизации для разработки на основе контейнеров.
Войдите в Google Cloud
- Нажмите на значок Cloud Code и выберите «Войти в Google Cloud»:
- Нажмите «Продолжить вход».
- Проверьте вывод в терминале и откройте ссылку:
- Войдите, используя свои учетные данные студента Qwiklabs.
- Выберите «Разрешить»:
- Скопируйте код подтверждения и вернитесь на вкладку «Рабочая станция».
- Вставьте код подтверждения и нажмите Enter.
Добавить кластер Kubernetes
- Добавить кластер
- Выберите Google Kubernetes Engine:
- Выберите проект.
- Выберите «mycluster», созданный при первоначальной настройке.
- Кластер теперь отображается в списке кластеров Kubernetes в разделе Cloud Code. Перемещайтесь и исследуйте кластер отсюда.
Установите текущий идентификатор проекта с помощью gcloud cli
- Скопируйте идентификатор проекта для этой лабораторной работы со страницы qwiklabs.
- В терминале выполните команду gcloud cli, чтобы установить идентификатор проекта. Замените идентификатор примера проекта перед запуском команды. ЗАМЕНИТЕ идентификатор проекта перед запуском команды ниже.
gcloud config set project qwiklabs-gcp-project-id
Развертывание в Kubernetes
- На панели внизу редактора Cloud Shell выберите Cloud Code 
- На появившейся вверху панели в разделе «СЕССИИ РАЗРАБОТКИ» выберите «Выполнить на Kubernetes» . При появлении запроса выберите Да, чтобы использовать текущий контекст Kubernetes.
- При первом запуске команды в верхней части экрана появится приглашение с вопросом, хотите ли вы использовать текущий контекст Kubernetes, выберите «Да», чтобы принять и использовать текущий контекст.
- Затем появится приглашение с вопросом, какой реестр контейнеров использовать. Нажмите Enter, чтобы принять предоставленное значение по умолчанию.
- Выберите вкладку «Вывод» на нижней панели и выберите «Kubernetes: Run/Debug» в раскрывающемся списке, чтобы просмотреть ход выполнения и уведомления.
- Выберите «Kubernetes: Run/Debug — Detailed» в раскрывающемся списке каналов справа, чтобы просмотреть дополнительные сведения и журналы, транслируемые в реальном времени из контейнеров.
- Вернитесь к упрощенному представлению, выбрав «Kubernetes: Run/Debug» в раскрывающемся списке.
- Когда сборка и тесты завершены, на вкладке «Вывод» отображается сообщение:
Resource deployment/mynodejsapp status completed successfully
» и отображается URL-адрес: «Перенаправленный URL-адрес из демонстрационного приложения службы: 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
.
- Обратите внимание, что в окне
Kubernetes Run/Debug - Detailed
представлениеOutput
» 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="Hello from Node";
- Добавьте точку останова в эту строку, щелкнув пустое место слева от номера строки. Красный индикатор покажет, что точка останова установлена.
- Перезагрузите браузер и обратите внимание, что отладчик останавливает процесс в точке останова и позволяет вам исследовать переменные и состояние приложения, которое работает удаленно в GKE.
- Нажимайте вниз в раздел переменных, пока не найдете переменную
"message"
. - Выполните строку, нажав «Перешагнуть».
- Обратите внимание, что текущее значение переменной
"message"
изменилось на"Hello from Node"
- Дважды щелкните имя переменной «target» и во всплывающем окне измените значение на другое, например
"Hi from Node"
- Нажмите кнопку «Продолжить» на панели управления отладкой.
- Просмотрите ответ в своем браузере, который теперь показывает обновленное значение, которое вы только что ввели.
- Остановите режим «Отладка», нажав кнопку «Стоп». и удалите точку останова, снова нажав на точку останова.
6. Разработка простой службы отдыха CRUD
На этом этапе ваше приложение полностью настроено для контейнерной разработки, и вы прошли базовый рабочий процесс разработки с помощью Cloud Code. В следующих разделах вы попрактикуете полученные знания, добавив конечные точки службы REST, подключающиеся к управляемой базе данных в Google Cloud.
Настройка зависимостей
Код приложения использует базу данных для сохранения остальных данных службы. Убедитесь, что зависимости доступны, добавив следующее в файл package.json
.
- Добавьте еще две зависимости
pg
иsequelize
в файлpackage.json
, чтобы создать Postgres CRUD-приложение. После внесения изменений раздел зависимостей будет выглядеть так.
"dependencies": {
"express": "^4.17.3",
"pg": "^8.8.0",
"sequelize": "^6.25.7"
}
Напишите код службы REST
- Добавьте код приложения CRUD в это приложение.
wget -O app.zip https://github.com/GoogleCloudPlatform/container-developer-workshop/raw/main/labs/nodejs/app.zip
unzip app.zip
Этот код имеет
- папка моделей с моделью объекта для
item
- папка контроллеров с кодом, выполняющим операции 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 что-то не так, поскольку она не возвращает желаемый результат. Итак, вы должны установить точку останова в методе
itemcontroller.js
->exports.delete
. - Запустите пошаговое выполнение и наблюдайте за переменными на каждом шаге, чтобы увидеть значения локальных переменных в левом окне.
- Чтобы наблюдать за конкретными значениями, такими как
request.params
добавьте эту переменную в окно наблюдения.
- Обратите внимание, что значение, присвоенное
id
,undefined
. Измените код, чтобы устранить проблему.
Фиксированный фрагмент кода будет выглядеть так.
// Delete a Item with the specified id in the request exports.delete = (req, res) => { const id = req.params.id;
- После перезапуска приложения проверьте еще раз, попытавшись удалить.
- Остановите сеанс отладки, щелкнув красный квадрат на панели инструментов отладки.
7. Очистка
Поздравляем! В ходе этой лабораторной работы вы создали новое приложение Nodejs с нуля и настроили его для работы в режиме горячего развертывания с контейнерами. Затем вы развернули и отладили свое приложение в удаленном кластере GKE, следуя той же схеме разработки, что и в традиционных стеках приложений.
Чтобы навести порядок после завершения лабораторной работы:
- Удалите файлы, используемые в лаборатории.
cd ~ && rm -rf mynodejsapp && rm -f setup.sh
- Удалите проект, чтобы удалить всю связанную инфраструктуру и ресурсы.