О практической работе
1. Введение
Последнее обновление: 1 ноября 2024 г.
Как нам модернизировать старое PHP-приложение до Google Cloud?
(📽️ посмотрите 7-минутное вступительное видео к этой кодовой лаборатории)
Обычно локально работают устаревшие приложения, которые необходимо модернизировать. Это означает, что они должны быть масштабируемыми, безопасными и пригодными для развертывания в различных средах.
На этом семинаре вы:
- Контейнеризация PHP-приложения.
- Перейдите на службу управляемой базы данных ( Cloud SQL ).
- Развертывание в Cloud Run (это альтернатива GKE/Kubernetes, не требующая операций).
- Защитите приложение с помощью управления идентификацией и доступом (IAM) и диспетчера секретов.
- Определите конвейер CI/CD с помощью Cloud Build . Cloud Build может быть связан с вашим репозиторием Git, размещенным на популярных провайдерах Git, таких как GitHub или GitLab, и запускаться, например, при любом нажатии на основной.
- Разместите изображения приложения в облачном хранилище . Это достигается за счет монтирования, и для изменения приложения код не требуется.
- Внедрите функциональность Gen AI через Gemini , управляемую с помощью облачных функций (бессерверных).
- Ознакомьтесь с SLO и работой с обновленным приложением.
Следуя этим шагам, вы сможете постепенно модернизировать свое PHP-приложение, улучшая его масштабируемость, безопасность и гибкость развертывания. Более того, переход в Google Cloud позволяет вам использовать его мощную инфраструктуру и сервисы, чтобы обеспечить бесперебойную работу вашего приложения в облачной среде.
Мы считаем, что то, что вы узнаете, выполнив эти простые шаги, можно применить к вашему собственному приложению и организации с другим языком/стеком и разными сценариями использования.
О приложении
Приложение ( код под лицензией MIT ), которое вы создадите, представляет собой базовое приложение PHP 5.7 с аутентификацией MySQL. Основная идея приложения — предоставить платформу, на которую пользователи могут загружать фотографии, а администраторы имеют возможность отмечать неприемлемые изображения. В приложении есть две таблицы:
- Пользователи . Поставляется предварительно скомпилированным администратором. Новые люди могут зарегистрироваться.
- Изображения . Поставляется с несколькими примерами изображений. Авторизованные пользователи могут загружать новые изображения. Мы добавим сюда немного магии.
Ваша цель
Мы хотим модернизировать старое приложение, чтобы разместить его в Google Cloud. Мы будем использовать его инструменты и услуги для улучшения масштабируемости, повышения безопасности, автоматизации управления инфраструктурой и интеграции расширенных функций, таких как обработка изображений, мониторинг и хранение данных, с помощью таких сервисов, как Cloud SQL, Cloud Run, Cloud Build, Secret Manager и других.
Что еще более важно, мы хотим делать это шаг за шагом, чтобы вы могли узнать, какой мыслительный процесс стоит за каждым шагом, и обычно каждый шаг открывает новые возможности для следующих (пример: модули 2 -> 3 и 6 -> 7).
Еще не убеждены? Посмотрите это 7-минутное видео на YouTube .
Что вам понадобится
- Компьютер с браузером, подключенный к Интернету.
- Некоторые кредиты GCP. См. следующий шаг .
- Вы будете использовать облачную Shell . Он поставляется со всеми предустановленными командами, которые вам понадобятся, и IDE .
- Аккаунт на GitHub . Это необходимо для разветвления исходного кода 🧑🏻💻 gdgpescara/app-mod-workshop на собственный репозиторий git. Это необходимо для наличия собственного конвейера CI/CD (автоматическая фиксация -> сборка -> развертывание).
Примеры решений можно найти здесь:
- Репозиторий автора: https://github.com/Friends-of-Ricc/app-mod-workshop.
- Оригинальный репозиторий мастерской в папках
.solutions/
для каждой главы.
Этот семинар предназначен для выполнения в Cloud Shell (в браузере).
Однако это также можно попытаться сделать с вашего локального компьютера.
2. Настройка кредита и форк
Погасите кредит GCP и настройте свою среду GCP [необязательно]
Для проведения этого семинара вам понадобится платежный аккаунт с некоторым кредитом. Если у вас уже есть собственный платежный аккаунт, вы можете пропустить этот шаг.
Создайте новую учетную запись Google Gmail (*), чтобы привязать ее к своему кредиту GCP. Попросите своего инструктора ссылку, чтобы выкупить кредит GCP, или воспользуйтесь кредитами здесь: bit.ly/PHP-Amarcord-credits .
Войдите в новую учетную запись и следуйте инструкциям.
(
) Зачем мне нужна новая учетная запись Gmail? *
Мы видели, как люди терпели неудачу при проверке кода, поскольку их учетные записи (особенно рабочие или студенческие электронные письма) ранее подвергались воздействию GCP, а организационные политики ограничивали их возможности это делать. Мы рекомендуем либо создать новую учетную запись Gmail, либо использовать существующую учетную запись GMail (gmail.com) без предварительного использования GCP.
Нажмите кнопку, чтобы погасить кредит.
Заполните следующую форму, указав свое имя и фамилию, и согласитесь с Условиями использования.
Возможно, вам придется подождать несколько секунд, прежде чем платежный аккаунт появится здесь: https://console.cloud.google.com/billing.
После этого откройте Google Cloud Console и создайте новый проект, щелкнув «Выбор проекта» в раскрывающемся меню слева вверху, где отображается «Нет организации». См. ниже
Создайте новый проект, если у вас его нет, как показано на скриншоте ниже. В правом верхнем углу есть опция «НОВЫЙ ПРОЕКТ».
Обязательно свяжите новый проект с платежным аккаунтом пробной версии GCP следующим образом.
Все готово для использования Google Cloud Platform. Если вы новичок или просто хотите делать все в облачной среде, вы можете получить доступ к Cloud Shell и его редактору с помощью следующей кнопки в верхнем левом углу, как показано ниже.
Убедитесь, что ваш новый проект выбран в левом верхнем углу:
Не выбрано (плохо):
Выбрано (хорошо):
Форк приложения с GitHub
- Перейдите в демо-приложение: https://github.com/gdgpescara/app-mod-workshop.
- Нажмите 🍴 вилка.
- Если у вас нет учетной записи GitHub, вам необходимо создать новую.
- Редактируйте вещи по своему желанию.
- Клонируйте код приложения, используя
-
git clone
YOUR-GITHUB-USER/YOUR-REPO-NAME
https://github.com/
- Откройте папку клонированного проекта в вашем любимом редакторе. Если вы выберете Cloud Shell, вы можете сделать это, нажав « Открыть редактор », как показано ниже.
У вас есть все необходимое с редактором Google Cloud Shell, как показано на следующем рисунке.
Этого можно добиться визуально, нажав «Открыть папку» и выбрав папку (вероятно app-mod-workshop
в вашей домашней папке.
3. Модуль 1. Создание экземпляра SQL
Создайте экземпляр Google Cloud SQL.
Наше PHP-приложение будет подключаться к базе данных MySQL, поэтому нам необходимо реплицировать его в Google Cloud для беспроблемной миграции. Cloud SQL идеально подходит, поскольку позволяет запускать полностью управляемую базу данных MySQL в облаке. Вот шаги, которые необходимо выполнить:
- Перейдите на страницу Cloud SQL: https://console.cloud.google.com/sql/instances.
- Нажмите «Создать экземпляр».
- Включите API (при необходимости). Это может занять несколько секунд.
- Выберите MySQL.
- (Мы стараемся предоставить вам самую дешевую версию, чтобы она прослужила дольше):
- Издание: Предприятие
- Предустановка: разработка (мы пробовали Sandbox и у нас не сработало)
- Mysql версия: 5.7 (вау, взрыв из прошлого!)
- Идентификатор экземпляра: выберите
appmod-phpapp
(если вы его измените, не забудьте соответствующим образом изменить будущие скрипты и решения). - Пароль: любой, но запишите его как CLOUDSQL_INSTANCE_PASSWORD.
- Регион: оставьте то же, что вы выбрали для остальной части приложения (например, Милан =
europe-west8
). - Зональное использование: одна зона (мы экономим деньги на демо-версию)
Нажмите кнопку «Создать экземпляр», чтобы развернуть базу данных Cloud SQL; ⌛ выполнение занимает около 10 минут⌛ . А пока продолжайте читать документацию; вы также можете начать решать следующий модуль («Контейнеризация вашего PHP-приложения»), поскольку он не имеет зависимостей от этого модуля в первой части (пока вы не исправите соединение с БД).
Примечание . Этот экземпляр обойдется вам примерно в 7 долларов в день. Обязательно отключите его после семинара.
Создайте базу данных image_catalog и пользователя в Cloud SQL.
Проект приложения поставляется с папкой db/
, содержащей два файла sql:
- 01_schema.sql : содержит код SQL для создания двух таблиц, содержащих данные пользователей и изображений.
- 02_seed.sql : содержит код SQL для заполнения данных в ранее созданных таблицах.
Эти файлы будут использоваться позже, когда будет создана база данных image_catalog
. Вы можете сделать это, выполнив следующие шаги:
- Откройте свой экземпляр и перейдите на вкладку «Базы данных»:
- нажмите «Создать базу данных»
- назовите его
image_catalog
(как в конфигурации приложения PHP).
Затем мы создаем пользователя базы данных. Благодаря этому мы можем пройти аутентификацию в базе данных image_catalog.
- Теперь нажмите на вкладку «Пользователи».
- Нажмите «Добавить учетную запись пользователя».
- Пользователь: давайте создадим:
- Имя пользователя:
appmod-phpapp-user
- Пароль: выберите тот, который вы помните, или нажмите «Создать».
- Оставьте « Разрешить любой хост (%) ».
- нажмите ДОБАВИТЬ.
Откройте БД для известных IP-адресов.
Обратите внимание, что все базы данных в Cloud SQL изначально изолированы. Вам необходимо явно настроить сеть для доступа.
- Нажмите на свой экземпляр
- Откройте меню «Подключения»
- Нажмите на вкладку «Сеть».
- Нажмите «Авторизованные сети». Теперь добавим сеть (т.е. подсеть).
- А пока давайте выберем быстрые, но НЕБЕЗОПАСНЫЕ настройки, чтобы приложение могло работать — возможно, позже вы захотите ограничить его IP-адресами, которым вы доверяете:
- Название: «Все в мире – НЕБЕЗОПАСНЫ».
- Сеть: «
0.0.0.0/0"
(Примечание: это НЕБЕЗОПАСНАЯ часть!) - Нажмите ГОТОВО
- Нажмите «Сохранить».
Вы должны увидеть что-то вроде этого:
Примечание . Это решение является хорошим компромиссом для завершения семинара за O(часов). Однако ознакомьтесь с документом БЕЗОПАСНОСТЬ , чтобы защитить свое решение для производства!
Пришло время проверить соединение с БД!
Давайте посмотрим, работает ли созданный нами ранее пользователь image_catalog
.
Откройте «Cloud SQL Studio» внутри экземпляра и введите базу данных, пользователя и пароль для аутентификации, как показано ниже:
Теперь вы можете открыть редактор SQL и перейти к следующему разделу.
Импортируйте базу данных из базы кода.
Используйте редактор SQL для импорта таблиц image_catalog
с их данными. Скопируйте код SQL из файлов в репозитории ( 01_schema.sql , а затем 02_seed.sql ) и выполните их один за другим в последовательном порядке.
После этого вы должны получить две таблицы в image_catalog, которые представляют собой пользователей и изображения , как показано ниже:
Вы можете проверить это, выполнив в редакторе следующее: select * from images;
Также обязательно запишите общедоступный IP-адрес экземпляра Cloud SQL, он понадобится вам позже. Чтобы получить IP-адрес, перейдите на главную страницу экземпляра CLoud SQL на странице «Обзор» . (Обзор > Подключиться к этому экземпляру > Публичный IP-адрес).
4. Модуль 2. Контейнеризация вашего PHP-приложения
Мы хотим создать это приложение для облака.
Это означает упаковку кода в какой-то ZIP-файл, содержащий всю информацию для его запуска в облаке.
Есть несколько способов упаковки:
- Докер . Очень популярный, но довольно сложный в правильной настройке.
- Сборочные пакеты . Менее популярен, но имеет тенденцию «автоматически угадывать», что создавать и что запускать. Часто это просто работает!
В контексте этого семинара мы будем предполагать, что вы используете Docker.
Если вы решили использовать Cloud Shell , сейчас самое время снова открыть его (нажмите в правом верхнем углу облачной консоли).
При этом должна открыться удобная оболочка внизу страницы, куда вы должны были разветвить код на этапе настройки .
Докер
Если вы хотите иметь контроль, это правильное решение для вас. Это имеет смысл, когда вам нужно настроить определенные библиотеки и внедрить определенное неочевидное поведение (chmod при загрузке, нестандартный исполняемый файл в вашем приложении и т. д.).
Поскольку мы хотим в конечном итоге развернуть наше контейнерное приложение в Cloud Run, ознакомьтесь со следующей документацией . Как бы вы перенесли его с PHP 8 на PHP 5.7? Возможно, вы сможете использовать для этого Близнецов. В качестве альтернативы вы можете использовать эту заранее запеченную версию:
# Use the official PHP image: https://hub.docker.com/_/php
FROM php:5.6-apache
# Configure PHP for Cloud Run.
# Precompile PHP code with opcache.
# Install PHP's extension for MySQL
RUN docker-php-ext-install -j "$(nproc)" opcache mysqli pdo pdo_mysql && docker-php-ext-enable pdo_mysql
RUN set -ex; \
{ \
echo "; Cloud Run enforces memory & timeouts"; \
echo "memory_limit = -1"; \
echo "max_execution_time = 0"; \
echo "; File upload at Cloud Run network limit"; \
echo "upload_max_filesize = 32M"; \
echo "post_max_size = 32M"; \
echo "; Configure Opcache for Containers"; \
echo "opcache.enable = On"; \
echo "opcache.validate_timestamps = Off"; \
echo "; Configure Opcache Memory (Application-specific)"; \
echo "opcache.memory_consumption = 32"; \
} > "$PHP_INI_DIR/conf.d/cloud-run.ini"
# Copy in custom code from the host machine.
WORKDIR /var/www/html
COPY . .
# Setup the PORT environment variable in Apache configuration files: https://cloud.google.com/run/docs/reference/container-contract#port
ENV PORT=8080
# Tell Apache to use 8080 instead of 80.
RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf
# Note: This is quite insecure and opens security breaches. See last chapter for hardening ideas.
# Uncomment at your own risk:
#RUN chmod 777 /var/www/html/uploads/
# Configure PHP for development.
# Switch to the production php.ini for production operations.
# RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# https://github.com/docker-library/docs/blob/master/php/README.md#configuration
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
# Expose the port
EXPOSE 8080
Последняя версия Dockerfile
доступна здесь .
Чтобы протестировать наше приложение локально, нам нужно изменить файл config.php таким образом, чтобы наше приложение PHP могло подключаться к базе данных MYSQL, доступной в Google CloudSQL. На основе того, что вы настроили ранее, заполните поля :
<?php
// Database configuration
$db_host = '____________';
$db_name = '____________';
$db_user = '____________';
$db_pass = '____________';
try {
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Errore di connessione: " . $e->getMessage());
}
session_start();
?>
-
DB_HOST
— это общедоступный IP-адрес Cloud SQL. Его можно найти в консоли SQL:
-
DB_NAME
должно остаться без изменений:image_catalog
-
DB_USER
должен бытьappmod-phpapp-user
-
DB_PASS
— это то, что вы выбрали. Заключите его в одинарные кавычки и при необходимости экранируйте.
А еще вы можете перевести несколько 🇮🇹 итальянских произведений на английский с помощью Gemini !
Хорошо, теперь, когда у вас есть Dockerfile
и вы настроили PHP-приложение для подключения к вашей БД, давайте попробуем!
Установите докер, если у вас его еще нет ( ссылка ). Вам это не нужно, если вы используете Cloud Shell (насколько это круто?).
Теперь попробуйте собрать и запустить контейнерное PHP-приложение с помощью соответствующих команд сборки и запуска Docker.
# Build command - don't forget the final . This works if Dockerfile is inside the code folder:
$ docker build -t my-php-app-docker .
# Local Run command: most likely ports will be 8080:8080
$ docker run -it -p <CONTAINER_PORT>:<LOCAL_MACHINE_PORT> my-php-app-docker
Если все работает, вы сможете увидеть следующую веб-страницу при подключении к локальному хосту! Теперь ваше приложение работает на порту 8080 , щелкните значок «Предварительный просмотр в Интернете» (браузер с глазом), а затем выберите «Предварительный просмотр на порту 8080 » (или «Изменить порт» на любой другой порт).
Тестирование результата в вашем браузере
Теперь ваше приложение должно выглядеть примерно так:
И если вы войдете в систему под учетной записью Admin/admin123, вы увидите что-то вроде этого.
Большой!!! Помимо итальянского текста, он работает! 🎉🎉🎉
Если ваша докеризация прошла успешно, но учетные данные БД неверны, вы можете получить что-то вроде этого:
Попробуй еще раз, ты близко!
Сохранение в реестре артефактов [необязательно]
К этому моменту у вас должно быть работающее контейнерное PHP-приложение, готовое к развертыванию в облаке. Далее нам нужно место в облаке для хранения нашего образа Docker и обеспечения его доступности для развертывания в облачных сервисах Google, таких как Cloud Run. Это решение для хранения называется Artifact Registry — полностью управляемый облачный сервис Google, предназначенный для хранения артефактов приложений, включая образы контейнеров Docker, пакеты Maven, модули npm и многое другое.
Создадим репозиторий в Google Cloud Artifact Registry с помощью соответствующей кнопки.
Выберите допустимое имя, формат и регион, подходящий для хранения артефактов.
Вернитесь к тегу локальной среды разработки и отправьте образ контейнера приложения в только что созданный репозиторий реестра артефактов. Для этого выполните следующие команды.
- тег Docker SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
- докер нажмите TARGET_IMAGE[:TAG]
Результат должен выглядеть как на следующем снимке экрана.
Ура 🎉🎉🎉 вы можете перейти на следующий уровень. До этого, возможно, потратьте 2 минуты, пытаясь загрузить, войти в систему или выйти из системы и ознакомиться с конечными точками приложения. Они понадобятся вам позже.
Возможные ошибки
Если вы получаете ошибки контейнеризации, попробуйте использовать Gemini , чтобы объяснить и исправить ошибку, предоставив:
- Ваш текущий Dockerfile
- Получена ошибка
- [при необходимости] выполняемый PHP-код.
Разрешения на загрузку . Также попробуйте конечную точку /upload.php
и попробуйте загрузить изображение. Вы можете получить ошибку ниже. Если да, то вам нужно внести исправления chmod/chown
в Dockerfile
.
Предупреждение : move_uploaded_file(uploads/image (3).png): не удалось открыть поток: разрешение отклонено в /var/www/html/upload.php в строке 11.
PDOException «не удалось найти драйвер» (или «Ошибка подключения: не удалось найти драйвер») . Убедитесь, что ваш Dockerfile имеет подходящие библиотеки PDO для mysql ( pdo_mysql
) для подключения к БД. Черпайте вдохновение из решений здесь .
Невозможно переслать ваш запрос на серверную часть. Не удалось подключиться к серверу через порт 8080. Это означает, что вы, вероятно, указываете неправильный порт. Убедитесь, что вы раскрываете порт, с которого фактически обслуживается Apache/Nginx. Это не тривиально. Если возможно, попробуйте сделать этот порт 8080 (облегчает жизнь с Cloud Run). Если вы хотите сохранить порт 80 (например, потому что Apache этого хочет), используйте для его запуска другую команду:
$ docker run -it -p 8080:80 # force 80
# Use the PORT environment variable in Apache configuration files.
# https://cloud.google.com/run/docs/reference/container-contract#port
RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf
5. Модуль 3. Развертывание приложения в Cloud Run
Почему Cloud Run?
Честный вопрос! Несколько лет назад вы наверняка выбрали бы Google App Engine.
Проще говоря, сегодня Cloud Run имеет более новый стек технологий, его проще развернуть, он дешевле и масштабируется до 0, когда вы его не используете. Благодаря своей гибкости для запуска любого контейнера без сохранения состояния и интеграции с различными сервисами Google Cloud он идеально подходит для развертывания микросервисов и современных приложений с минимальными накладными расходами и максимальной эффективностью.
В частности, Cloud Run — это полностью управляемая платформа Google Cloud, которая позволяет запускать контейнерные приложения без сохранения состояния в бессерверной среде. Он автоматически управляет всей инфраструктурой, масштабируясь с нуля для удовлетворения входящего трафика и прекращая работу в случае простоя, что делает его экономичным и эффективным. Cloud Run поддерживает любой язык или библиотеку, если они упакованы в контейнер, что обеспечивает большую гибкость при разработке. Он хорошо интегрируется с другими сервисами Google Cloud и подходит для создания микросервисов, API, веб-сайтов и приложений, управляемых событиями, без необходимости управлять серверной инфраструктурой.
Предварительные условия
Для выполнения этой задачи на вашем локальном компьютере должен быть установлен gcloud
. Если нет, смотрите инструкции здесь . Вместо этого, если вы используете Google Cloud Shell, никаких действий предпринимать не нужно.
Прежде чем развернуть...
Если вы работаете в своей локальной среде, выполните аутентификацию в Google Cloud, выполнив следующие действия:
-
$ gcloud auth login –update-adc # not needed in Cloud Shell
Это должно аутентифицировать вас через вход OAuth в вашем браузере. Убедитесь, что вы входите в систему через Chrome под тем же пользователем (например, vattelapesca@gmail.com), который вошел в Google Cloud с включенной оплатой.
Включите Cloud Run API с помощью следующей команды:
-
$ gcloud services enable run.googleapis.com cloudbuild.googleapis.com
На этом этапе все готово к развертыванию в Cloud Run.
Разверните свое приложение в облаке. Запуск через gcloud
Команда, позволяющая развернуть приложение в Cloud Run, — это gcloud run deploy
. Есть несколько вариантов настройки для достижения вашей цели. Минимальный набор параметров (которые вы можете указать через командную строку или инструмент запросит вас с помощью интерактивной подсказки) следующий:
- Имя службы Cloud Run, которую вы хотите развернуть для своего приложения. Служба Cloud Run вернет вам URL-адрес, который предоставляет конечную точку для вашего приложения.
- Регион Google Cloud , в котором будет работать ваше приложение. (
--region
РЕГИОН) - Изображение контейнера , которое обертывает ваше приложение.
- Переменные среды , которые ваше приложение должно использовать во время своего выполнения.
- Флаг «Разрешить-неаутентифицированный» , который разрешает каждому доступ к вашему приложению без дополнительной аутентификации.
Обратитесь к документации (или прокрутите вниз, чтобы найти возможное решение), чтобы узнать, как применить эту опцию к вашей командной строке.
Развертывание займет несколько минут. Если все правильно, вы должны увидеть что-то подобное в Google Cloud Console.
Нажмите на URL-адрес, предоставленный Cloud Run, и протестируйте свое приложение. После аутентификации вы должны увидеть что-то вроде этого.
«gcloud run Deploy» без аргументов
Возможно, вы заметили, что gcloud run deploy
задает вам правильные вопросы и заполняет оставленные вами пробелы. Это потрясающе!
Однако в нескольких модулях мы собираемся добавить эту команду в триггер Cloud Build, чтобы мы не могли позволить себе интерактивные вопросы. Нам нужно заполнить каждую опцию в команде. Итак, вы хотите создать золотой gcloud run deploy --option1 blah --foo bar --region your-fav-region
. Как ты это делаешь?
- повторяйте шаги 2-3-4, пока gcloud не перестанет задавать вопросы:
- [LOOP]
gcloud run deploy
с найденными на данный момент опциями - Системы [LOOP] запрашивают опцию X
- [LOOP] Найдите в общедоступных документах, как настроить X из CLI, добавив параметр
--my-option [my-value]
. - Вернитесь к шагу 2, если только gcloud не завершится без дополнительных вопросов.
- Этот запуск gcloud развертывает БЛА-БЛА-БЛА-камни! Сохраните команду где-нибудь, она понадобится вам позже на этапе Cloud Build!
Возможное решение здесь . Документы здесь .
Ура 🎉🎉🎉 Вы успешно развернули свое приложение в Google Cloud, пройдя первый этап модернизации.
6. Модуль 4. Очистка пароля с помощью Secret Manager
На предыдущем шаге мы смогли успешно развернуть и запустить наше приложение в Cloud Run. Однако мы сделали это, используя плохую с точки зрения безопасности практику: предоставляя некоторые секреты в открытом виде .
Первая итерация: обновите свой config.php , чтобы использовать ENV.
Возможно, вы заметили, что мы поместили пароль к базе данных прямо в код файла config.php. Это подходит для целей тестирования и проверки работы приложения. Но вы не можете фиксировать/использовать такой код в производственной среде. Пароль (и другие параметры подключения к БД) следует считывать динамически и предоставлять приложению во время выполнения. Измените файл config.php так, чтобы он считывал параметры базы данных из переменных ENV. Если это не помогло, вам следует рассмотреть возможность установки значений по умолчанию . Это хорошо, если вам не удалось загрузить ENV, поэтому выходные данные страницы сообщат вам, используются ли значения по умолчанию. Заполните пробелы и замените код в config.php.
<?php
// Database configuration with ENV variables. Set default values as well
$db_host = getenv('DB_HOST') ?: 'localhost';
$db_name = getenv('DB_NAME') ?: 'image_catalog';
$db_user = getenv('DB_USER') ?: 'appmod-phpapp-user';
$db_pass = getenv('DB_PASS') ?: 'wrong_password';
// Note getenv() is PHP 5.3 compatible
try {
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Errore di connessione: " . $e->getMessage());
}
session_start();
?>
Поскольку ваше приложение является контейнерным, вам необходимо предоставить способ предоставления переменных ENV в приложение. Это можно сделать несколькими способами:
- Во время сборки в файле Dockerfile. Добавьте в предыдущий файл Docker 4 параметра, используя синтаксис ENV DB_VAR=ENV_VAR_VALUE. Это установит значения по умолчанию, которые можно переопределить во время выполнения. Например, «DB_NAME» и «DB_USER» могут быть установлены здесь и нигде больше.
- Во время выполнения . Вы можете настроить эти переменные для Cloud Run как из CLI, так и из пользовательского интерфейса. Это подходящее место для размещения всех ваших 4 переменных (если вы не хотите сохранить значения по умолчанию, установленные в Dockerfile).
На локальном хосте вы можете поместить переменные ENV в файл .env
(проверьте папку решений ).
Также убедитесь, что .env добавлен в ваш .gitignore
: вы не хотите отправлять свои секреты на Github!
echo .env >> .gitignore
После этого вы можете протестировать экземпляр локально:
docker run -it -p 8080:8080 --env-file .env my-php-app-docker
Теперь вы достигли следующего:
- Ваше приложение будет динамически считывать переменную из вашего ENV.
- Вы улучшили безопасность, убрав пароль БД из своего кода)
Теперь вы можете развернуть новую версию в Cloud Run. Давайте перейдем к пользовательскому интерфейсу и вручную установим переменные среды:
- Перейдите на https://console.cloud.google.com/run.
- Нажмите на свое приложение
- Нажмите «Изменить и развернуть новую ревизию».
- На первой вкладке «Контейнер(ы)» нажмите нижнюю вкладку «Переменные и секреты».
- Нажмите «+ Добавить переменную» и добавьте все необходимые переменные. В итоге у вас должно получиться что-то вроде этого:
Это идеально? Нет. Ваш PASS по-прежнему виден большинству операторов. Это можно исправить с помощью Google Cloud Secret Manager.
Вторая итерация: Секретный менеджер
Ваши пароли исчезли из вашего собственного кода: победа! Но подождите, мы уже в безопасности?
Ваши пароли по-прежнему будут видны всем, у кого есть доступ к Google Cloud Console. Фактически, если вы получите доступ к файлу развертывания Cloud Run YAML, вы сможете получить его. Или, если вы попытаетесь отредактировать или развернуть новую версию Cloud Run, пароль будет виден в разделе «Переменные и секреты», как показано на снимках экрана ниже.
Google Cloud Secret Manager — это безопасный централизованный сервис для управления конфиденциальной информацией, такой как ключи API, пароли, сертификаты и другие секреты.
Он позволяет хранить секреты, управлять ими и получать к ним доступ с детальными разрешениями и надежным шифрованием. Secret Manager, интегрированный с системой управления идентификацией и доступом (IAM) Google Cloud, позволяет вам контролировать, кто может получить доступ к определенным секретам, обеспечивая безопасность данных и соответствие нормативным требованиям.
Он также поддерживает автоматическую ротацию секретов и управление версиями, упрощая управление жизненным циклом секретов и повышая безопасность приложений в сервисах Google Cloud.
Чтобы получить доступ к Секретному менеджеру , перейдите из меню «Гамбургер» в «Службы безопасности» и найдите его в разделе «Защита данных» , как показано на снимке экрана ниже.
Включите API Secret Manager, как только вы окажетесь там, как показано на следующем изображении.
- Теперь нажмите « Создать секрет »: Назовем его рационально:
- Имя:
php-amarcord-db-pass
- Секретное значение: « пароль вашей базы данных » (игнорируйте часть «загрузить файл»).
- аннотируйте эту секретную ссылку, она должна выглядеть так:
projects/123456789012/secrets/php-amarcord-db-pass
. Это уникальный указатель на ваш секрет (для Terraform, Cloud Run и других). Этот номер является вашим уникальным номером проекта.
Совет . Попробуйте использовать единообразные соглашения об именах для своих секретов, начиная слева направо, например: cloud-devrel-phpamarcord-dbpass
- Организация (с компанией)
- Команда (внутри организации)
- Заявка (внутри команды)
- Имя переменной (внутри приложения)
Это позволит вам легко использовать регулярные выражения для поиска всех ваших секретов для одного приложения.
Создайте новую версию Cloud Run.
Теперь, когда у нас есть новый секрет, нам нужно избавиться от переменной ENV DB_PASS и заменить ее новым секретом. Так:
- Доступ к Cloud Run с помощью Google Cloud Console
- Выберите приложение.
- Нажмите «Редактировать и развернуть новую версию».
- найдите вкладку «Переменные и секреты».
- Используйте кнопку «+ Ссылка на секрет», чтобы сбросить переменную DB_PASS ENV.
- Используйте тот же «DB_PASS» для указанных секретов и используйте последнюю версию.
После этого вы должны получить следующую ошибку
Постарайтесь придумать, как это исправить. Чтобы решить эту проблему, вам необходимо получить доступ к разделу IAM & Admin и изменить разрешения на предоставление. Удачной отладки!
Как только вы это выясните, вернитесь в Cloud Run и повторно разверните новую версию. Результат должен выглядеть как на следующем рисунке:
Совет : консоль разработчика (пользовательский интерфейс) отлично подходит для выявления проблем с разрешениями. Найдите время, чтобы просмотреть все ссылки для ваших облачных объектов!
7. Модуль 5. Настройка CI/CD с помощью Cloud Build
Зачем нужен конвейер CI/CD?
К этому моменту вы уже должны были набрать gcloud run deploy
несколько раз, возможно, отвечая на один и тот же вопрос снова и снова.
Устали развертывать приложение вручную с помощью gcloud run Deploy? Разве не было бы здорово, если бы ваше приложение могло автоматически развертываться каждый раз, когда вы добавляете новое изменение в свой репозиторий Git?
Чтобы использовать конвейер CI/CD, вам понадобятся две вещи:
- Персональный репозиторий Git . К счастью, вы уже должны были подключить репозиторий Workshop к своей учетной записи GitHub на шаге 2. Если нет, вернитесь и завершите этот шаг. Ваш раздвоенный репозиторий должен выглядеть следующим образом:
https://github.com/<YOUR_GITHUB_USER>/app-mod-workshop
- Облачная сборка . Этот замечательный и дешевый сервис позволяет настроить автоматизацию сборки практически для всего: Terraform, док-приложений и т. д.
В этом разделе основное внимание будет уделено настройке Cloud Build.
Вступайте в облачную сборку!
Для этого мы будем использовать Cloud Build:
- создайте свой исходный код (с помощью Dockerfile). Думайте об этом как о «большом ZIP-файле», который содержит все необходимое для его сборки и запуска («ваш «артефакт сборки»).
- отправить этот артефакт в реестр артефактов (AR).
- Затем выполните развертывание из AR в Cloud Run для приложения «php-amarcord».
- Это создаст новую версию («ревизию») существующего приложения (представьте себе слой с новым кодом), и мы настроим его для перенаправления трафика на новую версию в случае успешной отправки.
Это пример некоторых сборок моего приложения php-amarcord
:
Как нам все это сделать?
- Создав один идеальный файл YAML:
cloudbuild.yaml
- Создав триггер Cloud Build.
- Подключившись к нашему репозиторию на GitHub через интерфейс Cloud Build .
Создать триггер (и подключить репозиторий)
- Перейдите на https://console.cloud.google.com/cloud-build/triggers.
- Нажмите «Создать триггер».
- Скомпилировать:
- Имя: что-то значимое, например
on-git-commit-build-php-app
- Событие: Нажмите на ветку
- Источник: «Подключить новый репозиторий»
- Откроется окно справа: «Подключить репозиторий».
- Поставщик исходного кода: Github (первый)
- "Продолжать"
- Аутентификация откроет окно на github для перекрестной аутентификации. Следуйте за потоком и будьте терпеливы. Если у вас много репозиториев, это может занять некоторое время.
- «Выбрать репо» Выберите свою учетную запись/репо и отметьте часть «Я понимаю…».
- Если вы получили сообщение об ошибке : Приложение GitHub не установлено ни в одном из ваших репозиториев, нажмите «Установить Google Cloud Build» и следуйте инструкциям.
Нажмите «Подключиться».
- Бинго! Ваше репо теперь подключено.
- Вернемся к триггерной части....
- Конфигурация: определяется автоматически (*)
- Дополнительно: выберите учетную запись службы «[PROJECT_NUMBER] -compute@developer.gserviceaccount.com ».
- ххххх — это идентификатор вашего проекта
- Учетная запись вычислительной службы по умолчанию подходит для лабораторного подхода — не используйте ее в рабочей среде! ( Узнать больше ).
- все остальное оставь как есть.
- Нажмите на кнопку «Создать».
(*) Это самый простой способ, поскольку он проверяет наличие Dockerfile или cloudbuild.yaml. Однако cloudbuild.yaml
дает вам реальную возможность решать, что делать на каком этапе.
У меня есть сила!
Теперь триггер не будет работать, если вы не укажете учетную запись службы Cloud Build (что такое учетная запись службы? Электронная почта «робота», который действует от вашего имени для выполнения задачи — в данном случае создание чего-либо в облаке!).
Ваш SA не сможет построить и развернуть, если вы не уполномочите его сделать это. К счастью, это легко!
- перейдите в «Облачная сборка» > « Настройки ».
- Учетная запись службы «[PROJECT_NUMBER]- Compute@developer.gserviceaccount.com »
- Отметьте эти поля:
- Облачный бег
- Секретный менеджер
- Сервисные аккаунты
- Облачная сборка
- Также отметьте «Установить в качестве предпочтительной учетной записи службы».
Где YAML для облачной сборки?
Мы настоятельно рекомендуем вам потратить некоторое время на создание собственной облачной сборки YAML.
Однако, если у вас нет времени или вы не хотите его уделять, вы можете почерпнуть вдохновение в этой папке решений: .solutions
Теперь вы можете отправить изменение на github и наблюдать за Cloud Build.
Настройка Cloud Build может оказаться сложной задачей. Ожидайте немного взад и вперед:
- Проверка журналов в https://console.cloud.google.com/cloud-build/builds;region=global
- Находим свою ошибку.
- Исправляем код и перевыпускаем git commit/git push.
- Иногда ошибка не в коде, а в какой-то конфигурации. В этом случае вы можете запустить новую сборку из пользовательского интерфейса (облачная сборка > «Триггеры» > «Выполнить»).
Обратите внимание: если вы используете это решение, вам еще предстоит поработать. Например, вам нужно установить переменные ENV для вновь созданных конечных точек dev/prod:
Вы можете сделать это двумя способами:
- Через пользовательский интерфейс — снова установив переменные ENV.
- Через CLI , создав для вас «идеальный» сценарий. Пример можно найти здесь: gcloud-run-deploy.sh . Вам нужно настроить несколько вещей, например, конечную точку и номер проекта; Номер вашего проекта можно найти в обзоре облака .
Как мне зафиксировать код на github?
В задачи этого семинара не входит научить вас лучшему способу перехода git push
на github. Однако если вы застряли и находитесь в Cloud Shell, есть два способа:
- Интерфейс командной строки . Добавьте ssh-ключ локально и добавьте удаленный доступ с помощью git@github.com : YOUR_USER/app-mod-workshop.git (вместо http).
- VSCode . Если вы используете редактор Cloud Shell, вы можете использовать вкладку «Управление версиями» (ctrl-shift-G), нажать «Синхронизировать изменения» и следовать инструкциям. У вас должна быть возможность аутентифицировать свою учетную запись github в vscode, и извлечение/отправка оттуда станет проще простого.
Не забудьте git add clodubuild.yaml
среди других файлов, иначе это не сработает.
Deep vs Shallow «паритет разработчиков и продуктов» [необязательно]
Если вы скопировали версию модели отсюда , у вас будут две идентичные версии DEV и PROD. Это круто и соответствует правилу 10 приложения «Двенадцать факторов» .
Однако мы используем две разные конечные точки веб-сайта, чтобы приложение ссылалось на одну и ту же базу данных. Этого достаточно для семинара; однако в реальной жизни вам нужно потратить некоторое время на создание подходящей рабочей среды. Это означает наличие двух баз данных (одну для разработки и одну для рабочей версии), а также выбор места их размещения для аварийного восстановления/высокой доступности. Это выходит за рамки данного семинара, но дает пищу для размышлений.
Если у вас есть время на «глубокую» версию производства, имейте в виду все ресурсы, которые вам необходимо дублировать, например:
- База данных Cloud SQL (и, возможно, экземпляр SQL).
- сегмент GCS
- Облачная функция.
- Вы можете использовать Gemini 1.5 Flash в качестве модели для разработки (дешевле, быстрее) и Gemini 1.5 Pro (более мощная).
В общем, каждый раз, когда вы что-то делаете с приложением, подумайте критически: должно ли производство иметь такую же ценность или нет? А если нет, дублируйте свои усилия. Это, конечно, намного проще с Terraform, где вы можете добавить свою среду (-dev, -prod) в качестве суффикса к вашим ресурсам.
8. Модуль 6. Переход в облачное хранилище Google
Хранилище
В настоящее время приложение хранит состояние в контейнере докера. Если машина сломается, приложение взорвется или просто если вы отправите новую версию , будет запланирована новая версия с новым пустым хранилищем: 🙈
Как мы это исправим? существует ряд подходов.
- Храните изображения в БД. Это то, что я сделал с моим предыдущим PHP-приложением. Это самое простое решение, поскольку оно не усложняет задачу. Но это наверняка увеличивает задержку и нагрузку на вашу БД!
- Перенесите свое приложение Cloud Run на решение, удобное для хранения данных: GCE + постоянный диск ? Может быть, GKE + Storage ? Примечание: то, что вы получаете в контроле, вы теряете в ловкости.
- Перейдите в GCS . Google Cloud Storage предлагает лучшее в своем классе хранилище для всего Google Cloud и является наиболее идиоматическим облачным решением. Однако это требует от нас работы с библиотеками PHP . Есть ли у нас библиотеки PHP 5.7 для GCS ? Поддерживает ли
PHP 5.7
Composer
(похоже, PHP 5.3.2 — самая ранняя версия , поддерживаемая Composer)? - Может быть, использовать коляску-докер ?
- Или, может быть, использовать GCS Cloud Run Volume Mounts . Это звучит потрясающе.
🤔 Перенос хранилища (открытое)
[Открытое окончание] В этом упражнении мы хотим, чтобы вы нашли решение, позволяющее переместить ваши изображения таким образом, чтобы они каким-то образом сохранялись.
Приемочный тест
Я не хочу рассказывать вам решение, но я хочу, чтобы это произошло:
- Вы загружаете
newpic.jpg
. Вы видите это в приложении. - Вы обновляете приложение до новой версии.
-
newpic.jpg
все еще виден.
💡 Возможное решение (монтирование тома GCS Cloud Run)
Это очень элегантное решение, которое позволяет нам осуществлять загрузку файлов с сохранением состояния, ВООБЩЕ не трогая код (кроме показа описания изображения, но это тривиально и просто для удовольствия глаз).
Это должно позволить вам смонтировать папку из Cloud Run в GCS, поэтому:
- Все загрузки в GCS будут видны в вашем приложении.
- Все загрузки в ваше приложение будут фактически загружены в GCS.
- С объектами, загруженными в GCS, произойдет волшебство (глава 7).
Примечание . Пожалуйста, прочтите мелкий шрифт ПРЕДОХРАНИТЕЛЯ. Это НЕ нормально, если производительность является проблемой.
Создайте сегмент GCS
GCS — это вездесущий сервис хранения данных Google Cloud. Он проверен в боевых условиях и используется каждым сервисом GCP, которому требуется хранилище.
Обратите внимание, что Cloud Shell экспортирует PROJECT_ID как GOOGLE_CLOUD_PROJECT:
$ export PROJECT_ID=$GOOGLE_CLOUD_PROJECT
#!/bin/bash
set -euo pipefail
# Your Cloud Run Service Name, eg php-amarcord-dev
SERVICE_NAME='php-amarcord-dev'
BUCKET="${PROJECT_ID}-public-images"
GS_BUCKET="gs://${BUCKET}"
# Create bucket
gsutil mb -l "$GCP_REGION" -p "$PROJECT_ID" "$GS_BUCKET/"
# Copy original pictures there - better if you add an image of YOURS before.
gsutil cp ./uploads/*.png "$GS_BUCKET/"
Настройте Cloud Run для подключения корзины в папке /uploads/.
Теперь перейдем к элегантной части. Мы создаем том php_uploads
и указываем Cloud Run выполнить монтирование FUSE по MOUNT_PATH
(что-то вроде /var/www/html/uploads/
):
#!/bin/bash
set -euo pipefail
# .. keep variables from previous script..
# Uploads folder within your docker container.
# Tweak it for your app code.
MOUNT_PATH='/var/www/html/uploads/'
# Inject a volume mount to your GCS bucket in the right folder.
gcloud --project "$PROJECT_ID" beta run services update "$SERVICE_NAME" \
--region $GCP_REGION \
--execution-environment gen2 \
--add-volume=name=php_uploads,type=cloud-storage,bucket="$BUCKET" \
--add-volume-mount=volume=php_uploads,mount-path="$MOUNT_PATH"
Теперь повторите этот шаг для всех конечных точек, которые вы хотите указать на Cloud Storage.
Вы также можете добиться того же из пользовательского интерфейса
- На вкладке «Тома» создайте тома, указывающие на вашу корзину, типа «Корзина облачного хранилища», например, с именем «php_uploads».
- В разделе «Контейнер(ы)» > «Подключение тома» смонтируйте только что созданный том в точке тома, запрошенной вашим приложением. Это зависит от файла dockerfile, но может выглядеть так:
var/www/html/uploads/
.
В любом случае, если это работает, редактирование новой версии Cloud Run должно показать вам что-то вроде этого:
Теперь протестируйте новое приложение, загрузив одно новое изображение в конечную точку /upload.php
.
Изображения должны плавно передаваться в GCS без написания единой строки PHP:
Что только что произошло?
Произошло что-то очень волшебное.
Старое приложение со старым кодом все еще выполняет свою работу. Новый модернизированный стек позволяет нам удобно размещать все изображения/изображения в нашем приложении в облачном ведре с сохранением состояния. Теперь небо - это предел:
- Хотите отправлять электронное письмо каждый раз, когда появляется изображение со словами «опасно» или «обнаженное»? Вы можете сделать это, не касаясь кода PHP.
- Хотите использовать мультимодальную модель Gemini каждый раз, когда появляется изображение для ее описания, и загружать БД с его описанием? Вы можете сделать это, не касаясь кода PHP. Ты мне не веришь? Продолжайте читать главу 7.
Мы только что открыли здесь большие возможности.
9. Модуль 7. Расширьте возможности своего приложения с помощью Google Gemini
Теперь у вас есть потрясающее модернизированное и новое блестящее PHP-приложение (например, Fiat 126
2024 года) с облачным хранилищем.
Что с этим можно сделать?
Предварительные условия
В предыдущей главе типовое решение позволяло нам монтировать изображения /uploads/
в GCS, фактически отделяя логику приложения от хранилища изображений.
Это упражнение требует от вас:
- Успешно выполнили упражнение в главе 6 (хранение).
- Создайте корзину GCS с загрузкой изображений, куда люди загружают изображения в ваше приложение, и изображения передаются в вашу корзину.
Настройте функцию облака (на Python)
Вы когда-нибудь задумывались, как реализовать приложение, управляемое событиями ? Что-то вроде:
- когда произойдет <событие > => отправить электронное письмо
- когда происходит <событие> => если <условие> истинно, обновите базу данных.
Событием может быть что угодно: новая запись, доступная в BigQuery, изменение нового объекта в папке в GCS или новое сообщение, ожидающее очереди в Pub/Sub.
Google Cloud поддерживает несколько парадигм для достижения этой цели. В частности:
- EventArc . Узнайте, как получать события GCS . Отлично подходит для создания групп DAG и координации действий на основе if-then-else в облаке.
- Облачный планировщик . Например, отлично подходит для полуночного cron в облаке.
- Облачные рабочие процессы . Аналогично Event Arc, позволяет вам
- Функции облачного запуска (известные как
lambdas
). - Облачный композитор . По сути, Google-версия Apache Airflow , также отлично подходит для DAG .
В этом упражнении мы углубимся в Cloud Function, чтобы добиться весьма впечатляющего результата. И мы предоставим вам дополнительные упражнения.
Обратите внимание, что пример кода представлен в разделе .solutions/
Настройте функцию облака (🐍 python)
Мы пытаемся создать очень амбициозный ЗКФ.
- Когда в GCS создается новое изображение.. (вероятно, потому что кто-то загрузил его в приложение - но не только)
- .. позвоните Gemini, чтобы описать его и получить текстовое описание изображения .. (было бы неплохо проверить MIME и убедиться, что это изображение, а не PDF, MP3 или текст)
- .. и обновите БД этим описанием. (для этого может потребоваться исправление БД для добавления столбца
description
в таблицуimages
).
Исправьте БД, чтобы добавить description
к изображениям.
- Откройте Cloud SQL Studio:
- Введите своего пользователя и пароль для базы данных изображений.
- Введите этот SQL, который добавляет столбец для описания изображения:
ALTER TABLE images ADD COLUMN description TEXT;
И бинго! Попробуйте сейчас проверить, сработало ли это:
SELECT * FROM images;
Вы должны увидеть новый столбец описания:
Напишите Близнецы f(x)
Примечание . Эта функция была фактически создана с помощью помощника Gemini Code .
Примечание . Создавая эту функцию, вы можете столкнуться с ошибками разрешений IAM. Некоторые из них описаны ниже в разделе «Возможные ошибки».
- Включите API
- Перейдите на https://console.cloud.google.com/functions/list.
- Нажмите «Создать функцию».
- Включите API из мастера API:
Вы можете создать GCF из пользовательского интерфейса или из командной строки. Здесь мы будем использовать командную строку.
Возможный код можно найти в разделе .solutions/
- Создайте папку для размещения вашего кода, например «gcf/». Войдите в папку.
- Создайте файл
requirements.txt
:
google-cloud-storage
google-cloud-aiplatform
pymysql
- Создайте функцию Python. Пример кода здесь: gcf/main.py .
#!/usr/bin/env python
"""Complete this"""
from google.cloud import storage
from google.cloud import aiplatform
import vertexai
from vertexai.generative_models import GenerativeModel, Part
import os
import pymysql
import pymysql.cursors
# Replace with your project ID
PROJECT_ID = "your-project-id"
GEMINI_MODEL = "gemini-1.5-pro-002"
DEFAULT_PROMPT = "Generate a caption for this image: "
def gemini_describe_image_from_gcs(gcs_url, image_prompt=DEFAULT_PROMPT):
pass
def update_db_with_description(image_filename, caption, db_user, db_pass, db_host, db_name):
pass
def generate_caption(event, context):
"""
Cloud Function triggered by a GCS event.
Args:
event (dict): The dictionary with data specific to this type of event.
context (google.cloud.functions.Context): The context parameter contains
event metadata such as event ID
and timestamp.
"""
pass
- Нажмите функцию. Вы можете использовать сценарий, подобный этому: gcf/push-to-gcf.sh .
Примечание 1 . Обязательно укажите в ENV правильные значения или просто добавьте их сверху ( GS_BUCKET=blah
, ..):
Примечание 2 . Это приведет к отправке всего локального кода ( .
), поэтому обязательно поместите свой код в определенную папку и используйте .gcloudignore
как профессионал, чтобы избежать размещения огромных библиотек. ( пример ).
#!/bin/bash
set -euo pipefail
# add your logic here, for instance:
source .env || exit 2
echo "Pushing ☁️ f(x)☁ to 🪣 $GS_BUCKET, along with DB config.. (DB_PASS=$DB_PASS)"
gcloud --project "$PROJECT_ID" functions deploy php_amarcord_generate_caption \
--runtime python310 \
--region "$GCP_REGION" \
--trigger-event google.cloud.storage.object.v1.finalized \
--trigger-resource "$BUCKET" \
--set-env-vars "DB_HOST=$DB_HOST,DB_NAME=$DB_NAME,DB_PASS=$DB_PASS,DB_USER=$DB_USER" \
--source . \
--entry-point generate_caption \
--gen2
Примечание . В этом примере generate_caption
будет вызванным методом, а Cloud Function передаст ему событие GCS со всей соответствующей информацией (имя сегмента, имя объекта и т. д.). Потратьте некоторое время на отладку этого события Python dict.
Тестирование функции
Модульные тесты
Функция имеет множество движущихся частей. Возможно, вам захочется протестировать все отдельные из них.
Пример находится в gcf/test.py .
Пользовательский интерфейс облачных функций
Также уделите некоторое время изучению своих функций в пользовательском интерфейсе. Каждую вкладку стоит изучить, особенно Source
(мой любимый), Variables
, Trigger
и Logs
; Вы потратите много времени в Logs
для устранения ошибок (также см. возможные ошибки внизу этой страницы). также не забудьте проверить Permissions
.
E2E-тест
Пришло время вручную протестировать функцию!
- Зайдите в свое приложение и войдите в систему
- Загрузите изображение (не слишком большое, мы видели проблемы с большими изображениями)
- проверьте пользовательский интерфейс, изображение загружено.
- Проверьте в Cloud SQL Studio , что описание обновлено. Войдите в систему и выполните этот запрос:
SELECT * FROM images
.
И это работает! Возможно, мы также захотим обновить интерфейс, чтобы отобразить это описание.
Обновите PHP, чтобы показать [необязательно]
Мы доказали, что приложение работает. Однако было бы неплохо, чтобы пользователи также могли видеть это описание.
Нам не нужно быть экспертом по PHP, чтобы добавить описание в index.php
. Этот код должен подойти (да, Gemini написал его и для меня!):
<?php if (!empty($image['description'])): ?>
<p class="font-bold">Gemini Caption:</p>
<p class="italic"><?php echo $image['description']; ?></p>
<?php endif; ?>
Разместите этот код внутри foreach
по своему вкусу.
На следующих шагах мы также увидим более красивую версию пользовательского интерфейса благодаря Gemini Code Assist. Красивая версия может выглядеть так:
Выводы
У вас есть облачная функция, активируемая при попадании новых объектов в GCS, которая может аннотировать содержимое изображения, как это мог бы сделать человек, и автоматически обновлять БД. Ух ты!
Что дальше? Вы можете следовать тем же рассуждениям, чтобы достичь двух замечательных функций.
[необязательно] Добавьте дополнительные облачные функции [открытый вариант]
На ум приходит пара дополнительных функций.
📩 Триггер по электронной почте
Триггер по электронной почте , который отправляет вам электронное письмо каждый раз, когда кто-то отправляет изображение.
- Слишком часто? Добавьте дополнительное ограничение: БОЛЬШОЕ изображение или изображение, содержание Gemini которого содержит слова «обнаженная натура/нагота/насилие».
- Рассмотрите возможность проверки
EventArc
для этого.
🚫 Автоматическая модерация неприемлемых фотографий
В настоящее время администратор помечает изображения как «неприемлемые». Как насчет того, чтобы Близнецы выполняли тяжелую работу и модерировали пространство? Добавьте тест для выявления недопустимого содержимого триггера и обновите базу данных, как мы узнали в предыдущей функции. Это означает, что вы берете предыдущую функцию, меняете подсказку и обновляете БД на основе ответа.
Предостережение . Генеративный ИИ имеет непредсказуемые результаты. Убедитесь, что «творческий результат» Близнецов поставлен «на рельсы». Вы можете задать детерминированный ответ, например, оценку достоверности от 0 до 1, JSON и т. д. Этого можно добиться разными способами, например: * Использование библиотек Python pydantic
, langchain
, ... * Использование структурированного вывода Gemini .
Кончик . У вас может быть НЕСКОЛЬКО функций или одно приглашение, которое обеспечивает ответ JSON (работает отлично с «структурированным выводом Gemini», как указано выше), например:
Какова будет подсказка для создания этого?
{
"description": "This is the picture of an arrosticino",
"suitable": TRUE
}
Вы можете добавить в подсказку дополнительные поля, чтобы получить информацию, например: есть ли в этом что-то хорошее? Плохо это? Вы узнали это место? Есть ли текст (распознавание текста еще никогда не было таким простым):
-
goods
: «Похоже на вкусную еду» -
bads
: «Это похоже на нездоровую еду» -
OCR
: «Предпочтительно потреблять до 10 ноября 2024 г.» -
location
: «Пескара, Лунгомаре»
Хотя обычно лучше иметь N- функцию для N результатов, невероятно полезно создать функцию, которая выполняет 10 действий. Прочтите эту статью Риккардо, чтобы узнать, как это сделать.
Возможные ошибки (в основном IAM/разрешения)
Когда я впервые разработал это решение, я столкнулся с некоторыми проблемами с разрешениями IAM. Я добавлю их сюда для сочувствия и для того, чтобы дать несколько идей, как их исправить.
Ошибка: недостаточно разрешений для сервисной учетной записи.
- Обратите внимание, что для развертывания функции GCF, которая прослушивает сегмент GCS, вам необходимо настроить соответствующие разрешения для учетной записи службы, которую вы используете для задания, как показано на рисунке:
Возможно, вам также придется включить API EventArc — и это за несколько минут до того, как они станут полностью доступными.
Ошибка: отсутствует средство вызова Cloud Run.
- Еще один комментарий из пользовательского интерфейса для разрешений GCF: ( роль Invoker для запуска облака ):
Эту ошибку можно исправить, выполнив команду из образа, аналогичную fix-permissions.sh.
Эта проблема описана здесь: https://cloud.google.com/functions/docs/securing/authentication.
Ошибка: превышен лимит памяти.
При первом запуске в моих журналах могло быть написано: «Превышен лимит памяти в 244 МБ при использовании 270 МБ. Рассмотрите возможность увеличения лимита памяти, см. https://cloud.google.com/functions/docs/configuring/memory ». Опять же, добавьте ОЗУ к вашему GCF. Это очень легко сделать в пользовательском интерфейсе. Вот возможная шишка:
Кроме того, вы также можете исправить сценарий развертывания в облаке, чтобы увеличить нагрузку на MEM/CPU. Это занимает немного больше времени.
Ошибка: опубликовано в PubSub.
Создание триггера с помощью GCF v1 однажды привело к этой ошибке:
Опять же, это легко исправить, зайдя в IAM и назначив своей учетной записи службы роль «Издатель Pub/Sub».
Ошибка: Vertex AI не использовался.
Если вы получили эту ошибку:
В разрешении отказано: 403 Vertex AI API ранее не использовался в проекте YOUR_PROJECT или отключен. Включите его, посетив https://console.developers.google.com/apis/api/aiplatform.googleapis.com/overview?project=YOR_PROJECT.
Вам просто нужно включить API Vertex AI. Самый простой способ включить ВСЕ необходимые API:
- https://console.cloud.google.com/vertex-ai
- Нажмите «Включить все рекомендуемые APIS».
Ошибка: Триггер EventArc не найден.
Если вы получили это, повторите развертывание функции.
Ошибка: 400 агентов службы подготавливаются.
Подготавливаются 400 сервисных агентов ( https://cloud.google.com/vertex-ai/docs/general/access-control#service-agents ). Сервисные агенты необходимы для чтения предоставленного файла Cloud Storage. Поэтому повторите попытку через несколько минут.
Если это произойдет, подождите некоторое время или спросите специалиста Google.
10. Модуль 8: Создание SLO доступности
В главе мы пытаемся добиться этого:
- Создание SLI
- Создание SLO на основе SLI
- Создание оповещений на основе SLO
Это очень дорогая тема автору, поскольку Риккардо работает в направлении SRE/DevOps Google Cloud.
(неограниченный) Создайте SLI и SLO для этого приложения.
Насколько хорошо приложение, если вы не можете определить, когда оно не работает?
Что такое СЛО?
О боже! Google изобрел SLO! Чтобы узнать больше об этом, я могу предложить:
- Книга SRE – глава 2 – Реализация SLO . ( 👉 еще SREbooks )
- Искусство SLO ( потрясающее видео ). Это потрясающий тренинг, позволяющий узнать больше о том, как создать идеальный SLO для вашего сервиса.
- Курс SRE на Coursera . Я внес в это свой вклад!
Шаг 1. Создайте доступность SLI/SLO
Начнем с доступности SLO, поскольку это самая простая и, возможно, самая важная вещь, которую вы хотите измерить.
К счастью, благодаря Istio Cloud run уже имеет встроенную поддержку SLO.
Когда ваше приложение запущено в облаке, добиться этого очень просто: у меня это занимает 30 секунд.
- Перейдите на страницу Cloud Run.
- Нажмите/выберите свое приложение.
- Выберите вкладку
SLOs
. - Нажмите «+ Создать SLO».
- Доступность , По запросу
- Продолжать
- Календарный месяц / 99%.
- нажмите «Создать SLO».
Шаг 2. Настройте оповещения для этого SLO.
Я предлагаю создать 2 оповещения:
- Один с низкой скоростью сжигания («Slowburn»), чтобы предупредить вас по электронной почте (имитирует билет с низкой ценой).
- Один с высокой скоростью сжигания («Fastburn»), чтобы оповещать вас через SMS (имитирует билет / пейджер с высокой ценой)
Перейдите на предыдущую SLO tab
.
Сделайте это дважды:
- Нажмите «Создать оповещение SLO» (кнопка 🔔 с плюсом внутри справа)
- Продолжительность ретроспективного анализа, пороговое значение Burnrate:
- [БЫСТРЫЙ]. Первый:
60
мин /10
х - [МЕДЛЕННЫЙ]. Второй:
720
мин /2
х - Канал уведомлений: нажмите «Управление каналами уведомлений».
- Сначала «Электронная почта» -> Добавить новое -> ..
- Второе: «СМС» -> Добавить новое -> Подтвердить на телефоне.
- Совет: мне нравится использовать в именах смайлы! Это развлечение для демо.
- когда закончите, нажмите большой X в правом верхнем углу.
- Сначала выберите телефон (быстро), затем электронную почту (медленно).
- Добавьте пример документации, например:
-
[PHP Amarcord] Riccardo told me to type sudo reboot or to check documentation in http://example.com/playbooks/1.php but I guess he was joking
.
Бинго!
Окончательный результат
Мы можем считать это упражнение завершенным, как только у вас будет 1 работающий SLO + 2 оповещения о вашей доступности, а также оповещения на вашу электронную почту и на телефон.
Если вы хотите, вы можете добавить задержку (и я настоятельно рекомендую вам это сделать) или даже более сложную. Для задержки выберите задержку, которую вы считаете разумной; если сомневаетесь, выберите 200 мс .
11. Следующие шаги
Вы выполнили ВСЕ, чего не хватает?
Немного пищи для размышления:
Играйте с Близнецами
Вы можете использовать Gemini в двух вариантах:
- Вертекс ИИ. «Путь предприятия», переплетенный с вашим GCP, который мы рассмотрели в главе 7 (GCF+Gemini). Вся аутентификация волшебным образом работает, а сервисы прекрасно взаимодействуют между собой.
- Гугл ИИ. «Потребительский путь». Здесь вы получаете ключ Gemini API и начинаете создавать небольшие сценарии, которые можно привязать к любой уже имеющейся у вас рабочей нагрузке (собственная работа, другие облака, локальный хост и т. д.). Вы просто подставляете свой ключ API, и код волшебным образом начинает работать.
Мы рекомендуем вам попробовать изучить (2) с помощью своих собственных любимых проектов.
Поднятие пользовательского интерфейса
Я плохо разбираюсь в пользовательском интерфейсе. Но Близнецы есть! Вы можете просто взять одну страницу PHP и сказать что-то вроде этого:
I have a VERY old PHP application. I want to touch it as little as possible. Can you help me:
1. add some nice CSS to it, a single static include for tailwind or similar, whatever you prefer
2. Transform the image print with description into cards, which fit 4 per line in the canvas?
Here's the code:
-----------------------------------
[Paste your PHP page, for instance index.php - mind the token limit!]
Вы можете легко получить это менее чем за 5 минут, на расстоянии одной сборки Cloud! :)
Ответ Близнецов был безупречным (то есть мне не пришлось ничего менять):
А вот новая верстка в личном приложении автора:
Примечание. Код вставлен как изображение, поскольку мы не хотим поощрять вас брать код, а хотим, чтобы Gemini написала код за вас с вашими собственными творческими ограничениями пользовательского интерфейса/интерфейса; поверьте мне, после этого у вас останутся очень незначительные изменения.
Безопасность
Надлежащая защита этого приложения не является целью этого 4-часового семинара, поскольку это увеличит время завершения этого семинара на 1-2 порядка.
Однако эта тема сверхважна! Мы собрали несколько идей в SECURITY
.
12. Поздравляем!
Поздравляем 🎉🎉🎉, вы успешно модернизировали свое устаревшее PHP-приложение с помощью Google Cloud.
Вкратце, в этой кодовой лаборатории вы узнали:
- Как развернуть базу данных в Google Cloud SQL и как перенести в нее существующую базу данных.
- Как контейнеризировать ваше PHP-приложение с помощью Docker и Buildpacks и сохранить его образ в реестре Google Cloud Artifact.
- Как развернуть контейнерное приложение в Cloud Run и заставить его работать с Cloud SQL
- Как тайно хранить/использовать конфиденциальные параметры конфигурации (например, пароль БД) с помощью Google Secret Manager
- Как настроить конвейер CI/CD с помощью Google Cloud Build для автоматической сборки и развертывания вашего PHP-приложения при любой отправке кода в ваш репозиторий GitHub.
- Как использовать Cloud Storage для «облака» ресурсов вашего приложения
- Как использовать бессерверные технологии для создания потрясающих рабочих процессов на базе Google Cloud, не затрагивая код вашего приложения.
- Используйте мультимодальные возможности Gemini для подходящего сценария использования.
- Внедрение принципов SRE в Google Cloud
Это отличное начало вашего пути к модернизации приложений с помощью Google Cloud!
🔁 Обратная связь
Если вы хотите рассказать нам о своем опыте участия в этом семинаре, заполните эту форму обратной связи .
Мы будем рады вашим отзывам, а также рекламным сообщениям о фрагментах кода, которыми вы особенно гордитесь.
🙏 Спасибо
Автор хотел бы поблагодарить Мирко Джилиоли и Маурицио Ипсале из Datatonic за помощь в написании и тестировании решения.