App Engine 服务的出站 IP 地址

出站服务(例如,网址提取、套接字和 Mail API)使用大型 IP 地址池。此池中的 IP 地址范围可能会进行日常更改。实际上,来自同一应用的两个连续 API 调用可能看上去源于两个不同的 IP 地址。

如果您需要知道与服务的出站流量相关联的 IP 地址,则可以找到服务的当前 IP 地址范围,或为您的服务设置静态 IP 地址。

App Engine 服务的 IP 地址

您可以根据 Google 发布的 IP 范围信息查找 App Engine 服务的当前 IP 地址范围:

  • Google 在 goog.json 中发布了其向互联网用户提供的完整 IP 范围列表。

  • Google 还在 cloud.json 中发布了可用于客户的 Google Cloud 资源的全球和区域外部 IP 地址范围列表。

Google API 和服务使用的 IP 地址范围是,从 goog.json 的范围中减去 cloud.json 的所有范围之后所得的一系列 IP 地址范围。这些列表会经常更新。

您可以使用以下 Python 脚本创建 IP 地址范围列表,其中包含 Google API 和服务使用的 IP 地址范围。

如需了解如何运行此脚本,请参阅运行方式

from __future__ import print_function

import json

try:
    from urllib import urlopen
except ImportError:
    from urllib.request import urlopen
    from urllib.error import HTTPError

import netaddr

IPRANGE_URLS = {
    "goog": "https://www.gstatic.com/ipranges/goog.json",
    "cloud": "https://www.gstatic.com/ipranges/cloud.json",
}


def read_url(url):
    try:
        return json.loads(urlopen(url).read())
    except (IOError, HTTPError):
        print("ERROR: Invalid HTTP response from %s" % url)
    except json.decoder.JSONDecodeError:
        print("ERROR: Could not parse HTTP response from %s" % url)


def get_data(link):
    data = read_url(link)
    if data:
        print("{} published: {}".format(link, data.get("creationTime")))
        cidrs = netaddr.IPSet()
        for e in data["prefixes"]:
            if "ipv4Prefix" in e:
                cidrs.add(e.get("ipv4Prefix"))
            if "ipv6Prefix" in e:
                cidrs.add(e.get("ipv6Prefix"))
        return cidrs


def main():
    cidrs = {group: get_data(link) for group, link in IPRANGE_URLS.items()}
    if len(cidrs) != 2:
        raise ValueError("ERROR: Could process data from Google")
    print("IP ranges for Google APIs and services default domains:")
    for ip in (cidrs["goog"] - cidrs["cloud"]).iter_cidrs():
        print(ip)


if __name__ == "__main__":
    main()

设置静态出站 IP 地址

如需为 App Engine 标准环境服务设置静态 IP 地址,请将无服务器 VPC 访问通道与 Cloud Router 和 Cloud NAT 搭配使用。通过使用无服务器 VPC 访问通道,您可以将出站流量发送到 Virtual Private Cloud (VPC) 网络。通过在 VPC 上使用网络地址转换 (NAT) 网关,您可以通过专用 IP 地址路由 App Engine 流量。

通过 Cloud NAT 路由流量不会导致网络栈中出现额外的跃点,因为 Cloud NAT 网关和 Cloud Router 路由器仅会提供控制平面,并且数据包不会通过 Cloud NAT 网关或 Cloud Router 路由器。

无法为使用 URL Fetch 服务发送的流量配置静态出站 IP 地址。使用 URL Fetch 服务发送的流量将继续使用公共 IP 地址池。如果您希望所有出站流量都使用静态 IP 地址,请通过使用套接字停用 URL Fetch 默认值,并停止对 urlfetch 软件包的任何显式使用。

以下步骤显示了如何为 App Engine 标准环境服务设置静态出站 IP 地址。

  1. 确保您拥有 roles/compute.networkAdmin 角色或具有相同权限的自定义角色。

  2. 在 VPC 网络内为 App Engine 流量创建一个子网。这可确保您的 VPC 网络中的其他资源无法使用静态 IP 地址。

    gcloud compute networks subnets create SUBNET_NAME \
        --range=RANGE \
        --network=NETWORK_NAME \
        --region=REGION

    在上述命令中,进行如下替换:

    • SUBNET_NAME 替换为您要为子网指定的名称。
    • RANGE 替换为您要分配给此子网的 CIDR 格式的 IP 范围(例如 10.124.0.0/28
    • NETWORK_NAME 替换为 VPC 网络的名称。
    • REGION 替换为您的 App Engine 服务的区域。
  3. 将 App Engine 服务连接到子网。

    按照连接到 VPC 网络指南操作,并指定您在上一步针对连接器子网创建的子网的名称。

  4. 创建新的 Cloud Router 路由器。Cloud Router 是 Cloud NAT 必需的控制平面组件。

    gcloud compute routers create ROUTER_NAME \
        --network=NETWORK_NAME \
        --region=REGION

    在上述命令中,进行如下替换:

    • ROUTER_NAME 替换为您要创建的 Cloud Router 资源的名称。
    • NETWORK_NAME 替换为 VPC 网络的名称。
    • REGION 替换为要在其中创建 NAT 网关的区域。
  5. 保留静态 IP 地址。

    这是您的服务将用于发送传出流量的地址。当与之关联的资源被删除并重新创建时,保留的 IP 地址资源将保留基础 IP 地址。此 IP 地址会计入 Google Cloud 项目中的静态 IP 地址配额。

    gcloud compute addresses create ORIGIN_IP_NAME \
        --region=REGION

    在上述命令中,进行如下替换:

    • ORIGIN_IP_NAME 替换为您要分配给 IP 地址资源的名称。
    • REGION 替换为将运行 Cloud NAT 路由器的区域。理想情况下,与 App Engine 服务位于同一区域,可最大程度地减少延迟和网络费用。

    使用 compute addresses describe 命令可以查看结果:

    gcloud compute addresses describe ORIGIN_IP_NAME
  6. 创建 Cloud NAT 网关并指定您的 IP 地址。

    来自您的子网的流量将经过此网关,并使用您在上一步预留的静态 IP 地址。

    gcloud compute routers nats create NAT_NAME \
        --router=ROUTER_NAME \
        --region=REGION \
        --nat-custom-subnet-ip-ranges=SUBNET_NAME \
        --nat-external-ip-pool=ORIGIN_IP_NAME
      

    在上述命令中,进行如下替换:

    • NAT_NAME 替换为您要创建的 Cloud NAT 网关资源的名称。
    • ROUTER_NAME 替换为您的 Cloud Router 的名称
    • REGION 替换为要在其中创建 NAT 网关的区域。
    • ORIGIN_IP_NAME 替换为您在上一步中创建的预留 IP 地址资源的名称。
  7. 将无服务器 VPC 访问通道出站流量设置设为 all-traffic

    默认情况下,使用无服务器 VPC 访问通道的 App Engine 服务仅将内部流量发送到您的 VPC 网络。如需将具有外部目标的流量发送到 VPC 网络,使其具有您指定的静态 IP 地址,您必须更改出站流量设置。

    在服务的 app.yaml 文件中指定出站流量设置:

    vpc_access_connector:
      name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR_NAME
      egress_setting: all-traffic

    您需要将其中的:

    • PROJECT_ID 替换为 Google Cloud 项目 ID。
    • REGION 替换为连接器所在的区域。
    • CONNECTOR_NAME 替换为连接器的名称。

    部署该服务:

     gcloud app deploy