Cloud Run 私密访问 Cloud Storage 全球端点和区域端点

1. 简介

Google API 端点

Google Cloud API 提供不同类型的端点来访问服务,主要区别在于它们处理请求路由、数据驻留和区域隔离的方式。

请查看有关 API 端点类型的产品文档。

下面详细介绍了全球端点、区域端点和位置端点:

  1. 全局端点
  • 格式:{service}.googleapis.com(例如 storage.googleapis.com)
  • 说明:这些端点为服务提供单一的全局访问点。它们未在网址中指定区域。
  • 路由:请求由全球 Google Front End 前端 (GFE) 和全球服务负载均衡进行路由,通常会将流量导向最近的运行状况良好的区域,以最大限度地缩短延迟时间。
  • TLS 终止:发生在最靠近客户端的 GFE,该 GFE 可能位于数据或资源所在的 Google Cloud 区域之外。
  • 数据驻留:不保证传输中的数据驻留在特定区域。在 GFE 中解密后,数据可能会跨越区域边界。
  • 区域隔离:有限。虽然后端通常是区域性的,但入口点和负载均衡是全球性的,这意味着全球基础架构的一部分出现问题可能会影响其他区域的服务。
  • 使用情形:通用访问,其中地理位置分散的用户的低延迟是关键,而严格的数据驻留传输不是主要考虑因素。
  1. 单区域端点 (REP)
  • 格式:{service}.{location}.rep.googleapis.com(例如 storage.us-east1.rep.googleapis.com)
  • 说明:旨在提供强大的区域隔离和数据驻留保证。位置(特定 Google Cloud 区域)以子网域的形式指定。这是现代标准,正在取代位置端点。
  • 路由:使用完全区域化的前端堆栈,包括区域级外部负载平衡器和区域级服务负载均衡。从 DNS 到服务后端的整个请求路径都位于指定区域内。
  • TLS 终止:在区域级外部负载平衡器上指定区域内发生。
  • 数据驻留:保证数据在传输和使用过程中始终保留在指定区域内,满足严格的合规性和主权要求。
  • 区域隔离:强。一个区域的前端基础设施发生故障不会影响其他区域。
  • 使用场景:需要严格的数据驻留、高区域隔离和合规性的应用。

请注意,并非每个 Google API 都有区域级端点,如需查看支持的所有区域级端点,请点击此处

多区域区域端点 (mREP) 也是区域端点,例如 us(美国)、eu(欧盟)等(例如 storage.us.rep.googleapis.com)

  1. 位置端点 (LEP)
  • 格式:{location}-{service}.googleapis.com(例如 us-east1-storage.googleapis.com)
  • 说明:这些端点是提供特定于位置的访问权限的早期方法。相应位置是主主机名的一部分。注意:位置端点正被区域端点取代。
  • 路由:仍依赖于全球 Google Front Ends。
  • TLS 终止:通常发生在 GFE 上,而 GFE 可能不在主机名中指定的区域。
  • 数据驻留:无法保证来自公共互联网的流量在传输期间数据始终保留在指定区域内。
  • 区域隔离:弱于区域端点,因为它们使用全球前端基础架构。
  • 使用场景:过去曾用于某些区域访问场景,但现在一般不建议使用,而建议使用区域端点以获得更强的保证。

适用于 Google API 的 Private Service Connect

Private Service Connect 是 Google Cloud 网络的一项功能,允许使用方访问提供方服务。这包括通过托管在用户 VPC 中的专用端点连接到 Google API 的功能。

如何使用 PSC 端点访问 Google API:

如何使用 PSC 后端访问 Google API:

Cloud Run 将流量发送到 VPC 网络

直接 VPC 出站流量为 Cloud Run 提供了增强的基础架构和更简单的 VPC 出站流量配置,包括以下优势:

  • 设置:Cloud Run 服务和作业可以将流量发送到 VPC 网络,而无需管理无服务器 VPC 访问通道连接器的开销。
  • 费用:您只需支付网络流量费用,该服务可以像服务本身一样缩减至零。
  • 安全性:您可以直接在服务修订版本上使用网络标记,以实现更精细的网络安全。
  • 性能:延迟时间更短,吞吐量更高。

您可以启用 Cloud Run 服务、函数、作业或工作器池,以通过直接 VPC 出站流量将所有流量发送到 VPC 网络。

2. 学习内容

  • 如何为全球 Google API 创建 PSC 端点。
  • 如何为区域级 Google API 创建 PSC 端点。
  • 如何在 Cloud Run 代码中更改 API 端点并配置出站流量的网络。

