直接 VPC 出站流量为您的 App Engine 服务提供高性能网络解决方案,以便将流量发送到 Virtual Private Cloud (VPC) 网络。借助直接 VPC 出站流量,工作负载可以无缝访问 VPC 网络资源,而无需配置无服务器 VPC 访问通道连接器。
主要优势
- 简化管理:消除管理连接器实例、机器类型和伸缩设置的运营开销。App Engine 直接在服务的
app.yaml文件中处理配置。 - 成本效益:使用直接 VPC 出站流量无需额外付费,并且您无需为连接器虚拟机支付固定的月度费用。
- 提高性能和可靠性:直接 VPC 出站流量无需使用连接器,可提供更快、更可靠的 VPC 网络资源连接。它会随着 App Engine 服务的扩缩而快速扩缩,并避免在维护期间连接器可能发生的连接中断。
精细的安全性:您可以直接将网络标记应用于 App Engine 服务版本,从而实现精确、特定于服务的防火墙规则和网络政策。
支持 VPC 流日志:您可以在子网上启用 VPC 流日志,以记录来自 App Engine 服务的出站流量。
支持 Cloud NAT:您可以在子网上配置 Cloud NAT 网关,以便为 App Engine 服务的出站流量提供 NAT 服务,例如 Public NAT 或 Private NAT。
限制
IP 地址消耗:服务的 IP 地址用量会直接随正在运行的实例数量而伸缩,并且伸缩能力受所选子网中可用 IP 地址数量的限制。
维护事件:在网络基础设施维护事件期间,您的服务可能会遇到短暂的连接中断。我们建议您使用客户端库来处理偶尔的连接重置。
冷启动:初始冷启动时间取决于区域和具体用例。在极少数情况下,冷启动可能需要长达一分钟。
直接 VPC 入站流量:App Engine 不支持直接 VPC 入站流量。
实例数量:默认情况下,每个 App Engine 版本最多只能配置 100 个实例来使用直接 VPC 出站流量。如果您的工作负载需要更多实例,您可以申请增加配额。
VPC 流日志:不会在日志记录中显示 App Engine 服务版本。服务名称显示在
AppEngineServiceDetails字段中。区域可用性:直接 VPC 出站流量仅在特定区域通过邀请提供。如需在这些区域申请访问权限,请与支持团队联系。
IP 地址分配
如需将 App Engine 服务置于 VPC 网络中,请指定 VPC 网络或子网,或同时指定两者。如果您仅指定网络,则子网会使用与网络相同的名称。 App Engine 会分配子网中的 IP 地址。
IP 地址是临时性的,因此请勿基于各个 IP 创建政策。如果您需要基于 IP 创建政策(例如防火墙规则),则必须使用整个子网的 IP 地址范围。
如需更改服务使用的网络或子网,请部署使用新的网络和子网值的新版本。
扩容和缩容
为在发生流量激增时实现快速扩容,App Engine 会一次性预留 16 个 IP 地址块(28 子网掩码)。为了确保有足够的 IPv4 地址可在 App Engine 中使用,子网的 IPv4 地址范围必须为 /26 或更大。
为了提高 IP 分配效率和易于管理,请将多个资源置于同一子网中。如果 IPv4 地址空间有限,请参阅支持的 IPv4 范围以了解更多选项。
如需删除子网,您必须先删除或重新部署 App Engine 服务以停止使用子网,然后等待 1-2 小时。
服务的 IP 地址消耗量
在稳定状态下,App Engine 使用的 IP 地址数量是实例数量的 2 倍 (2X)。版本缩容时,App Engine 会将其 IP 地址保留最多 20 分钟。总共预留至少 2 倍的 IP 地址数量,再加上考虑到版本更新的缓冲空间。
例如,如果您升级版本,使 version 1 从 100 个实例缩减到零,而 version 2 从零扩容到 100,则 App Engine 会在缩容之后将 version 1 IP 地址保留最多 20 分钟。在 20 分钟的保留窗口内,您必须至少预留 400 个 IP 地址 ((100 + 100) * 2)。
支持的 IPv4 范围
App Engine 支持子网的以下 IPv4 范围:
准备工作
确保您的项目中已有 VPC 网络和子网。如果您还没有现有 VPC,请按照创建 VPC 网络中的说明创建一个。
启用 Compute Engine API 和 Cloud Build API:
如需使用直接 VPC 出站流量,请确保您运行的是最新版本的 Google Cloud CLI:
gcloud components update
所需的角色
通过向 App Engine 服务代理授予以下角色,确保 App Engine 有权访问 VPC 网络:
App Engine Service Agent 角色:默认情况下,App Engine 服务代理具有 App Engine Service Agent 角色 (
roles/appengine.serviceAgent),该角色含有必要的权限。自定义权限:如需进行更精细的控制,请向 App Engine 服务代理授予对项目的以下额外权限:
compute.networks.getcompute.subnetworks.get- 项目或特定子网的
compute.subnetworks.use权限 compute.addresses.getcompute.addresses.listcompute.addresses.createcompute.addresses.deletecompute.addresses.createInternalcompute.addresses.deleteInternalcompute.regionOperations.get
Compute Network User 角色:如果您不使用默认 App Engine Service Agent 角色或自定义权限,请向 App Engine 服务代理授予 Compute Network User 角色 (
roles/compute.networkUser)。具有外部 IPv6 的子网还需要 Compute Public IP Admin 角色 (roles/compute.publicIpAdmin)。例如,如需授予 Compute Network User 角色,请运行以下命令:
gcloud projects add-iam-policy-binding PROJECT_ID \ --member "serviceAccount:service-PROJECT_NUMBER@gcp-gae-service." \ --role "roles/compute.networkUser"
替换以下内容:
- PROJECT_ID:您的项目的 ID。
- PROJECT_NUMBER:您在其中部署 App Engine 服务的项目编号。
为 App Engine 服务配置直接 VPC 出站流量
您可以使用 YAML 或 Terraform 为 App Engine 服务配置直接 VPC 出站流量。如需启用或断开直接 VPC 出站流量,请部署新版本并将流量迁移到该版本。您也可以先删除已部署的版本,而不是覆盖现有版本 ID。
YAML
将以下
vpc_access设置添加到app.yaml文件中:vpc_access: network_interface: network: NETWORK subnet: SUBNET tags: - NETWORK_TAGS vpc_egress: EGRESS_SETTING
替换以下内容:
NETWORK:应用实例连接到的现有网络的名称,例如
default。指定 VPC 网络或子网,或同时指定两者。如果您仅指定网络,则子网会使用与网络相同的名称。SUBNET:应用实例连接到的现有子网的名称,例如
default。指定 VPC 网络或子网,或同时指定两者。如果您仅指定网络,则子网会使用与网络相同的名称。可选:NETWORK_TAGS 列出了要与 App Engine 服务的实例关联的网络标记,以便在防火墙规则和路由政策中使用。
可选:EGRESS_SETTING 控制出站流量的路由方式。此字段支持以下配置设置:
all-traffic:所有出站请求都通过 VPC 网络进行路由。private-ranges-only(默认):只有发送到内部 IP 地址的流量才会通过 VPC 网络进行路由。网络流量使用默认的 App Engine 路径。
运行以下命令,将应用部署到 App Engine:
gcloud app deploy
Terraform
如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令。
将以下
vpc_access块添加到 Terraform 配置中的google_app_engine_standard_app_version资源:vpc_access { vpc_egress = "EGRESS_SETTING" network_interfaces { network = "NETWORK" subnetwork = "SUBNET" tags = ["TAG_1", "TAG_2"] } }
替换以下内容:
- NETWORK:应用实例连接到的现有 VPC 网络的名称,例如
default。指定 VPC 网络或子网,或同时指定两者。如果您仅指定网络,则子网会使用与网络相同的名称。您还可以引用google_compute_network资源名称(例如google_compute_network.custom.name)。 - SUBNET:应用实例连接到的现有子网的名称,例如
default。指定 VPC 网络或子网,或同时指定两者。如果您仅指定网络,则子网会使用与网络相同的名称。您还可以引用google_compute_subnetwork资源名称(例如google_compute_subnetwork.custom.name)。 - 可选:TAG_1、TAG_2 列出了要与 App Engine 服务的实例关联的网络标记,以便在防火墙规则和路由政策中使用。
- 可选:EGRESS_SETTING 控制出站流量的路由方式。此字段支持以下配置设置:
ALL_TRAFFIC:所有出站请求都通过 VPC 网络进行路由。PRIVATE_IP_RANGES(默认):只有发送到内部 IP 地址的流量才会通过 VPC 网络进行路由。网络流量使用默认的 App Engine 路径。
- NETWORK:应用实例连接到的现有 VPC 网络的名称,例如
如果该版本已部署,但未使用直接 VPC 出站流量,请将
version_id字段更新为新值。您无法在现有版本上启用直接 VPC 出站流量。应用配置:
terraform apply
断开服务连接
如需断开服务与 VPC 网络的连接,请使用 YAML 或 Terraform:
YAML
从
app.yaml文件中移除vpc_access部分。重新部署服务:
gcloud app deploy
Terraform
从 Terraform 配置中的
google_app_engine_standard_app_version资源中移除vpc_access块。将
version_id字段更新为新值。您无法在现有版本上停用直接 VPC 出站流量。应用配置:
terraform apply
隔离出站互联网流量
默认情况下,当 vpc_egress 设置为 private-ranges-only 时,App Engine 会通过在无服务器工作负载之间共享的动态 IP 地址的区域池发送出站互联网流量。对于依赖 IP 信誉或生成大量探测流量的工作负载,请勿使用此默认共享池。
在以下情况下,请改为设置 vpc_egress: all-traffic,并通过具有专用静态出站 IP 地址的 Cloud NAT 路由出站流量:
- 您的服务连接到对信誉敏感的外部端点,例如第三方 Web 应用防火墙 (WAF) 后面的 Payment Gateway、托管式数据库或合作伙伴 API。专用静态 IP 地址可防止共享池中其他租户的干扰流量触发外部 WAF 屏蔽或
HTTP 403错误。 - 您的服务会运行授权的网络扫描、端口枚举、主机指纹识别、漏洞探测、网络抓取或负载测试。通过默认共享 IP 池运行这些工作负载会降低 IP 信誉,可能会中断其他客户的服务,违反Google Cloud 使用限制政策,并可能导致 Google 限制或暂停您的工作负载。
通过 Cloud NAT 运行授权扫描或高连接工作负载时,请分配足够的静态 IP 地址并配置端口预留,以防止端口耗尽。
问题排查
本部分介绍了在使用直接 VPC 出站流量部署 App Engine 服务时可能会遇到的常见错误。
无法删除子网
如需删除子网,您必须先删除或重新部署使用该子网的所有资源。如果 App Engine 使用子网,请将 App Engine 服务与 VPC 网络断开连接,或将其移至其他子网,然后才能删除子网。
删除或移动 App Engine 服务后,请等待 1-2 小时,以便 App Engine 释放 IP 地址,然后再删除子网。
部署失败
如果部署失败,Google Cloud CLI 会显示出错提示,指明根本原因。一些常见问题包括:
VPC 元数据不正确,例如
app.yaml文件中的网络或子网名称拼写错误。如需修正潜在错误,请查看app.yaml文件中的 VPC 配置。IAM 权限不足。确保您向 App Engine 服务代理授予所需权限。如果您在部署期间遇到权限错误,请确保向部署服务账号授予以下额外角色:
- Cloud Build 服务账号 (
roles/cloudbuild.builds.builder) - Service Account Token Creator (
roles/iam.serviceAccountTokenCreator)
- Cloud Build 服务账号 (
IP 地址耗尽
如果子网中的可用 IP 地址用尽,App Engine 将无法启动新实例,并会记录错误。如需解决此问题,请扩大子网的 IP 范围,或将服务移至更大的子网。
IP 地址泄露
IP 地址泄露可能会导致 IP 地址耗尽。在标准操作期间,IP 地址不太可能泄露,但可能会由于以下原因而泄露:
- App Engine 服务代理仅有权预留地址(
create、createInternal),无权释放地址(delete、deleteInternal)。 - App Engine 服务代理在其他 Google Cloud 地址预留处于活动状态时被删除。
- 在无服务器地址预留处于活跃状态时,Cloud Billing 账号已从项目中移除,随后又重新启用。
- 您的 Google Cloud 项目已被删除,随后在无服务器地址预留仍然存在时恢复。
如需解决此问题,请按以下步骤操作:
在Logs Explorer中查询以下日志,以找出泄露的地址:
protoPayload.authorizationInfo.permission=~"compute.addresses.delete.*" protoPayload.authorizationInfo.resourceAttributes.type="compute.addresses" protoPayload.resourceName=~"projects/.*/regions/.*/addresses/serverless-.*" severity>=WARNING如果此查询未返回结果,则表示没有 IP 地址泄露,您无需采取进一步措施。
如果您的查询返回结果,请确保 App Engine 服务代理具有 App Engine Service Agent 角色 (
roles/appengine.serviceAgent)。如果您无法使用此角色,请确保向 App Engine 服务代理授予其他必需的角色和权限。使用 Google Cloud 控制台或 Google Cloud CLI 手动删除泄露的 IP 地址:
控制台
在 Google Cloud 控制台中,前往 IP 地址页面:
选择您在上一步中通过运行查询发现的泄露 IP 地址。
点击释放静态地址,移除泄露的地址。
gcloud
运行
gcloud compute addresses delete命令:gcloud compute addresses delete ADDRESS_NAME --region=REGION
替换以下内容:
- ADDRESS_NAME:泄露的 IP 地址的名称。
- REGION:泄露的 IP 地址所在的区域。