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 可以与托管在 GitHub 或 GitLab 等热门 Git 提供商上的 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,并且受到组织政策的限制,无法完成此 Codelab。我们建议您创建一个新的 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 编辑器提供了您所需的一切
如需直观地实现此操作,请点击“打开文件夹”,然后选择文件夹(可能是主文件夹中的 app-mod-workshop
)。
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 版本: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 中的所有数据库都是“隔离”状态。您需要明确设置可供访问的网络。
- 点击您的实例
- 打开“连接”菜单
- 点击“Networking”标签页。
- 点击“已获授权的网络”下方的相应位置。现在,添加网络(即子网)。
- 现在,我们选择快速但不安全的设置,以便应用正常运行。您可能需要稍后将其限制为仅允许可信 IP 访问:
- 名称:“Everyone in the world - INSECURE”。
- 网络:“
0.0.0.0/0"
(注意:这是不安全的部分!) - 点击“完成”
- 点击“保存”。
您应该会看到与以下类似的内容:
注意:此解决方案是一个很好的折衷方案,可在 O(hours) 内完成本研讨会。不过,请查看安全文档,以帮助您确保生产环境中的解决方案安全无虞!
现在该测试数据库连接了!
我们来看看之前创建的 image_catalog
用户是否可用。
访问实例中的“Cloud SQL Studio”,然后输入要进行身份验证的数据库、用户和密码,如下所示:
现在,您可以打开 SQL 编辑器并继续下一部分。
从代码库导入数据库
使用 SQL 编辑器导入 image_catalog
表及其数据。从代码库中的文件(先是 01_schema.sql,然后是 02_seed.sql)复制 SQL 代码,并按顺序依次执行这些代码。
之后,您应该会在 image_catalog 中看到两个表,即 users 和 images,如下所示:
您可以在编辑器中运行以下代码进行测试:select * from images;
此外,请务必记下 Cloud SQL 实例的公共 IP 地址,您稍后会用到它。如需获取 IP,请前往 概览页面下的 Cloud SQL 实例主页面。(“概览”>“连接到此实例”>“公共 IP 地址”)。
4. 第 2 单元:将 PHP 应用容器化
我们希望将此应用构建为云端应用。
这意味着,您需要将代码打包到某种 ZIP 文件中,其中包含在云端运行该代码所需的所有信息。
您可以通过以下几种方式打包它:
- Docker。非常受欢迎,但正确设置起来非常复杂。
- Buildpack。不太常用,但往往会“自动猜测”要构建和运行的内容。通常,它会正常运行!
在本研讨会中,我们假设您使用的是 Docker。
如果您选择使用 Cloud Shell,请在此时重新打开它(点击 Cloud 控制台右上角)。
这应该会在页面底部打开一个方便的 Shell,您应该已在设置步骤中将代码分叉到该 Shell 中。
Docker
如果您希望掌控一切,这是一个不错的选择。当您需要配置特定库并注入某些不明显的行为(上传中的 chmod、应用中的非标准可执行文件等)时,这很有用。
由于我们最终希望将容器化应用部署到 Cloud Run,因此请参阅以下文档。您如何将其从 PHP 8 向后移植到 PHP 5.7?您或许可以使用 Gemini 来解决此问题。或者,您也可以使用此预先编译的版本:
最新的 Dockerfile
版本可在此处找到。
为了在本地测试我们的应用,我们需要更改 config.php 文件,以便我们的 PHP 应用能够连接到 Google CloudSQL 上可用的 MySQL 数据库。根据您之前的设置,填写空白:
<?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
是 Cloud SQL 公共 IP 地址,您可以在 SQL 控制台中找到它:
DB_NAME
应保持不变:image_catalog
DB_USER
应为appmod-phpapp-user
DB_PASS
是您选择的。使用单引号进行设置,并根据需要进行转义。
此外,您还可以随时使用 Gemini 将少数 🇮?🇹? 意大利语内容翻译成英语!
好的,现在您已经有了 Dockerfile
,并已将 PHP 应用配置为连接到数据库,接下来我们来试一试!
如果您尚未安装 Docker,请安装(链接)。如果您使用的是 Cloud Shell,则无需执行此操作(是不是很酷?)。
现在,尝试使用适当的 Docker 构建和运行命令构建和运行容器化 PHP 应用。
# 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 登录,则应该会看到如下内容。
太棒了!除了意大利语文本外,其他都正常!🎉🎉🎉
如果您的 Docker 容器化设置正确无误,但数据库凭据有误,您可能会收到如下错误消息:
请再试一次,您已经很接近了!
保存到 Artifact Registry [可选]
到目前为止,您应该已经拥有一个可正常运行的容器化 PHP 应用,可以部署到云端了。接下来,我们需要在云端找到一个位置来存储 Docker 映像,并使其可供部署到 Cloud Run 等 Google Cloud 服务。此存储解决方案称为 Artifact Registry,是一项全代管式 Google Cloud 服务,专门用于存储应用工件,包括 Docker 容器映像、Maven 软件包、npm 模块等。
我们来使用相应的按钮在 Google Cloud Artifact Registry 中创建一个代码库。
选择适合存储工件的有效名称、格式和区域。
返回本地开发环境标记,然后将应用容器映像推送到刚刚创建的 Artifact Registry 代码库。为此,请完成以下命令。
- docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
- docker push TARGET_IMAGE[:TAG]
结果应如下屏幕截图所示。
太棒了!🎉?🎉?🎉?您可以进入下一级了。在此之前,不妨花 2 分钟时间尝试上传/登录/退出登录,并熟悉应用端点。您稍后需要用到这些端点。
可能出现的错误
如果您收到容器化错误,请尝试使用 Gemini 来解释和修复错误,并提供以下信息:
- 您当前的 Dockerfile
- 收到的错误
- [如果需要] 要执行的 PHP 代码。
上传权限。您还可以尝试使用 /upload.php
端点并上传一张照片。您可能会收到以下错误。如果是,您需要在 Dockerfile
中执行一些 chmod/chown
修复。
警告:move_uploaded_file(uploads/image (3).png):无法打开数据流:/var/www/html/upload.php 中第 11 行中的权限被拒绝
PDOException“找不到驱动程序”(或“Errore di connessione: could not find driver”)。确保您的 Dockerfile 包含适用于 mysql (pdo_mysql
) 的正确 PDO 库,以便连接到数据库。您可以点击此处,从解决方案中获得灵感。
无法将您的请求转发到后端。无法连接到端口 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 登录对您进行身份验证。请务必使用已登录 Google Cloud 且已启用结算功能的用户(例如 vattelapesca@gmail.com)通过 Chrome 登录。
使用以下命令启用 Cloud Run API:
$ gcloud services enable run.googleapis.com cloudbuild.googleapis.com
至此,一切都已准备好部署到 Cloud Run。
通过 gcloud 将应用部署到 Cloud Run
用于在 Cloud Run 上部署应用的命令是 gcloud run deploy
。您可以通过设置多种选项来实现自己的目标。最少需要提供以下一组选项(您可以通过命令行提供,也可以通过交互式提示获取):
- 您要为应用部署的 Cloud Run 服务的名称。Cloud Run 服务会返回一个网址,用于为您的应用提供端点。
- 应用将运行的 Google Cloud 区域。(
--region
REGION) - 封装应用的容器映像。
- 应用在执行期间需要使用的环境变量。
- Allow-Unauthenticated 标志,可允许所有人无需进一步身份验证即可访问您的应用。
请参阅文档(或向下滚动查看可能的解决方案),了解如何将此选项应用于命令行。
部署需要几分钟时间。如果一切正确无误,您应该会在 Google Cloud 控制台中看到如下内容。
点击 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
with options found so far - [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') ?: '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 的构建时。使用语法 ENV DB_VAR=ENV_VAR_VALUE 将 4 个参数添加到之前的 Dockerfile 中。这会设置可在运行时替换的默认值。例如,只能在此处设置“DB_NAME”和“DB_USER”,不能在其他任何位置设置。
- 在运行时。您可以为 Cloud Run 设置这些变量,无论是通过 CLI 还是界面都可以。这是放置所有 4 个变量的位置(除非您想保留 Dockerfile 中设置的默认值)。
在 localhost 中,您可能需要将 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 等敏感信息。
借助 Secret Manager,您可以通过精细的权限和强大的加密功能存储、管理和访问 Secret。Secret Manager 与 Google Cloud 的 Identity and Access Management (IAM) 集成后,您可以控制哪些人可以访问特定 Secret,从而确保数据安全和合规。
它还支持自动轮替 Secret 和版本控制,简化 Secret 生命周期管理,并增强 Google Cloud 服务中应用的安全性。
如需访问 Secret Manager,请从三线菜单前往安全服务,然后在数据保护部分下找到它,如下图所示。
进入该页面后,按照下图所示启用 Secret Manager API。
- 现在,点击“创建 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 管理中心(界面)非常擅长指出权限问题。请花些时间浏览 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 文件”,其中包含构建和运行该应用所需的所有内容(即“build 工件”)。
- 将此工件推送到 Artifact Registry (AR)。
- 然后,为应用“php-amarcord”从 AR 向 Cloud Run 发出部署
- 这将创建现有应用的新版本(“修订版本”),您可以将其视为包含新代码的层,我们会将其配置为在推送成功时将流量转移到新版本。
以下是我的 php-amarcord
应用的部分 build 示例:
我们如何实现这一切?
- 通过编写一个完美的 YAML 文件:
cloudbuild.yaml
- 通过创建 Cloud Build 触发器。
- 通过 Cloud Build 界面连接到我们的 GitHub 代码库。
创建触发器(并关联代码库)
- 前往 https://console.cloud.google.com/cloud-build/triggers
- 点击“创建触发器”。
- 编译:
- 名称:
on-git-commit-build-php-app
等有意义的名称 - 事件:推送到分支
- 来源:“关联新代码库”
- 这会在右侧打开一个窗口:“关联代码库”
- 来源提供方:“Github”(第一项)
- “继续”
- 点击“Authenticate”(验证身份)后,GitHub 上会打开一个窗口以进行跨平台身份验证。请按照流程操作,并耐心等待。如果您有许多代码库,则可能需要一些时间。
- “Select repo”(选择代码库)选择您的账号/代码库,然后勾选“I understand...”(我了解...)部分。
- 如果您收到错误:未针对您的任何代码库安装 GitHub 应用,请继续点击“安装 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,这样就可以轻松地在 VSCode 中执行拉取/推送操作。
请务必在其他文件中 git add clodubuild.yaml
,否则将无法运行。
深度与浅层“开发环境/生产环境一致性”[可选]
如果您从此处复制了模型版本,则 DEV 和 PROD 版本将完全相同。这很棒,符合 《十二要素应用》规则 10。
不过,我们使用两个不同的 Web 端点让应用指向同一数据库。这对于研讨会来说已经足够了;不过,在现实生活中,您需要花些时间创建合适的生产环境。这意味着,您需要有两个数据库(一个用于开发环境,一个用于生产环境),还需要选择它们的存储位置,以便实现灾难恢复 / 高可用性。这超出了本研讨会的范围,但不妨作为一个思考方向。
如果您有时间制作“深度”版正式版,请记得您需要复制的所有资源,例如:
- Cloud SQL 数据库(可能还有 SQL 实例)。
- GCS 存储桶
- Cloud Functions 函数。
- 您可以在开发阶段使用 Gemini 1.5 Flash 作为模型(价格更低、速度更快),在生产阶段使用 Gemini 1.5 Pro(功能更强大)。
一般来说,每次对应用执行操作时,都要进行批判性思考:生产环境是否应具有相同的值?如果没有,则需要重复工作。当然,使用 Terraform 时,您可以将环境(-dev、-prod)作为后缀注入到资源中,这样就更容易了。
8. 第 6 单元:迁移到 Google Cloud Storage
存储
目前,该应用会将状态存储在 Docker 容器中。如果机器发生故障、应用崩溃,或者您只是推送了新修订版本,系统就会安排新的修订版本,并使用新的空存储空间:🙈?
如何解决此问题?有多种方法。
- 将图片存储在数据库中。我最终对之前的 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
(类似于 /var/www/html/uploads/
)执行 FUSE 挂载:
#!/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 代码:
刚刚发生了什么?
发生了一件非常神奇的事。
使用旧代码的旧应用仍在正常运行。借助全新的现代化堆栈,我们可以将应用中的所有图片放置在有状态的 Cloud 存储分区中。现在,您可以尽情发挥创意:
- 想在每次收到包含“危险”或“裸露”内容的图片时发送电子邮件?您无需修改 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 函数(通常称为
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
错误:超出内存上限
我第一次运行时,日志会显示:“内存用量已超出 244 MiB 的限制,达到 270 MiB。Consider increasing the memory limit, see https://cloud.google.com/functions/docs/configuring/memory'"。再次向 GCF 添加 RAM。在界面中执行此操作非常简单。可能出现以下问题:
或者,您也可以修正 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 密钥,然后开始构建可与您现有的任何工作负载(专有工作、其他云、localhost 等)相关联的小脚本。只需替换您的 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 小时工作坊的目标不是妥善保护此应用,因为这会使完成本工作坊所需的时间增加 1-2 个数量级。
不过,这个主题非常重要!我们在 SECURITY
中收集了一些想法。
12. 恭喜!
恭喜🎉?🎉?🎉?,您已成功使用 Google Cloud 对旧版 PHP 应用进行了现代化改造。
总结一下,在此 Codelab 中,您学习了以下内容:
- 如何在 Google Cloud SQL 中部署数据库,以及如何将现有数据库迁移到其中。
- 如何使用 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 中实施 SRE 原则
这对您开启 Google Cloud 应用现代化之旅来说是一个良好的开端!
🔁? 反馈
如果您想告诉我们您在参加此研讨会的体验,不妨填写此反馈表单。
我们欢迎您针对自己特别满意的代码提供反馈,以及提交PR。
🙏? 谢谢
作者衷心感谢 Datatonic 的 Mirko Gilioli 和 Maurizio Ipsale 在撰写本文档和测试解决方案方面的帮助。