3. 实验室整体架构

8f5328678688f210.png

4. 准备步骤

完成实验所需的 IAM 角色

首先,您需要在项目级层向 GCP 账号分配所需的 IAM 角色。

  • Compute Network Admin (roles/compute.networkAdmin):此角色可让您完全控制 Compute Engine 网络资源。
  • Logging 管理员 (roles/logging.admin):此角色可让您使用所有日志记录权限和相关权限。
  • Service Usage Admin (roles/serviceusage.serviceUsageAdmin):此角色可让您能够启用、停用和检查使用方项目的服务状态和操作,以及使用该项目的配额和结算服务。
  • DNS 管理员 (roles/dns.admin):此角色可让您对所有 Cloud DNS 资源拥有读写权限
  • Cloud Run Admin (roles/run.admin):此角色可让您完全控制所有 Cloud Run 资源。
  • Storage Admin (roles/storage.admin):此角色可让您完全控制对象和存储分区。

启用 API

在 Cloud Shell 中,确保您的项目已正确配置并设置了环境变量。

在 Cloud Shell 中,执行以下操作:

gcloud auth login
gcloud config set project <your project id>
export project_id=<your project id>
export region=<your region>
export zone=$region-a
echo $project_id
echo $region

在项目中启用所有必需的 Google API。在 Cloud Shell 中,执行以下操作:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  run.googleapis.com \
  compute.googleapis.com \
  dns.googleapis.com \
  servicedirectory.googleapis.com \
  networkconnectivity.googleapis.com

创建 VPC

在该项目中,创建一个具有自定义子网模式的 VPC 网络。在 Cloud Shell 中执行以下操作:

gcloud compute networks create mynet \
    --subnet-mode=custom

创建子网

在 Cloud Shell 中,执行以下操作以创建 IPv4 子网:

gcloud compute networks subnets create mysubnet \
    --network=mynet \
    --range=10.0.0.0/24 \
    --region=$region

创建 Cloud NAT 和 Cloud Router

Cloud NAT 用于允许 Cloud Run 作业连接到外部网站。

gcloud compute routers create $region-cr \
   --network=mynet \
   --region=$region 
gcloud compute routers nats create $region-nat \
    --router=$region-cr \
    --region=$region \
    --nat-all-subnet-ip-ranges \
    --auto-allocate-nat-external-ips

5. 为 Cloud Storage 创建 PSC 端点

您将为 Cloud Storage 创建两个 PSC 端点,一个用于全局范围,另一个用于区域范围。

创建全球范围的 PSC 端点

通过 Private Service Connect,您可以使用 VPC 网络中的全局内部 IP 地址创建全局范围的专用端点。

您需要分配一个未在 VPC 中定义的唯一 IP 地址。请参阅有关此 IP 地址要求的文档。

在 Cloud Shell 中,执行以下操作以创建 IP 地址。请将 –addresses=<pscendpointip> 更改为使用您已分配的 IP 地址。

gcloud compute addresses create pscglobalip \
    --global \
    --purpose=PRIVATE_SERVICE_CONNECT \
    --addresses=<pscendpointip> \
    --network=mynet
pscendpointip=$(gcloud compute addresses list --filter=name:pscglobalip --format="value(address)")
echo $pscendpointip

创建转发规则以将端点连接到 Google API 和服务。

gcloud compute forwarding-rules create pscendpoint \
    --global \
    --network=mynet \
    --address=pscglobalip \
    --target-google-apis-bundle=all-apis

在 Cloud DNS 中检查 p.googleapis.com

创建端点时,系统会自动创建以下 DNS 配置:

  • 为 p.googleapis.com 创建了一个 Service Directory 专用 DNS 区域
  • 系统会在 p.googleapis.com 中为一些常用 Google API 和服务(通过 Private Service Connect 提供且默认 DNS 名称以 googleapis.com 结尾)创建 DNS 记录

全局端点已向 Service Directory 注册。您将使用 storage-[PSC 端点名称].p.googleapis.com 访问 Cloud Storage。如需了解详情,请参阅产品文档

运行以下命令,检查 p.googleaps.com 区域是否已创建。

gcloud dns managed-zones list

如果您想使用默认 DNS 名称 storage.googleapis.com,则需要在 Cloud DNS 中创建专用区域 storage.googleapis.com,并添加指向全局范围 IP 地址的 PSC 端点的根记录。

