1. 简介
上次更新日期:2024 年 11 月 1 日
如何将旧版 PHP 应用升级到 Google Cloud?
(📽️ 观看 7 分钟的介绍视频,了解此 Codelab)
在本地运行且需要进行现代化改造的旧式应用是很常见的。这意味着,使其可在不同环境中进行扩缩、安全且可部署。
在本研讨会中,您将:
- 将 PHP 应用容器化。
- 移至代管式数据库服务 ( Cloud SQL)。
- 部署到 Cloud Run(它是 GKE/Kubernetes 的零运维替代方案)。
- 使用 Identity and Access Management (IAM) 和 Secret Manager 保护应用。
- 通过 Cloud Build 定义 CI/CD 流水线。例如,Cloud Build 可以与在热门 Git 提供商(如 GitHub 或 GitLab)上托管的 Git 代码库相关联,并且可在任何推送到主库时触发。
- 在 Cloud Storage 上托管应用图片。这是通过挂载实现的,无需代码即可更改应用。
- 通过 Gemini 引入 Gen AI 功能,并通过 Cloud Functions(无服务器)进行编排。
- 熟悉 SLO 并运行新刷新的应用。
按照这些步骤,您可以逐步改进 PHP 应用,提高其可扩展性、安全性和部署灵活性。此外,通过迁移到 Google Cloud,您可以利用其强大的基础架构和服务,确保您的应用在云原生环境中顺畅运行。
我们相信,您通过这些简单的步骤学到的内容可以应用于具有不同语言/堆栈和不同使用情形的您自己的应用和组织。
应用简介
您将要创建分支的应用(代码,依据 MIT 许可)是一个基于 MySQL 身份验证的基本 PHP 5.7 应用。该应用的主要理念是提供一个平台,供用户上传照片,并让管理员能够标记不当图片。该应用包含两个表:
- 用户。已预编译,并包含管理员。新用户可以注册。
- 图片。附带一些示例图片。登录后的用户可以上传新照片。我们将在此处添加一些魔法。
您的目标
我们希望对旧版应用进行现代化改造,以便将其迁移到 Google Cloud。我们将利用其工具和服务,通过 Cloud SQL、Cloud Run、Cloud Build、Secret Manager 等服务来提升可伸缩性、增强安全性、自动执行基础架构管理,并集成图片处理、监控和数据存储等高级功能。
更重要的是,我们希望分步完成,以便您了解每个步骤背后的思考过程,通常每个步骤都会为后续步骤开启新的可能性(例如:模块 2 -> 3,以及 6 -> 7)。
还在犹豫不决?请观看 YouTube 上的这段 7 分钟视频。
所需条件
- 一台已连接到互联网且装有浏览器的计算机。
- 部分 GCP 赠金。请向您当地的 Google 爱好者寻求帮助 ;)
gcloud
命令正在运行。- 你在本地工作吗?请点击此处下载。您还需要一些实用的编辑器(例如 vscode 或 intellij)。
- 想在云端执行一切操作吗?然后,您可以使用 Cloud Shell。
- GitHub 用户。您需要使用自己的 Git 代码库对原始代码 🧑?🏻?💻? gdgpescara/app-mod-workshop 进行分支。您需要拥有自己的 CI/CD 流水线(自动提交 -> 构建 -> 部署)
解决方案示例:
- 作者代码库:https://github.com/Friends-of-Ricc/app-mod-workshop
- 每章
.solutions/
文件夹下的原始研讨会代码库。
您可以在本地计算机上参加此研讨会,也可以完全在浏览器中完成。
2. 创建信用和分叉
兑换 GCP 赠金并设置 GCP 环境 [可选]
要举办此研讨会,您需要一个具有部分赠金的结算账号。如果您已有自己的结算系统,则可以跳过此步骤。
创建一个全新的 Google Gmail 账号 (*),以便与您的 GCP 抵用金相关联。请向您的教师索要用于兑换 GCP 抵用金的链接,或访问以下网址使用抵用金:bit.ly/PHP-Amarcord-credits。
使用新创建的账号登录并按照说明操作。
(
) Why do I need a brand new gmail account?*
我们注意到有些用户未通过 Codelab,因为他们的账号(尤其是工作账号或学生电子邮件地址)之前使用过 GCP,并且组织政策 限制了他们操作的能力。我们建议您创建一个新的 Gmail 账号,或者使用之前未接触过 GCP 的现有 Gmail 账号 (gmail.com)。
点击该按钮即可兑换抵用金。
填写以下表单,提供您的名字和姓氏,并同意条款及条件。
您可能需要等待几秒钟,结算账号才会显示在此处:https://console.cloud.google.com/billing
完成后,打开 Google Cloud 控制台并创建一个新项目,点击左上角显示“无组织”的下拉菜单的“项目选择器”。如下所示
如果您没有项目,请创建一个新项目,如以下屏幕截图所示。右上角有一个“新建项目”选项。
请务必按照以下步骤将新项目与 GCP 试用结算账号相关联。
大功告成,您可以使用 Google Cloud Platform 了。如果您是新手,或者只想在 Cloud 环境中执行所有操作,可以通过左上角的以下按钮访问 Cloud Shell 及其编辑器,如下所示。
确保您已在左上角选择了新项目:
未选择(不良):
已选中(良好):
从 GitHub 复制应用
- 前往演示版应用:https://github.com/gdgpescara/app-mod-workshop
- 点击 🍴? 分叉。
- 如果您没有 GitHub 账号,则需要创建一个新账号。
- 您可以根据需要进行修改。
- 使用 git clone 克隆应用代码:https://github.com/<YOUR-GITHUB-USER>/<YOUR-REPO-NAME>
- 使用您喜欢的编辑器打开克隆的项目文件夹。如果您选择 Cloud Shell,可以点击“打开编辑器”执行此操作,如下所示。
如图所示,Google Cloud Shell 编辑器提供了您所需的一切
3. 第 1 单元:创建 SQL 实例
创建 Google Cloud SQL 实例
我们的 PHP 应用将连接到 MySQL 数据库,因此我们需要将其复制到 Google Cloud,以便顺利完成迁移。Cloud SQL 是理想之选,因为它支持您在 Cloud 中运行全代管式 MySQL 数据库。具体步骤如下:
- 前往 Cloud SQL 页面:https://console.cloud.google.com/sql/instances
- 点击“创建实例”
- 启用 API(如有必要)。此过程可能需要几秒钟的时间。
- 选择 MySQL。
- (我们会尽量为您提供价格最实惠的版本,以延长其使用寿命):
- 版本:企业版
- 预设:开发(我们尝试过沙盒,但不起作用)
- Mysql Ver: 5.7(哇,怀旧一下!)
- 实例 ID:选择
appmod-phpapp
(如果您更改此值,请务必相应地更改未来的脚本和解决方案)。 - 密码:您可以随意设置,但请记下 CLOUDSQL_INSTANCE_PASSWORD
- 地区:与您为应用的其余部分选择的地区保持一致(例如,米兰 =
europe-west8
) - 可用区可用性:单可用区(为演示节省费用)
点击“创建实例”按钮以部署 Cloud SQL 数据库;⌛ 此过程大约需要 10 分钟⌛。在此期间,请继续阅读文档;您也可以开始解决下一个模块(“将 PHP 应用容器化”),因为它与第一部分中的此模块没有依赖项(在您修复数据库连接之前)。
注意:此实例的费用应该约为 7 美元/天。请务必在研讨会结束后将其停止。
在 Cloud SQL 中创建 image_catalog 数据库和用户
应用项目附带一个 db/
文件夹,其中包含两个 sql 文件:
- 01_schema.sql:包含用于创建包含 Users 和 Images 数据的两个表的 SQL 代码。
- 02_seed.sql:包含用于将数据注入之前创建的表的 SQL 代码。
创建 image_catalog
数据库后,系统会使用这些文件。为此,请按以下步骤操作:
- 打开您的实例,然后点击“数据库”标签页:
- 点击“创建数据库”
- 将其命名为
image_catalog
(如 PHP 应用配置中所示)。
然后,我们创建数据库用户。这样,我们就可以对 image_catalog 数据库进行身份验证了。
- 现在,点击用户标签页
- 点击“添加用户账号”。
- 用户:我们来创建一个用户:
- 用户名:
appmod-phpapp-user
- 密码:请选择您能记住的密码,或点击“生成”
- 保留“允许任何主机 (%)”。
- 点击“添加”。
针对已知 IP 打开数据库。
请注意,Cloud SQL 中的所有数据库都是“独立”的。您需要明确设置可从中访问的网络。
- 点击您的实例
- 打开“连接”菜单
- 点击“网络”标签页。
- 点击“已获授权的网络”下方的相应位置。现在,添加子网。
- 现在,我们将其设为“不安全”,以便应用正常运行:
- 名称:“全世界的每个人 - 不安全”(让我们提醒自己,这种廉价解决方案也不安全)。
- 网络:“0.0.0.0/0”(注意:这不安全!)
点击“保存”。
您应该会看到与以下类似的内容:
注意:此解决方案是一个很好的折衷方案,可让您在 O(hours) 内完成本研讨会。不过,请查看安全文档,以帮助您确保生产环境中的解决方案安全无虞!
现在该测试数据库连接了!
我们来看看之前创建的 image_catalog
用户是否可用。访问实例中的 Cloud SQL Studio,然后输入要进行身份验证的数据库、用户和密码,如下所示:
现在,您可以打开 SQL 编辑器并继续执行下一部分的操作。
从代码库导入数据库
使用 SQL 编辑器导入 image_catalog 表及其数据。从代码库的 SQL 文件中获取 SQL 代码,并依次执行这些代码。01_schema.sql,然后是 02_seed.sql。
之后,您应该会在 image_catalog 中看到两个表,即 users 和 images,如下所示:
您可以通过在编辑器中运行以下命令来测试:select * from images;
此外,请务必记下公共 IP 地址,稍后您将用到它。
4. 第 2 单元:将 PHP 应用容器化
我们希望将此应用构建为云端应用。
这意味着,您需要将代码打包到某种 ZIP 文件中,其中包含在云端运行该代码所需的所有信息。
您可以通过以下几种方式打包它:
- Docker。非常受欢迎,但正确设置起来非常复杂。
- Buildpack。不太常用,但往往会“自动猜测”要构建和运行的内容。通常它就是有效的!
在本研讨会中,我们假设您使用的是 Docker。
Docker
如果您希望掌控一切,这是一个不错的解决方案。当您需要配置特定库并注入某些不明显的行为(上传中的 chmod、应用中的非标准可执行文件等)时,这很有用。
由于我们最终希望将容器化应用部署到 Cloud Run,因此请查看以下文档,并尝试填写空白。目前,我们只提供基本功能,以便您轻松上手。最终的 Dockerfile 将如下所示:
# Use an official PHP image with Apache
# Pull a suitable php image
FROM __________# Define the env variable for the Apache listening port 8080
ENV __________
# Set working directory inside the container
WORKDIR __________
# Install required PHP extensions: PDO, MySQL, and other dependencies
RUN __________
# Copy all application files into the container
COPY __________
# Configure Apache to listen on port 8080. Use ‘sed' command to change the default listening port.
RUN __________
# When in doubt, always expose to port 8080
EXPOSE __________
# Start Apache in the foreground
CMD __________
此外,为了在本地测试我们的应用,我们需要更改 config.php 文件,以便我们的 PHP 应用能够连接到 Google CloudSQL 上可用的 MySQL 数据库。根据您以前设置的内容,在空白处填写内容。
- Db_host 是 Cloud SQL 的公共 IP 地址,您可以在控制台中找到它:
- Db_name 应保持不变:
image_catalog
- Db_user 应为
appmod-phpapp-user
- Db_pass 是您选择的。使用单引号进行设置,并根据需要进行转义。
<?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();
?>
此外,您随时可以在 Gemini 的帮助下将一些意大利语内容翻译成英语!
好的,现在您已经有了 Dockerfile,并将 PHP 应用配置为连接到数据库,接下来我们来试一试!
如果您还没有 Docker,请安装它(链接)。如果您使用的是 Cloud Shell,就不需要安装这个版本(这有多酷?)。
现在,尝试使用适当的 docker build 和 run 命令构建和运行容器化 PHP 应用。
- docker build -t <IMAGE_TAG_NAME> .
- docker run -it -p <CONTAINER PORT>:<LOCAL MACHINE PORT> <IMAGE_TAG_NAME>
如果一切正常,您在连接到本地主机后应该会看到以下网页。
如果您使用的是 Cloud Shell,还可以将本地端口(例如 8080)导出到浏览器,如下所示:
docker build -t my-php-app-docker app-mod-workshop/ -f Dockerfile
docker run -it -p 8080:8080 my-php-app-docker
现在,您知道应用在端口 8080 上运行,请点击“网页预览”图标(带有眼睛的浏览器),然后点击在端口 8080 上预览(对于任何其他端口,请点击“更改端口”)
在浏览器中测试结果
现在,您的应用应如下所示:
如果您使用 Admin/admin123 登录,则应该会看到如下内容。
太棒了!正在处理 🎉🎉🎉
如果您的 dockerization 不错,但数据库凭据有误,您可能会收到如下内容:
请再试一次,您已经很接近了!
Buildpack [可选]
借助 Buildpack,应用会自动构建。很遗憾,您无法完全控制,因此最终可能会出现意外配置。
- 如需了解 GCP 上的 Buildpack,请参阅 https://cloud.google.com/docs/buildpacks/build-application 和此处
- 安装
pack
:https://buildpacks.io/docs/for-platform-operators/how-to/integrate-ci/pack/ - PHP 中的 buildpack:https://cloud.google.com/docs/buildpacks/php(其中介绍了如何设置 PHP 版本)
- 请尝试使用以下代码自动构建容器映像。
pack build --builder=gcr.io/buildpacks/builder my-app-with-buildpacks
您的本地环境中应该有一个新的 Docker 映像。您可以尝试为其运行容器,但由于我们无法完全控制映像的构建方式,应用可能无法运行。无论如何,我们都邀请您参与实验,并在成功后分享您的意见。谢谢!
保存到 Artifact Registry [可选]
到目前为止,您应该已经拥有一个可正常运行的容器化 PHP 应用,可以部署到云端了。接下来,我们需要在云端有个位置来存储 Docker 映像,使其可用于部署到 Cloud Run 等 Google Cloud 服务。此存储解决方案称为 Artifact Registry,是一项全代管式 Google Cloud 服务,专门用于存储应用工件,包括 Docker 容器映像、Maven 软件包、npm 模块等。
我们来使用相应的按钮在 Google Cloud Artifact Registry 中创建一个代码库。
选择有效的名称、格式和适合存储制品的区域。
返回本地开发环境标记,然后将应用容器映像推送到刚刚创建的 Artifact Registry 代码库。为此,请完成以下命令。
- docker 标记 SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
- docker push TARGET_IMAGE[:TAG]
结果应如下屏幕截图所示。
太棒了!🎉?🎉?🎉?您可以进入下一级别了。
注意:您还可以尝试使用 /upload.php
端点并上传一张照片。您可能会收到“权限被拒绝”消息。如果是这样,您需要在 Dockerfile
中进行一些 chmod/chown
修复。
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 登录对您进行身份验证。请务必使用已登录 Google Cloud 且已启用结算功能的用户(例如 vattelapesca@gmail.com)通过 Chrome 登录。
使用以下命令启用 Cloud Run API
$ gcloud services enable run.googleapis.com
至此,一切都已准备好部署到 Cloud Run。
通过 gcloud 将应用部署到 Cloud Run
用于在 Cloud Run 上部署应用的命令是 gcloud run deploy
。您可以通过设置多种选项来实现自己的目标。最小一组角色是:
- 您要为应用部署的 Cloud Run 服务的名称。Cloud Run 服务会返回一个网址,用于为您的应用提供端点。
- 您的应用将在其中运行的 Google Cloud 区域。
- 封装应用的容器映像。
- 应用在执行期间需要使用的环境变量。
- Allow-Unauthenticated 标志:允许所有人无需进一步身份验证即可访问您的应用
请参阅文档,了解如何将此选项应用于您的命令。部署需要几分钟时间。如果一切正确无误,您应该会在 Google Cloud 控制台中看到如下内容。
点击 Cloud Run 提供的网址,然后测试您的应用。身份验证成功后,您应该会看到如下内容。
使用“no questions”运行“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] 在公开文档中搜索如何通过 CLI 添加选项
--my-option [my-value]
来设置 X。 - 现在,请返回第 2 步,除非 gcloud 在没有其他问题的情况下完成。
- 此 gcloud run 部署 BLAH BLAH BLAH 太棒了!将该命令保存到某个位置,您稍后在 Cloud Build 步骤中需要用到它!
可在此处查看可能的解决方案。
太棒了!🎉?🎉?🎉?您已成功在 Google Cloud 中部署应用,完成了现代化改造的第一步。
6. 第 4 单元:使用 Secret Manager 清理密码
在上一步中,我们成功在 Cloud Run 中部署并运行了应用。不过,我们在实现该功能时采用了一种安全不良做法:以明文形式提供一些 Secret。
第一轮迭代:更新 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') ?: _______;
$db_name = getenv('DB_NAME') ?: 'image_catalog';
$db_user = getenv('DB_USER') ?: 'appmod-phpapp-user';
$db_pass = getenv('DB_PASS') ?: _______;
// 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 变量的方法。这可以通过以下几种方式实现:
- 在 build 时刻,在 Dockerfile 中。使用语法 ENV DB_VAR=ENV_VAR_VALUE 向上一个 Dockerfile 中添加 4 个参数。这会设置可在运行时替换的默认值。例如,只能在此处设置“DB_NAME”和“DB_USER”,不能在其他任何位置设置。
- 在 run 时。您可以通过 CLI 或界面为 Cloud Run 设置这些变量。这里是放置全部 4 个变量的正确位置(除非您希望保留 Dockerfile 中设置的默认值)。
在本地主机中,您可能需要将 ENV 变量放在 .env
文件中(请查看 solutions 文件夹)。
此外,请确保将 .env 添加到 .gitignore
:您不想将 Secret 推送到 GitHub!
echo .env >> .gitignore
之后,您可以在本地测试实例:
docker run -it -p 8080:8080 --env-file .env my-php-app-docker
现在,您已完成以下操作:
- 您的应用将从环境变量中动态读取变量
- 您从代码中移除了数据库密码,从而提高了安全性)
现在,您可以将新修订版本部署到 Cloud Run。我们直接进入界面,手动设置环境变量:
- 前往 https://console.cloud.google.com/run
- 点击您的应用
- 点击“修改和部署新的修订版本”
- 在第一个标签页“容器”上,点击下方的“变量和 Secret”标签页
- 点击“+ 添加变量”,然后添加所有所需的变量。最终结果应如下所示:
完美吗?不会。大多数运营商仍然可以看到您的卡券。您可以使用 Google Cloud Secret Manager 来缓解此问题。
第二次迭代:Secret Manager
你的密码从你自己的代码中消失了:成功!但请等一下 - 我们现在安全了吗?
任何有权访问 Google Cloud 控制台的用户仍然可以看到您的密码。事实上,如果您访问 Cloud Run YAML 部署文件,则可以检索该文件。或者,如果您尝试修改或部署新的 Cloud Run 修订版,密码会显示在“变量和 Secret”部分,如下面的屏幕截图所示。
Google Cloud Secret Manager 是一项安全的集中式服务,用于管理 API 密钥、密码、证书和其他密钥等敏感信息。
借助 Secret Manager,您可以使用精细的权限和强大的加密功能存储、管理和访问 Secret。Secret Manager 与 Google Cloud 的 Identity and Access Management (IAM) 集成,让您可以控制哪些人可以访问特定 Secret,从而确保数据安全和法规遵从。
它还支持自动轮替密钥和版本控制,简化密钥生命周期管理,并增强 Google Cloud 服务中应用的安全性。
如需访问 Secret Manager,请从三线菜单前往安全服务,然后在数据保护部分下找到它,如下面的屏幕截图所示。
进入该 API 后,按照下图所示启用 Secret Manager API。
- 现在,点击“Create a Secret”(创建 Secret)。我们理性地称呼它:
- 名称:
php-amarcord-db-pass
- Secret 值:“您的数据库密码”(忽略“上传文件”部分)。
- 为此 Secret 链接添加注释,应如下所示:
projects/123456789012/secrets/php-amarcord-db-pass
。这是指向您的 Secret 的唯一指针(适用于 Terraform、Cloud Run 等)。该编号是您的唯一项目编号。
提示:请尝试为您的 Secret 采用一致的命名惯例,从左到右进行专门化,例如:cloud-devrel-phpamarcord-dbpass
- 组织(包含公司)
- 团队(在组织内)
- 应用(团队内部)
- 变量名称(应用内)
这样,您就可以使用简单的正则表达式查找单个应用的所有密钥。
创建新的 Cloud Run 修订版本
现在,我们已经有了新的 Secret,需要移除 DB_PASS ENV 变量,并将其替换为新的 Secret。因此:
- 通过 Google Cloud 控制台访问 Cloud Run
- 选择相应应用。
- 点击“修改和部署新修订版本”
- 找到“变量和 Secret”标签页。
- 使用“+ 引用密文”按钮重置 DB_PASS ENV 变量。
- 为引用的 Secret 使用相同的“DB_PASS”,并使用最新版本。
完成后,您应该会看到以下错误
尝试找出解决方法。要解决此问题,您需要访问 IAM 和管理部分,然后更改授予权限。祝您调试顺利!
确定问题后,请返回 Cloud Run 并重新部署新修订版本。结果应如下图所示:
提示:Play 管理中心 (UI) 非常擅长指出权限问题。请花些时间浏览 Cloud 实体的所有链接!
7. 第 5 单元:使用 Cloud Build 设置 CI/CD
为什么要使用 CI/CD 流水线?
到现在,您应该已经输入了几次 gcloud run deploy
,也许还反复回答了同一个问题。
厌倦使用 gcloud run deploy 手动部署应用了吗?如果每次您将新更改推送到 Git 代码库时,您的应用都可以自动部署,那不是很好吗?
如需使用 CI/CD 流水线,您需要满足以下两项条件:
- 个人 Git 代码库:幸运的是,您应该已在第 2 步中将本教程的代码库分叉到您的 GitHub 账号。如果没有,请返回并完成该步骤。您的分叉代码库应如下所示:
https://github.com/<YOUR_GITHUB_USER>/app-mod-workshop
- Cloud Build。借助这项令人惊叹且价格低廉的服务,您可以为几乎所有内容配置构建自动化:Terraform、容器化应用等。
本部分将重点介绍如何设置 Cloud Build。
开始使用 Cloud Build!
我们将使用 Cloud Build 来实现这一点:
- 使用 Dockerfile 构建源代码。您可以将其视为一个“大 .zip 文件”,其中包含构建和运行该文件所需的所有内容(“构建工件”)。
- 将此工件推送到 Artifact Registry (AR)。
- 然后,为应用“php-amarcord”从 AR 到 Cloud Run 发出部署
- 这将创建现有应用的新版本(“修订版本”),该版本可视为包含新代码的层,我们会将其配置为在推送成功时将流量转移到新版本。
下面是我的 php-amarcord
应用的部分 build 示例:
我们如何实现这一切?
- 通过编写一个完美的 YAML 文件:
cloudbuild.yaml
- 通过创建 Cloud Build 触发器。
- 通过 Cloud Build 界面连接到我们的 GitHub 代码库。
创建触发器(和 Connect 代码库)
- 前往 https://console.cloud.google.com/cloud-build/triggers
- 点击“创建触发器”。
- 编译:
- 名称:
on-git-commit-build-php-app
等有意义的名称 - 事件:推送到分支
- 来源:“关联新代码库”
- 这会在右侧打开一个窗口:“关联代码库”
- 来源提供方:“GitHub”(第一项)
- “继续”
- 点击“Authenticate”(验证身份)后,GitHub 上会打开一个窗口以进行跨平台身份验证。请按照流程操作,并耐心等待。如果您有许多代码库,则可能需要一些时间。
- “选择代码库”选择您的账号/代码库,然后选中“我了解...”部分。
- 如果您收到错误:表示 GitHub 应用未安装在您的任何代码库中,请继续点击“Install Google Cloud Build”(安装 Google Cloud Build)并按照说明操作。
- 点击“连接”
- 答对了!您的代码库现已连接。
- 返回触发器部分...
- 配置:自动检测 (*)
- 高级:选择服务账号“[PROJECT_NUMBER]-compute@developer.gserviceaccount.com”
- xxxxx 是您的项目 ID
- 默认计算服务账号适用于实验室方法,请勿在生产环境中使用!(了解详情)。
- 其他所有设置均保持不变。
- 点击“创建”按钮。
(*) 这是最简单的方法,因为它会检查 Dockerfile 或 cloudbuild.yaml。不过,cloudbuild.yaml
让您可以真正决定在哪个步骤执行哪项操作。
我有电源!
现在,除非您向 Cloud Build 服务账号(什么是服务账号?代表您执行任务的“机器人”的电子邮件地址(在本例中,是在云端构建内容)。
除非您授权您的 SA 执行构建和部署操作,否则他将无法执行这些操作。幸运的是,这很容易!
- 依次前往“Cloud Build”>“Settings”(设置)。
- “[PROJECT_NUMBER]-compute@developer.gserviceaccount.com”服务账号
- 勾选以下复选框:
- Cloud Run
- Secret Manager
- 服务账号
- Cloud Build
- 还要勾选“设置为首选服务账号”
Cloud Build YAML 在哪里?
我们强烈建议您花一些时间创建自己的 Cloud Build YAML。
不过,如果您没有时间或不想抽出时间,可以从以下解决方案文件夹中获得一些灵感:.solutions
现在,您可以将更改推送到 GitHub,并观察 Cloud Build 的运行情况。
设置 Cloud Build 可能会比较复杂。预计可通过以下方式来回发送:
- 在 https://console.cloud.google.com/cloud-build/builds;region=global 中查看日志
- 正在查找错误。
- 修复代码并重新发出 git commit / git push。
- 有时错误并非在代码中,而是在一些配置中。在这种情况下,您可以通过界面(Cloud Build >“Triggers”>“Run”)发布新的 build
请注意,如果您使用此解决方案,则仍需执行一些工作。例如,您需要为新创建的 dev/prod 端点设置 ENV 变量:
可以通过以下两种方法实现此目的:
- 通过界面 - 再次设置 ENV 变量
- 通过 CLI 为您量身打造“完美”脚本。您可以点击此处查看示例:gcloud-run-deploy.sh。您需要调整一些设置,例如端点和项目编号;您可以在 Cloud 概览中找到项目编号。
如何将代码提交到 GitHub?
本研讨会无法介绍将 git push
推送到 GitHub 的最佳方式。不过,如果您在 Cloud Shell 中遇到问题,可以通过以下两种方式解决:
- CLI。在本地添加 SSH 密钥,然后添加远程代码库 git@github.com:YOUR_USER/app-mod-workshop.git(而不是 http)
- VSCode。如果您使用的是 Cloud Shell 编辑器,则可以使用源代码控件 (ctrl-shift-G) 标签页,点击“同步更改”,然后按照说明操作。您应该能够将 GitHub 账号的身份验证信息导入到 VSCode,这样就可以轻松地从中拉取/推送代码了。
请务必git add clodubuild.yaml
和其他文件,否则将无法正常运行。
深度与浅层的“开发/生产环境一致性”[可选]
如果您从此处复制模型版本,则会有两个相同的 DEV 和 PROD 版本。这很棒,符合 《十二要素应用》规则 10。
不过,我们使用两个不同的 Web 端点让应用指向同一数据库。这对于研讨会来说已经足够了;但在现实生活中,您需要花一些时间来打造适当的生产环境。这意味着拥有两个数据库(一个用于开发数据库,一个用于生产环境),同时还要选择将其部署在何处以实现灾难恢复 / 高可用性。这超出了本研讨会的范围,但值得您思考。
如果您有时间进行“深度”版本的制作,请记住需要复制的所有资源,例如:
- Cloud SQL 数据库(可能还有 SQL 实例)。
- GCS 存储桶
- Cloud Functions 函数。
- 您可以在开发阶段使用 Gemini 1.5 Flash 作为模型(价格更低、速度更快),在生产阶段使用 Gemini 1.5 Pro(功能更强大)。
一般来说,每次您对应用执行操作时,都应进行批判性思考:生产环境是否应具有相同的值?如果没有,则需要重复工作。当然,使用 Terraform 会更加容易,通过 Terraform,您可以将环境(-dev、-prod)作为后缀注入资源。
8. 第 6 单元:迁移到 Google Cloud Storage
存储
目前,应用将状态存储在 Docker 容器中。如果机器发生故障、应用发生崩溃,或者您只是推送了新修订版,系统就会安排新的 build,并重置存储空间(=> 清空)。🙈
如何解决此问题?有多种方法。
- 将图片存储在数据库中。我最终对之前的 PHP 应用就是这么做的。这是最简单的解决方案,因为它不会增加复杂性。但这肯定会增加数据库的延迟时间和负载!
- 将您的 Cloud Run 应用迁移到适合存储的解决方案:GCE + 永久性磁盘?或许是 GKE + Storage?
- 移至 GCS。Google Cloud Storage 是整个 Google Cloud 中一流的存储服务,也是最符合 Cloud 惯例的解决方案。不过,这需要我们深入研究 PHP 库。我们是否有 适用于 GCS 的 PHP 5.7 库?
PHP 5.7
是否支持Composer
(似乎 PHP 5.3.2 是 Composer 支持的最低版本)? - 可以使用 docker sidecar 吗?
- 也可以使用 GCS Cloud Run 卷装载。这听起来很棒。
🤔 迁移存储空间(开放式)
[开放式] 在本练习中,我们希望您找到一种解决方案,以某种方式保留图片。
验收测试
我不想告诉您解决方案,但希望您能做到以下几点:
- 您上传了
newpic.jpg
。您可以在应用中看到它。 - 您将应用升级到新版本。
newpic.jpg
仍在原地,可见。
💡 可能的解决方案(GCS Cloud Run 卷挂载)
这是一个非常优雅的解决方案,它使我们能够在完全不涉及代码的情况下实现有状态文件上传(除了显示图片说明,但它很简单,并且仅是为了提升视觉满意度)。
这样,您应该就可以将 Cloud Run 中的文件夹挂载到 GCS 了,具体步骤如下:
- 所有上传到 GCS 的内容实际上都会显示在您的应用中。
- 所有上传到您的应用的内容实际上都会上传到 GCS
- 系统会对上传到 GCS 的对象执行一些神奇操作(第 7 章)。
注意:请阅读 FUSE 的详细信息。如果性能存在问题,则不适用。
创建 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 在 MOUNT_PATH
上进行 FUSE 装载(类似于 /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 的所有端点重复此步骤。
您也可以通过界面实现相同的效果
- 在“卷”标签页下,创建一个指向您的存储分区的卷挂载,类型为“Cloud Storage 存储分区”,例如名称为“php_uploads”。
- 在“容器”>“卷挂载”下,将您刚刚创建的卷挂载到应用请求的卷点。具体取决于 Dockerfile,但可能类似于
var/www/html/uploads/
。
无论是哪种方式,如果一切正常,您在修改新的 Cloud Run 修订版本时应该会看到如下内容:
现在,测试将一张新图片上传到 /upload.php
端点的新应用。
图片应该会在 GCS 上流畅传输,而无需编写任何 PHP 代码:
刚刚发生了什么?
发生了一件非常神奇的事。
使用旧代码的旧应用仍在正常运行。得益于现代化的全新堆栈,我们能够将应用中的所有图片/图片轻松存放在有状态的云端存储分区中。现在,您可以尽情发挥创意:
- 想要在每次收到包含“危险”或“裸露”内容的图片时发送电子邮件?您无需更改 PHP 代码即可执行此操作。
- 想要在每次收到图片时使用 Gemini 多模态模型对其进行描述,并将包含相应描述的数据库上传到数据库?您无需修改 PHP 代码即可执行此操作。您不相信我吗?请继续阅读第 7 章。
我们刚刚发现了一个巨大的机会。
9. 第 7 单元:利用 Google Gemini 为应用赋能
现在,您已经拥有了一个现代化的全新 PHP 应用(就像 2024 年的 Fiat 126
),并且该应用使用了云端存储空间。
您可以用它来做些什么呢?
前提条件
在上一章中,借助模型解决方案,我们可以在 GCS 上装载映像 /uploads/
,实际上可以将应用逻辑与映像存储空间分开。
在本练习中,您需要:
- 已成功完成第 6 章(存储)中的练习。
- 创建一个用于存储上传图片的 GCS 存储分区,用户可以在您的应用中上传图片,这些图片会流入您的存储分区。
设置 Cloud Functions 函数(使用 Python)
您是否曾想过如何实现事件驱动型应用?例如:
- 当 <event> 发生 => 时发送电子邮件
- 当 <event> 发生 => 时,如果 <condition> 为 true,则更新数据库。
事件可以是任何内容,包括 BigQuery 中可用的新记录、GCS 中某个文件夹中发生更改的新对象,或 Pub/Sub 队列中等待处理的新消息。
Google Cloud 支持多种范例来实现这一点。最值得注意的是:
- EventArc。了解如何接收 GCS 事件。很高兴能在 Cloud 中根据 if-then-else 创建 DAG 并协调操作。
- Cloud Scheduler。例如,非常适合在午夜运行 Cloud 中的 Cron 作业。
- Cloud Workflows。与 Event Arc 类似,可让您:
- Cloud Run Functions(通常称为
lambdas
)。 - Cloud Composer。基本上是 Google 版本的 Apache Airflow,也非常适合 DAG。
在本练习中,我们将深入了解 Cloud Functions 函数,以实现令人惊叹的效果。我们还会为您提供一些选做练习。
请注意,示例代码在 .solutions/
下提供
设置 Cloud Functions 函数 (공 python)
我们正努力打造一个雄心勃勃的 GCF。
- 在 GCS 上创建新映像时。(可能是因为有人在应用中上传了该内容,但也可能是因为其他原因)
- .. 调用 Gemini 来描述它并获取图片的文本说明 ..(最好检查 MIME 并确保它是图片,而不是 PDF、MP3 或文本)
- ... 并使用此说明更新数据库。(这可能需要对数据库进行补丁,以便向
images
表添加description
列)。
修补数据库以将 description
添加到映像
- 打开 Cloud SQL Studio:
- 输入图片数据库的用户名和密码
- 注入以下 SQL 语句,为图片说明添加列:
ALTER TABLE images ADD COLUMN description TEXT;
就是这样!现在,请尝试检查它是否正常运行:
SELECT * FROM images;
您应该会看到新的说明列:
写出 Gemini f(x)
注意:实际上,此函数是借助 Gemini Code Assist 创建的。
注意:创建此函数时,您可能会遇到 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 Functions 函数将将 GCS 事件及其所有相关信息(存储桶名称、对象名称等)传递给它。请花些时间调试该事件 Python 字典。
测试函数
单元测试
该函数包含许多动态部分。您可能希望能够测试所有单个用例。
如需查看示例,请参阅 gcf/test.py。
Cloud Functions 界面
此外,请花些时间在界面中浏览一下您的函数。每个标签页都值得探索,尤其是 Source
(我的最爱)、Variables
、Trigger
和 Logs
;您将会花费大量时间在 Logs
中排查错误(另请参阅此页面底部的可能错误)。此外,请务必查看 Permissions
。
端到端测试
现在,我们来手动测试该函数!
- 前往您的应用并登录
- 上传一张照片(不要太大,我们发现大图片会出现问题)
- 在界面上检查上传的图片。
- 在 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。美化后的版本可能如下所示:
总结
您有一个 Cloud Functions 函数会在有新对象存储到 GCS 时触发,该函数能够像人一样为图片内容添加注释,并自动更新数据库。哇哦!
接下来该做什么?您可以按照相同的推理来实现两个很棒的功能。
[可选] 添加其他 Cloud Functions 函数 [开放式]
我还想到了一些其他功能。
📩 电子邮件触发器
电子邮件触发器:每当有人发送照片时,系统都会向您发送一封电子邮件。
- 是否过于频繁?添加进一步的约束条件:大图片,或 Gemini 内容包含“裸露/裸体/暴力”字样的图片。
- 不妨参阅
EventArc
了解详情。
🚫? 自动审核不当照片
目前,人工管理员会将图片标记为“不当”。不妨让 Gemini 来帮您减负,管理聊天室。添加一个测试,用于标记不当的触发器内容并更新数据库,就像我们在前面的函数中学习的那样。这基本上意味着,使用之前的函数、更改提示,并根据回答更新数据库。
注意。生成式 AI 的输出不可预测。确保将 Gemini 中的“广告素材输出”放置在“轨道”上。您可以询问确定性答案,例如介于 0 到 1 之间的置信度得分、JSON 等。您可以通过多种方式实现此目的,例如:* 使用 Python 库 pydantic
、langchain
等* 使用 Gemini 结构化输出。
提示。您可以使用多个函数,也可以使用一个提示来强制要求回答 JSON 格式的问题(与上文中突出显示的“Gemini 结构化输出”搭配使用效果更佳),例如:
生成这类提示需要什么?
{
"description": "This is the picture of an arrosticino",
"suitable": TRUE
}
您可以在提示中添加其他字段,以获得相关洞见,例如:它有什么优点吗?对此有意见吗?您认得这个地方吗?是否包含文字(OCR 从未如此简单):
goods
:“看起来很美味”bads
:“看起来像不健康的食物”OCR
: "Da consumare preferibilmente prima del 10 Novembre 2024"location
:“Pescara, Lungomare”
虽然针对 N 个结果使用 N 函数通常更好,但当一个模型完成 10 项任务时却获得了极大的奖励。请参阅 Riccardo 撰写的这篇文章,了解具体方法。
可能出现的错误(主要是 IAM / 权限)
在首次开发此解决方案时,我遇到了一些 IAM 权限问题。我会将这些信息添加到此处,以便同情您的感受,并提供一些解决方法。
错误:服务账号权限不足
- 请注意,如需部署监听 GCS 存储分区的 GCF 函数,您需要为用于作业的服务账号设置适当的权限,如下图所示:
您可能还需要启用 EventArc API,这些 API 可能需要几分钟才能完全可用。
错误:缺少 Cloud Run Invoker
- 界面中关于 GCF 权限的另一条评论如下(Cloud Run Invoker 角色):
可以通过在映像中运行命令来修复此错误(类似于 fix-permissions.sh),
有关此问题的说明,请访问:https://cloud.google.com/functions/docs/securing/authenticating
错误:超出内存上限
第一次运行它时,我的日志可以这样显示:“‘使用 270 MiB 时,已超出 244 MiB 的内存限制。Consider increasing the memory limit, see https://cloud.google.com/functions/docs/configuring/memory'"。再次将 RAM 添加到 GCF。在界面中执行此操作非常简单。可能存在的排名靠前:
或者,您也可以修正 Cloud Run 部署脚本以提高 MEM/CPU。这需要多一点时间。
错误:PubSub 已发布
使用 GCF v1 创建触发器时,系统会显示以下错误:
同样,您只需前往 IAM 并向您的服务账号授予“Pub/Sub Publisher”角色,即可轻松解决此问题。
错误:未使用 Vertex AI
如果您收到以下错误:
权限被拒:403 Vertex AI API 之前未用于项目 YOUR_PROJECT,或者已停用。如需启用此 API,请访问 https://console.developers.google.com/apis/api/aiplatform.googleapis.com/overview?project=YOR_PROJECT
您只需启用 Vertex AI API 即可。启用所有需要的 API 的最简单方法是:
- https://console.cloud.google.com/vertex-ai
- 点击“启用所有推荐的 API”。
错误:未找到 EventArc 触发器。
如果您收到此消息,请重新部署函数。
错误:正在预配 400 个服务代理
系统正在预配 400 个服务代理 ( https://cloud.google.com/vertex-ai/docs/general/access-control#service-agents)。服务代理需要读取所提供的 Cloud Storage 文件。请过几分钟再试。
如果出现这种情况,请稍等片刻或向 Google 员工寻求帮助。
10. 第 8 单元:创建可用性 SLO
在本章中,我们将尝试实现以下目标:
- 创建 SLI
- 根据 SLI 创建 SLO
- 根据 SLO 创建提醒
这个主题对作者来说非常重要,因为 Riccardo 从事 Google Cloud 的 SRE / DevOps 领域。
(开放式问题)为此应用创建 SLI 和 SLO
如果您无法判断应用何时宕机,那么该应用还有什么用?
什么是 SLO?
噢,太巧了!SLO 是 Google 发明的!若要深入了解该工具,建议您:
- 《SRE 图书》第 2 章 - 实现 SLO。(👉 更多 SRE 图书)
- SLO 的艺术(精彩视频)。这门培训非常实用,可帮助您详细了解如何为服务制定完美的 SLO。
- Coursera 上的 SRE 课程。我为此贡献了力量!
第 1 步:创建可用性 SLI/SLO
我们先从可用性 SLO 开始,因为它是您要衡量的最简单,也可能是最重要的指标。
幸运的是,Cloud Run 内置了 SLO 支持,这得益于 Istio。
当应用在 Cloud Run 上运行后,这超级简单,需要 30 秒。
- 前往 Cloud Run 页面。
- 点击/选择您的应用。
- 选择
SLOs
标签。 - 点击“+ 创建服务等级目标”。
- 可用性(基于请求)
- 继续
- 日历月 / 99%。
- 点击“创建服务等级目标”。
第 2 步:针对此 SLO 设置提醒
我建议您创建 2 个提醒:
- 一个是消耗率较低的“Slowburn”,会通过电子邮件提醒您(模拟低优先级票券)。
- 一个烧毁率较高(“快速烧毁”),通过短信提醒您(模拟高优先级工单 / 寻呼器)
前往之前的 SLO tab
。
执行此操作两次:
- 点击“创建 SLO 提醒”(右侧带有加号的 🔔 按钮)
- 回溯期、消耗率阈值:
- [FAST]。第一种:
60
分钟/10
x - [慢]。秒:
720
分钟 /2
x - 通知渠道:点击“管理通知渠道”
- 首先,点击“电子邮件”->“添加新建”-> ..
- 其次,选择“短信”->“新增”->“在手机上验证”。
- 提示:我喜欢在名称中使用表情符号!演示时很有趣。
- 完成后,点击右上角的“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
Gemini 有两种版本:
- Vertex AI。“企业方式”与 GCP 交织在一起,我们已在第 7 章 (GCF+Gemini) 中对此进行了介绍。所有身份验证都会神奇地正常运行,服务之间会完美互联。
- Google AI。“消费者方式”。从此处获取 Gemini API 密钥,然后开始构建小脚本,这些脚本可以关联到已有的工作负载(专有工作、其他云、本地主机等)上。您只需替换 API 密钥,代码就会神奇地开始运行。
我们建议您尝试使用自己的小项目探索 (2)。
界面提升
我不擅长界面设计。但 Gemini 可以!您只需使用一个 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!]
只需一个 Cloud Build 即可轻松实现,整个流程不到 5 分钟!:)
Gemini 的回答非常完美(也就是说,我无需进行任何更改):
以下是作者个人应用中的新布局:
注意:代码以图片形式粘贴,因为我们并不想鼓励您直接使用代码,而是为了让 Gemini 为您编写代码,同时保持您对广告素材界面/前端的限制;相信我,您之后只能进行非常小的更改。
安全性
本 4 小时工作坊的目标并非妥善保护此应用。
如需获取一些想法,请查看 SECURITY
doc
。
12. 恭喜!
恭喜 🎉?🎉?🎉?,您已成功使用 Google Cloud 对旧版 PHP 应用进行了现代化改造。
总的来说,在此 Codelab 中,您学习了以下内容:
- 如何在 Google Cloud SQL 中部署 MYSQL 数据库,以及如何将现有数据库迁移到其中。
- 如何使用 Docker 和 Buildpack 将 PHP 应用容器化,并将其映像存储到 Google Cloud Artifact Registry
- 如何将容器化应用部署到 Cloud Run 并使用 Cloud SQL 运行该应用
- 如何使用 Google Secret Manager 秘密存储/使用敏感配置参数(例如数据库密码)
- 如何使用 Google Cloud Build 设置 CI/CD 流水线,以便在每次有代码推送到 GitHub 代码库时自动构建和部署 PHP 应用。
- 如何使用 Cloud Storage 将应用资源“云化”
- 如何利用无服务器技术在 Google Cloud 之上构建出色的工作流,而无需更改应用代码。
- 针对合适的应用场景使用 Gemini 多模态功能。
开启 Google Cloud 应用现代化改造之旅,开启美好的开始!
🔁 反馈
如果您想告诉我们您在参加此研讨会时的体验,不妨填写此反馈表单。
我们欢迎您提供反馈以及特别引以为豪的代码段的公关。
🙏? 谢谢
作者想感谢来自 Datatonic 的 Mirko Gilioli 和 Maurizio Ipsale,他们在撰写本文档和测试解决方案方面提供了帮助。