直接 VPC 出站流量

直接 VPC 出站流量为您的 App Engine 服务提供高性能网络解决方案,以便将流量发送到虚拟私有云 (VPC) 网络。借助直接 VPC 出站流量,工作负载可以无缝访问 VPC 网络资源,而无需配置无服务器 VPC 访问通道连接器。

主要优势

  • 简化管理:消除管理连接器实例、机器类型和伸缩设置的运营开销。App Engine 直接在服务的 app.yaml 文件中处理配置。
  • 成本效益:使用直接 VPC 出站流量无需支付额外费用,您也无需为连接器虚拟机支付固定的每月费用。
  • 提升性能和可靠性:直接 VPC 出站流量无需使用连接器,可提供更快、更可靠的 VPC 网络资源连接。它会随着 App Engine 服务快速扩缩,并避免在维护期间连接器可能发生的连接中断。
  • 精细的安全性:您可以直接将网络标记应用于 App Engine 服务版本,从而实现精确、特定于服务的防火墙规则和网络政策。

  • 支持 VPC 流日志:您可以在子网上启用 VPC 流日志,以记录来自 App Engine 服务的出站流量。

限制

  • IP 地址消耗:服务的 IP 地址用量会直接随正在运行的实例数量而伸缩,并且伸缩能力受所选子网中可用 IP 地址数量的限制。

  • 维护事件:在网络基础设施维护事件期间,您的服务可能会遇到短暂的连接中断。我们建议您使用客户端库来处理偶尔的连接重置。

  • 冷启动:初始冷启动时间取决于区域和具体用例。在极少数情况下,冷启动可能需要长达一分钟。

  • 直接 VPC 入站流量:App Engine 不支持直接 VPC 入站流量。

  • 实例数量:每个 App Engine 版本最多只能配置 100 个实例来使用直接 VPC 出站流量。

  • VPC 流日志:不会在日志记录中显示 App Engine 服务版本。服务名称显示在 AppEngineServiceDetails 字段中。

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 范围:

  • RFC 1918
    • 10.0.0.0/8
    • 172.16.0.0/12
    • 192.168.0.0/16
  • RFC 6598
    • 100.64.0.0/10
  • E 类
    • 240.0.0.0/4

准备工作

  1. 确保您的项目中已有 VPC 网络和子网。如果您还没有现有 VPC,请按照创建 VPC 网络中的说明创建一个。

  2. 启用 Compute Engine API 和 Cloud Build API:

    启用 API

  3. 如需使用直接 VPC 出站流量,请确保您运行的是最新版本的 Google Cloud CLI:

    gcloud components update

所需的角色

通过向部署服务账号授予以下角色,确保 App Engine 可以访问 VPC 网络:

  • App Engine Service Agent 角色:默认情况下,App Engine 服务代理具有 App Engine Service Agent 角色 (roles/appengine.serviceAgent),该角色含有必要的权限。

  • 自定义权限:如需进行更精细的控制,请向 App Engine 服务代理授予对项目的以下额外权限:

    • compute.networks.get
    • compute.subnetworks.get
    • 项目或特定子网的 compute.subnetworks.use 权限
    • compute.addresses.get
    • compute.addresses.list
    • compute.addresses.create
    • compute.addresses.delete
    • compute.addresses.createInternal
    • compute.addresses.deleteInternal
    • compute.regionOperations.get
  • Compute Network User 角色:如果您不使用默认 App Engine Service Agent 角色或自定义权限,请授予 App Engine Service Agent 服务账号的 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.iam.gserviceaccount.com" \
    --role "roles/compute.networkUser"

    替换以下内容:

    • PROJECT_ID:您的项目的 ID。
    • PROJECT_NUMBER:您在其中部署 App Engine 服务的项目编号。

为 App Engine 服务配置直接 VPC 出站流量

如需使新的或现有的 App Engine 服务能够直接连接到您的 VPC 网络,请按照以下步骤操作:

  1. 将以下 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 路径。
  2. 运行以下命令,将应用部署到 App Engine:

    gcloud beta app deploy

断开服务连接