为 Cloud Storage 创建区域范围的 PSC 端点

您将需要 VPC 子网中的一个 IP。运行以下命令,系统将为 PSC 端点分配子网中的一个 IP。

gcloud network-connectivity regional-endpoints create psc-regional-endpoint \
    --region=$region \
    --network=projects/$project_id/global/networks/mynet \
    --subnetwork=projects/$project_id/regions/$region/subnetworks/mysubnet \
    --target-google-api=storage.us-central1.rep.googleapis.com

获取上一步中创建的端点 IP 地址。

regionalip=$(gcloud network-connectivity regional-endpoints describe psc-regional-endpoint --region=$region --format="value(address)")
echo $regionalip

您将使用 storage.us-central1.rep.googleapis.com 访问 Cloud Storage。您需要为 storage.us-central1.rep.googleapis.com 创建一个专用区域,并在 Cloud DNS 中为刚刚创建的区域端点创建 IP 地址的根记录。

为 Cloud Storage 区域性端点创建专用可用区

您将使用 storage.[区域名称].rep.googleapis.com 访问 Cloud Storage 区域端点。

您需要在 Cloud DNS 中创建一个专用可用区,并添加一条指向 Cloud Storage 区域端点 IP 地址的根网域记录。

在以下命令中,us-central1 是示例区域。您应使用所在区域的名称创建可用区。

gcloud dns managed-zones create psc-regional-endpoint-zone \
  --description="" \
  --dns-name="storage.us-central1.rep.googleapis.com" \
  --visibility="private" \
  --networks="mynet"

gcloud dns record-sets create storage.us-central1.rep.googleapis.com. \
  --rrdatas=$regionalip \
  --ttl=300 \
  --type=A \
  --zone=psc-regional-endpoint-zone

6. 配置具有全局范围 PSC 端点的 Cloud Run 作业

获取代码

您首先要探索 Node.js 应用,了解如何截取网页屏幕截图并将其存储到 Cloud Storage 中。之后,您可以为该应用构建容器映像,并以作业的形式在 Cloud Run 上运行该应用。

在 Cloud Shell 中,运行以下命令以从该代码库克隆应用代码:

git clone https://github.com/GoogleCloudPlatform/jobs-demos.git

转到包含该应用的目录:

cd jobs-demos/screenshot

您应该会看到此文件布局:

|

├── Dockerfile

├── README.md

├── screenshot.js

├── package.json

以下是对每个文件的简要说明:

  • screenshot.js 包含应用的 Node.js 代码。该应用会截取网页的屏幕截图并将其存储在 Cloud Storage 中。
  • package.json 定义库依赖项。
  • Dockerfile 定义容器映像。

打开 screenshot.js 代码,您将把 apiEndpoint 更改为 PSC 全球端点。搜索代码并将 const storage = new Storage(); 替换为以下内容:

const storage = new Storage(
    {
      apiEndpoint:'https://storage-pscendpoint.p.googleapis.com.',
      useAuthWithCustomEndpoint: true
    }
  );

部署作业

在创建作业之前,您需要创建一个用于运行作业的服务账号。

gcloud iam service-accounts create screenshot-sa --display-name="Screenshot app service account"

向服务账号授予 storage.admin 角色,使其可用于创建存储分区和对象。

gcloud projects add-iam-policy-binding $project_id \
  --role roles/storage.admin \
  --member serviceAccount:screenshot-sa@$project_id.iam.gserviceaccount.com

向默认的 Compute 服务账号授予 Storage Object User 角色、Logs Writer 角色和 Artifact Registry Repository Administrator 角色。

project_number=$(gcloud projects describe $project_id --format="value(projectNumber)")

gcloud projects add-iam-policy-binding $project_id \
  --role roles/storage.objectUser \
  --member serviceAccount:$project_number-compute@developer.gserviceaccount.com

gcloud projects add-iam-policy-binding $project_id \
  --role roles/logging.logWriter \
  --member serviceAccount:$project_number-compute@developer.gserviceaccount.com

gcloud projects add-iam-policy-binding $project_id \
  --role roles/artifactregistry.repoAdmin \
  --member serviceAccount:$project_number-compute@developer.gserviceaccount.com

您将为 Cloud Run 作业启用直接 VPC 出站流量,以将所有流量发送到 VPC 网络。

在 Cloud Shell 中,执行以下操作:

gcloud run jobs deploy screenshot-1 \
  --source=. \
  --args="https://example.com" \
  --args="https://cloud.google.com" \
  --tasks=2 \
  --task-timeout=5m \
  --region=$region \
  --set-env-vars=BUCKET_NAME=screenshot-$project_id-$RANDOM \
  --service-account=screenshot-sa@$project_id.iam.gserviceaccount.com \
  --vpc-egress=all-traffic \
  --network=mynet \
  --subnet=mysubnet

运行作业

在 Cloud Shell 中,执行以下操作:

gcloud run jobs execute screenshot-1 --region=$region

检查作业的状态和日志。前往 Cloud Run 控制台,然后找到相应作业。您可以点击进入作业,然后查看日志的历史记录。您将看到如下所示的类似作业执行结果。

bae25d504ea20384.png

如需查看详细的作业执行日志,请点击任务中的“查看日志”。您将看到类似如下所示的作业日志。

aa0468dc463f4320.png

已创建新存储分区。您可以前往 Cloud Storage 控制台,查看新创建的存储分区。请注意,在使用 Cloud Storage 全球端点时,存储分区是多区域存储分区。您可以查看上传到存储分区的图片。

测试结果显示 Cloud Run 私下访问了您在 Cloud Run 作业中更改的 Cloud Storage 全局端点:

apiEndpoint:‘https://storage-pscendpoint.p.googleapis.com.'

7. 配置具有区域范围 PSC 端点的 Cloud Run 作业

在代码中,您将把 apiEndpoint 更改为具有区域级范围的 PSC 端点。

搜索代码并将 const storage = new Storage(); 替换为以下内容(我们以 us-central1 为例。请更改为您的区域):

const storage = new Storage(
    {
      apiEndpoint:'https://storage.us-central1.rep.googleapis.com.',
      useAuthWithCustomEndpoint: true
    }
  );

部署作业

确保您位于包含应用 (jobs-demos/screenshot) 的目录中。

pwd

您可以为作业启用直接 VPC 出站流量,以将所有流量发送到 VPC 网络。

在 Cloud Shell 中,执行以下操作:

gcloud run jobs deploy screenshot-2 \
  --source=. \
  --args="https://example.com" \
  --args="https://cloud.google.com" \
  --tasks=2 \
  --task-timeout=5m \
  --region=$region \
  --set-env-vars=BUCKET_NAME=screenshot-$PROJECT_ID-$RANDOM \
  --service-account=screenshot-sa@$project_id.iam.gserviceaccount.com \
  --vpc-egress=all-traffic \
  --network=mynet \
  --subnet=mysubnet

运行作业

在 Cloud Shell 中,执行以下操作:

gcloud run jobs execute screenshot-2 --region=$region

检查作业的状态和日志。前往 Cloud Run 控制台,然后找到相应作业。您可以点击相应作业,然后查看该作业的记录。您将看到如下所示的类似作业执行结果。

1065ce25136d355e.png

如需查看详细的作业执行日志,请点击“查看日志”。您将看到类似如下所示的作业日志。

837afb2f95a7049b.png

已创建新存储分区。您可以前往 Cloud Storage 控制台,查看新创建的存储分区。请注意,如果您使用 Cloud Storage 区域性端点,则存储分区是单区域存储分区。您可以查看上传到存储分区的图片。

测试结果显示 Cloud Run 私下访问了您在 Cloud Run 作业中更改的 Cloud Storage 区域端点:

apiEndpoint:‘https://storage.us-central1.rep.googleapis.com.'

8. 清理

清理 Cloud Run 作业

gcloud run jobs delete screenshot-1 \
  --region=$region --quiet
gcloud run jobs delete screenshot-2 \
  --region=$region --quiet

gcloud iam service-accounts delete screenshot-sa@$project_id.iam.gserviceaccount.com --quiet

清理 PSC 端点

gcloud compute forwarding-rules delete pscendpoint \
    --global --quiet
gcloud network-connectivity regional-endpoints delete psc-regional-endpoint \
    --region=$region --quiet
gcloud compute addresses delete pscglobalip \
    --global --quiet

清理 Cloud NAT、Cloud Router 和 VPC

gcloud compute routers nats delete $region-nat \
    --router=$region-cr \
    --region=$region --quiet
gcloud compute routers delete $region-cr \
    --region=$region --quiet
gcloud compute networks subnets delete mysubnet \
    --region=$region --quiet
gcloud compute networks delete mynet --quiet

9. 恭喜

您已成功测试了 Cloud Run 通过全局端点和区域端点对 Cloud Storage 的私密访问。