1. 概览
在本实验中,您将创建 Cymbal Eats 菜单服务,公开用于添加、更新、删除和列出菜单项的 RESTful API。您将创建一个 Cloud SQL 数据库,作为菜单服务的后端数据库,该菜单服务将在 Cloud Run 中运行。由于 Cloud Run 与 Cloud SQL 数据库不位于同一 VPC,因此您需要配置无服务器 VPC 访问通道连接器,以允许 Cloud Run 通过专用 IP 地址与 Cloud SQL 通信。
学习内容
在本实验中,您将学习如何完成以下操作:
- 配置专用 VPC 网络
- 创建专用 Postgres Cloud SQL 数据库
- 将 CloudRun 连接到专用 VPC
- 在 Cloud Run 上部署一项连接到 Cloud SQL 数据库的服务
2. 设置和要求
自定进度的环境设置
- 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个。
- 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
- 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常您不在乎这是什么在大多数 Codelab 中,您都需要引用项目 ID(它通常标识为
PROJECT_ID
)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且该 ID 在项目期间会一直保留。 - 此外,还有第三个值,即某些 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档。
- 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。如需关停资源,以免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除整个项目。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。
环境设置
- 创建与项目和资源相关的环境变量
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export PROJECT_NAME=$(gcloud projects describe $PROJECT_ID --format='value(name)')
export REGION=us-east1
export MENU_SERVICE_NAME=menu-service
export SERVERLESS_VPC_CONNECTOR=cymbalconnector
export DB_INSTANCE_NAME=menu-catalog
export DB_INSTANCE_PASSWORD=password123
export DB_DATABASE=menu-db
export DB_USER=menu-user
export DB_PASSWORD=menupassword123
- 克隆代码库并导航到相应目录
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/menu-service
- 启用服务
gcloud services enable \
sqladmin.googleapis.com \
run.googleapis.com \
vpcaccess.googleapis.com \
servicenetworking.googleapis.com
3. 配置专用访问通道
专用服务访问通道是作为您的 VPC 网络与 Cloud SQL 实例所在的底层 Google Cloud VPC 网络之间的 VPC 对等互连链路提供的。通过专用连接,您的 VPC 网络中的虚拟机实例和您使用的服务只能通过内部 IP 地址进行通信。如需访问通过专用服务访问通道提供的服务,虚拟机实例不需要互联网连接或外部 IP 地址。
- 分配 IP 地址范围
gcloud compute addresses create google-managed-services-default \
--global \
--purpose=VPC_PEERING \
--prefix-length=20 \
--network=projects/$PROJECT_ID/global/networks/default
输出示例
Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-2-348215/global/addresses/google-managed-services-default].
- 创建专用连接。
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=google-managed-services-default \
--network=default \
--project=$PROJECT_ID
输出示例
Operation "operations/pssn.p24-528514492617-2f2b507f-e4e5-4d53-a4de-9ddaceb4e92f" finished successfully.
4. 设置 Cloud SQL
Cloud SQL 是一种全代管式数据库服务,让您可以轻松地在云端设置、维护、管理和控制 PostgreSQL 和 MySQL 关系型数据库。每个 Cloud SQL 实例都由一个在 Google Cloud 主机服务器上运行的虚拟机 (VM) 提供支持。高可用性选项还包含另一个可用区中的备用虚拟机,其设置与主虚拟机相同。该数据库保存在可扩缩且持久的网络存储设备(称为永久性磁盘)上,该设备已连接到虚拟机。系统会为每个虚拟机分配一个静态 IP 地址,以确保应用连接的 IP 地址在 Cloud SQL 实例的生命周期内保持不变。
您将创建一个具有专用 IP 地址的 Postgres Cloud SQL 数据库。
创建数据库和用户
- 创建 Postgres Cloud SQL 实例以使用专用 IP
gcloud sql instances create $DB_INSTANCE_NAME \
--project=$PROJECT_ID \
--network=projects/$PROJECT_ID/global/networks/default \
--no-assign-ip \
--database-version=POSTGRES_12 \
--cpu=2 \
--memory=4GB \
--region=$REGION \
--root-password=${DB_INSTANCE_PASSWORD}
输出示例
Created [https://sqladmin.googleapis.com/sql/v1beta4/projects/cymbal1/instances/menu-instance]. NAME: menu-instance DATABASE_VERSION: POSTGRES_12 LOCATION: us-east1-a TIER: db-custom-2-4096 PRIMARY_ADDRESS: - PRIVATE_ADDRESS: 10.8.80.5 STATUS: RUNNABLE
- 向数据库实例添加数据库
gcloud sql databases create $DB_DATABASE --instance=$DB_INSTANCE_NAME
输出示例
Created database [menu-db]. instance: menu-catalog name: menu-db project: cymbal1
- 创建 SQL 用户
gcloud sql users create ${DB_USER} \
--password=$DB_PASSWORD \
--instance=$DB_INSTANCE_NAME
输出示例
Created user [menu-user].
- 存储数据库 IP 地址
export DB_INSTANCE_IP=$(gcloud sql instances describe $DB_INSTANCE_NAME \
--format=json | jq \
--raw-output ".ipAddresses[].ipAddress")
- 将 Cloud SQL Client 角色添加到 Compute Engine 服务账号
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/cloudsql.client"
输出示例
Updated IAM policy for project [cymbal1]. [...]
5. 无服务器 VPC
借助无服务器 VPC 访问通道,您可以从 Cloud Run、App Engine 或 Cloud Functions 等无服务器环境直接连接到 Virtual Private Cloud 网络。通过配置无服务器 VPC 访问通道,您的无服务器环境可以使用内部 DNS 和内部 IP 地址(如 RFC 1918 和 RFC 6598 所定义)向您的 VPC 网络发送请求。对这些请求的响应也会使用您的内部网络。
您将为 Cloud Run 服务创建一个无服务器 VPC 访问通道连接器,以连接到 Cloud SQL。
- 在 Cloud SQL 实例所在的 VPC 网络中创建一个无服务器 VPC 访问通道连接器。
gcloud compute networks vpc-access connectors create ${SERVERLESS_VPC_CONNECTOR} \
--region=${REGION} \
--range=10.8.0.0/28
输出示例
Created connector [cymbalconnector].
6. 部署到 Cloud Run
您将构建 Docker 映像并将其部署到 Cloud Run,然后将 Cloud Run 连接到无服务器 VPC 连接器以访问 Cloud SQL 数据库。
- 使用 Maven 编译应用
./mvnw package -DskipTests
输出示例
[...] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 42.864 s [INFO] Finished at: 2022-04-28T16:15:33Z [INFO] ------------------------------------------------------------------------
- 构建 Docker 映像:
docker build -f src/main/docker/Dockerfile.jvm \
--tag gcr.io/$PROJECT_NAME/menu-service .
输出示例
[...] Successfully built 4ef5d7a3befc Successfully tagged gcr.io/cymbal1/menu-service:latest
- 将 Docker 映像推送到 Container Registry:
docker push gcr.io/$PROJECT_NAME/menu-service
输出示例
Using default tag: latest The push refers to repository [gcr.io/cymbalsql/menu-service] 17b374963800: Pushed d9a51c06430d: Pushed fff5d2a2cfc9: Pushed f21fceb558c6: Pushed 5ffbbbf218dd: Pushed 60609ec85f86: Layer already exists f2c4302f03b8: Layer already exists latest: digest: sha256:f64cb7c288dbf4ad9b12bd210c23c5aec1048dee040450ff2d9dbdf96e83a426 size: 1789
- 部署菜单服务:
gcloud run deploy $MENU_SERVICE_NAME \
--image=gcr.io/$PROJECT_NAME/menu-service:latest \
--region $REGION \
--allow-unauthenticated \
--set-env-vars DB_USER=$DB_USER \
--set-env-vars DB_PASS=$DB_PASSWORD \
--set-env-vars DB_DATABASE=$DB_DATABASE \
--set-env-vars DB_HOST=$DB_INSTANCE_IP \
--vpc-connector $SERVERLESS_VPC_CONNECTOR \
--project=$PROJECT_ID \
--quiet
输出示例
[...] Done. Service [menu-service] revision [menu-service-00002-xox] has been deployed and is serving 100 percent of traffic. Service URL: https://menu-service-g2mfphytdq-uk.a.run.app
Google 建议您使用 Secret Manager 来存储 SQL 凭据等敏感信息。您可以使用 Cloud Run 将 Secret 作为环境变量传递或作为卷装载。
- 商店菜单服务网址:
MENU_SERVICE_URL=$(gcloud run services describe menu-service \
--platform managed \
--region $REGION \
--format=json | jq \
--raw-output ".status.url")
- 验证菜单服务网址
echo $MENU_SERVICE_URL
输出示例
https://menu-service-g2mfphytdq-uk.a.run.app
7. 测试服务
- 通过发送 POST 请求创建新菜单项:
curl -X POST "${MENU_SERVICE_URL}/menu" \
-H 'Content-Type: application/json' \
-d '{
"itemImageURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
"itemName": "Curry Plate",
"itemPrice": 12.5,
"itemThumbnailURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
"spiceLevel": 3,
"status": "Ready",
"tagLine": "Spicy touch for your taste buds!!"
}'
输出示例
{ "id": 16, "createDateTime": "2022-04-28T18:14:04.17225", "itemImageURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80", "itemName": "Curry Plate", "itemPrice": 12.5, "itemThumbnailURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80", "spiceLevel": 3, "status": "Processing", "tagLine": "Spicy touch for your taste buds!!", "updateDateTime": "2022-04-28T18:14:04.172298" }
- 通过发送 PUT 请求来更改菜单项的状态:
curl -X PUT "${MENU_SERVICE_URL}/menu/1" \
-H 'Content-Type: application/json' \
-d '{"status": "Ready"}'
输出示例
{ "id": 1, "createDateTime": "2022-04-28T17:21:02.369093", "itemImageURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80", "itemName": "Curry Plate", "itemPrice": 12.50, "itemThumbnailURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80", "spiceLevel": 0, "status": "Ready", "tagLine": "Spicy touch for your taste buds!!", "updateDateTime": "2022-04-28T17:21:02.657636" }
8. 恭喜!
恭喜,您已完成此 Codelab!
后续步骤:
探索其他 Cymbal Eats Codelab:
- 使用 Eventarc 触发 Cloud Workflows
- 从 Cloud Storage 触发事件处理
- 从 Cloud Run 连接到全代管式数据库
- 使用 Identity-Aware Proxy (IAP) 保护无服务器应用
- 使用 Cloud Scheduler 触发 Cloud Run 作业
- 安全地部署到 Cloud Run
- 保护 Cloud Run 入站流量
- 从 GKE Autopilot 连接到专用 AlloyDB
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
若要避免产生费用,最简单的方法是删除您为本教程创建的项目。