如需断开服务与 VPC 网络的连接,请执行以下操作:

  1. 从 app.yaml 文件中移除 vpc_access 部分。

  2. 重新部署服务:

    gcloud beta app deploy

IP 管理最佳实践

由于服务的每个实例都会使用子网中的 IP 地址,因此您需要管理 IP 地址。使用以下策略管理 IP 地址:

  • 建议的 IP 范围:为获得最佳兼容性,我们建议您先使用 RFC 6598 (100.64.0.0/10) 范围。

  • 备用 IP 范围:如果您已在使用推荐的 IP 范围 100.64.0.0/10,则可以在子网中使用非 RFC 1918 范围,例如 E 类 (240.0.0.0/4)。

  • 子网大小:确保子网的 IPv4 地址范围为 /26 或更大,以便为伸缩提供足够的地址。

  • 超额预配 IP:我们建议超额预配子网中的可用 IP 数量,以避免耗尽。与 Cloud Run 服务类似,您通常应使用运行实例数量 4 倍的 IP 地址(稳定状态下为 2 倍,部署期间额外增加 2 倍),以实现顺畅伸缩和更新。

隔离出站互联网流量

默认情况下,当 vpc_egress 设置为 private-ranges-only 时,App Engine 会通过在无服务器工作负载之间共享的动态 IP 地址区域池发送出站互联网流量。对于依赖 IP 信誉或会产生大量探测流量的工作负载,请勿使用此默认共享池。

相反,在以下情况下,请设置 vpc_egress: all-traffic 并通过具有专用静态出站 IP 地址的 Cloud NAT 路由出站流量:

  • 您的服务连接到对信誉敏感的外部端点,例如第三方 Web 应用防火墙 (WAF) 后面的支付网关、托管式数据库或合作伙伴 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 权限不足。请确保您向部署服务账号授予了所需权限。如果您在部署期间遇到权限错误,请确保向服务账号授予以下额外角色:

IP 地址耗尽

如果子网的可用 IP 地址用尽,App Engine 将无法启动新实例,并会记录错误。如需解决此问题,请扩展子网的 IP 范围,或将服务移至更大的子网。

IP 地址泄露

IP 地址泄露可能会导致 IP 地址耗尽。在标准操作期间,IP 地址不太可能泄露,但可能会由于以下原因而发生:

  • 您的部署服务账号仅有权预留地址(create、createInternal),无权释放地址(delete、deleteInternal)。
  • 您的服务账号已被删除,而其他 Google Cloud 地址预留处于有效状态。
  • 在无服务器地址预留处于活跃状态时,Cloud Billing 账号已从项目中移除,随后又重新启用。
  • 您的 Google Cloud 项目已被删除,随后在无服务器地址预留仍然存在时恢复。

如需解决此问题,请按以下步骤操作:

  1. 在Logs Explorer中查询以下日志,以找出泄露的地址:

    protoPayload.authorizationInfo.permission=~"compute.addresses.delete.*"
    protoPayload.authorizationInfo.resourceAttributes.type="compute.addresses"
    protoPayload.resourceName=~"projects/.*/regions/.*/addresses/serverless-.*"
    severity>=WARNING
    

    如果此查询未返回结果,则表示没有 IP 地址泄露,无需采取进一步措施。

  2. 如果查询返回结果,请确保您的部署服务账号包含 App Engine Service Agent 角色 (roles/appengine.serviceAgent)。如果您无法使用此角色,请确保向部署服务账号授予其他必需的角色和权限。

  3. 使用 Google Cloud 控制台或 Google Cloud CLI 手动删除泄露的 IP 地址:

    控制台

    1. 在 Google Cloud 控制台中,前往 IP 地址页面:

      进入“IP 地址”

    2. 选择您在上一步中通过运行查询发现的泄露 IP 地址。

    3. 点击释放静态地址,移除泄露的地址。

    gcloud

    运行 gcloud compute addresses delete 命令:

    gcloud compute addresses delete ADDRESS_NAME --region=REGION

    替换以下内容:

    • ADDRESS_NAME:泄露的 IP 地址的名称。
    • REGION:泄露的 IP 地址所在的区域。