设置无服务器 NEG

网络端点组 (NEG) 为负载平衡器指定了一组后端端点。无服务器 NEG 是指向 Cloud RunApp EngineCloud Functions 服务的后端。

无服务器 NEG 可以表示以下内容:

  • 一项 Cloud Run 服务或一组共用相同网址格式的服务。
  • 一个 Cloud Functions 函数或一组共用相同网址格式的函数。
  • 一个 App Engine 应用(标准或 Flex 应用)、应用内的一项特定服务,甚至是应用的某一特定版本。

本页面介绍了如何创建外部 HTTP(S) 负载平衡器,以将请求路由到无服务器后端。在此处,“无服务器”这一术语指的是以下无服务器计算产品:App Engine、Cloud Functions 和 Cloud Run(全代管式)。

借助无服务器 NEG,您可以将 Google Cloud 无服务器应用与外部 HTTP(S) 负载平衡搭配使用。配置具有无服务器 NEG 后端的负载平衡器后,对负载平衡器发出的请求会被路由到无服务器应用后端。

准备工作

准备工作:

  1. 阅读无服务器 NEG 概览
  2. 部署 App Engine、Cloud Functions 或 Cloud Run(全代管式)服务
  3. 安装 Google Cloud SDK
  4. 配置权限
  5. 添加 SSL 证书资源

部署 App Engine、Cloud Functions 或 Cloud Run(全代管式)服务

本页面中的说明假定您已运行 Cloud Run(全代管式)、Cloud Functions 或 App Engine 服务。

对于本页面中的示例,我们按照 Cloud Run(全代管式)Python 快速入门中的说明在 us-central1 地区中部署 helloworld 服务。本页面的其余部分介绍了如何设置外部 HTTP(S) 负载平衡器,以使其使用无服务器 NEG 后端将请求路由到 helloworld 服务。

如果您尚未部署无服务器应用,或者如果您想试用示例无服务器 NEG 应用,请按照以下快速入门之一进行操作。您可以在任何地区中创建无服务器应用,但稍后必须使用相同地区创建无服务器 NEG 和负载平衡器。

Cloud Run(全代管式)

如需创建简单的 Hello World 应用,将其打包到一个容器映像中,然后将该容器映像部署到 Cloud Run(全代管式),请参阅快速入门:构建和部署

如果您已将示例容器上传到 Container Registry,请参阅快速入门:部署预建的示例容器

Cloud Functions

请参阅 Cloud Functions:Python 快速入门

App Engine

请参阅以下 App Engine Python 3 快速入门指南:

安装 Google Cloud SDK

安装 gcloud 命令行工具。如需了解该工具的概念信息和安装信息,请参阅 gcloud 概览

如果您之前未运行过 gcloud 命令行工具,请先运行 gcloud init,以初始化您的 gcloud 目录。

您必须执行此操作,否则无法使用 Google Cloud Console 创建无服务器 NEG。

配置权限

若要按照本指南中的说明进行操作,您需要创建无服务器 NEG 并在项目中创建外部 HTTP(S) 负载平衡器。您应该是项目的 Owner 或 Editor,或者应具有下列 Compute Engine IAM 角色

任务 所需的角色
创建负载平衡器和网络组件 Network Admin
创建和修改 NEG Compute Instance Admin
创建和修改 SSL 证书 Security Admin

创建 SSL 证书资源

如果要创建 HTTPS 负载平衡器,您必须向该负载平衡器的前端添加 SSL 证书资源。您可以使用自行管理的 SSL 证书Google 管理的 SSL 证书创建 SSL 证书资源。 建议使用 Google 管理的证书,因为 Google Cloud 会自动获取、管理和续订这些证书。

此示例假定您已创建 SSL 证书资源。

预留外部 IP 地址

现在您的服务已启动并正在运行,接下来请设置一个全局静态外部 IP 地址,以供客户用来访问您的负载平衡器。

控制台

  1. 转到 Google Cloud Console 中的“外部 IP 地址”页面。
    转到“外部 IP 地址”页面
  2. 点击预留静态地址以预留 IPv4 地址。
  3. 指定名称 example-ip
  4. 将网络层级设置为优质
  5. IP 版本设置为 IPv4
  6. 类型设置为全局
  7. 点击预留

gcloud

gcloud compute addresses create example-ip \
    --ip-version=IPV4 \
    --global

请记下预留的 IPv4 地址:

gcloud compute addresses describe example-ip \
    --format="get(address)" \
    --global

创建外部 HTTP(S) 负载平衡器

在下图中,负载平衡器使用无服务器 NEG 后端将请求定向到无服务器 Cloud Run(全代管式)服务。对于此示例,我们按照 Cloud Run(全代管式)Python 快速入门中的说明来部署 helloworld-python 服务。

简单的 HTTPS 负载平衡(点击可放大)
适用于 Cloud Run 应用的 HTTPS 负载平衡

由于使用无服务器 NEG 后端的后端服务不支持运行状况检查,因此如果负载平衡器只有无服务器 NEG 后端,则您无需创建允许运行状况检查的防火墙规则。

gcloud

  1. 为 Cloud Run(全代管式)服务创建无服务器 NEG。 对于此示例,我们假定您已部署一项名为 helloworld 的 Cloud Run(全代管式)服务。
    gcloud beta compute network-endpoint-groups create helloworld-serverless-neg \
        --region=us-central1 \
        --network-endpoint-type=serverless  \
        --cloud-run-service=helloworld
    
    如需为 App Engine 服务或 Cloud Functions 函数创建 NEG,请参阅 gcloud beta compute network-endpoint-groups creategcloud 参考指南。
  2. 创建后端服务,并将无服务器 NEG 作为后端添加到后端服务:
    gcloud compute backend-services create helloworld-backend-service \
        --global
    
    gcloud beta compute backend-services add-backend helloworld-backend-service \
        --global \
        --network-endpoint-group=helloworld-serverless-neg \
        --network-endpoint-group-region=us-central1
    
  3. 创建网址映射以将传入请求路由到 helloworld-backend-service 后端服务:
    gcloud compute url-maps create helloworld-url-map \
        --default-service helloworld-backend-service
    
    此示例网址映射仅定位到一项代表单个 Cloud Run(全代管式)服务的后端服务,因此我们不需要设置主机规则或路径匹配器。如果您有多项后端服务,则可以使用主机规则根据主机名将请求定向到不同的服务,还可以设置路径匹配器以根据请求路径将请求定向到不同的服务。
  4. 如果要创建 HTTPS 负载平衡器,您必须拥有可在 HTTPS 代理中使用的 SSL 证书资源。您可以使用自行管理的 SSL 证书或 Google 管理的 SSL 证书创建 SSL 证书资源。建议使用 Google 管理的证书,因为 Google Cloud 会自动获取、管理和续订这些证书。 如需创建 Google 管理的证书,您必须拥有一个网域。 如果您没有网域,则可以使用自签名 SSL 证书进行测试。 如需创建自行管理的 SSL 证书资源 www-ssl-cert,请使用以下命令:
    gcloud compute ssl-certificates create www-ssl-cert \
        --certificate [CRT_FILE_PATH] \
        --private-key [KEY_FILE_PATH]
    
    如需创建 Google 管理的 SSL 证书资源 www-ssl-cert,请使用以下命令:
    gcloud compute ssl-certificates create www-ssl-cert \
        --domains [DOMAIN]
    
  5. 创建一个目标 HTTPS 代理以将请求路由到您的网址映射。 该代理属于负载平衡器,用于保存 HTTPS 负载平衡所需的 SSL 证书,因此您还需要在此步骤中加载您的证书。
    gcloud compute target-https-proxies create helloworld-https-proxy \
        --ssl-certificates=www-ssl-cert \
        --url-map=helloworld-url-map
    
  6. 创建全局转发规则以将传入请求路由到该代理。
    gcloud compute forwarding-rules create https-content-rule \
        --address=example-ip \
        --target-https-proxy=helloworld-https-proxy \
        --global \
        --ports=443
    

测试外部 HTTP(S) 负载平衡器

现在您已经配置了负载平衡器,接下来可以开始向负载平衡器的 IP 地址发送流量了。

控制台

  1. 转到 Google Cloud Console 中的“负载平衡”页面。
    转到“负载平衡”页面
  2. 您可以使用网络浏览器测试负载平衡器,方法是转到 https://IP_ADDRESS,其中 IP_ADDRESS负载平衡器的 IP 地址。系统会将您定向到 helloworld 服务首页。

gcloud/使用 curl

使用 curl 命令测试网址的响应。将 IP_ADDRESS 替换为负载平衡器的 IPv4 地址。系统会将您定向到 helloworld 服务首页。

curl https://IP_ADDRESS

其他配置选项

本部分对配置示例进行了扩展,以提供一些额外的替代配置选项。所有任务均为可选任务。您可以按任意顺序执行这些任务。

设置多地区负载平衡

在上述示例中,我们只使用一项 Cloud Run(全代管式)服务作为后端。由于无服务器 NEG 一次只能指向一个端点,因此实际上并未执行负载平衡。外部 HTTP(S) 负载平衡器仅用作前端,并将流量代理到指定的 helloworld 应用端点。但是,您可能需要从多个地区提供您的 Cloud Run(全代管式)应用,以提高服务的可用性并缩短用户的延迟时间。

如果后端服务包含多个 NEG,则负载平衡器会通过将请求转发到最近的可用地区中的无服务器 NEG 来平衡流量。 但是,后端服务在每个地区只能包含一个无服务器 NEG。如需使 Cloud Run(全代管式)服务可在多个地区使用,您需要设置跨地区路由。您应该能够使用一个全球通用的网址方案来从距离用户最近的地区处理用户请求。如果最近的地区不可用或容量不足,则请求将被路由到其他地区。

如需设置多地区传送,您需要使用优质网络层级,以确保所有地区 Cloud Run(全代管式)部署都兼容并可处理来自任何地区的流量。

如需设置多地区负载平衡器,请执行以下操作:

  1. 在不同地区中设置两项 Cloud Run(全代管式)服务。假设您已经部署了两项 Cloud Run(全代管式)服务:一项服务部署到欧洲的一个地区,另一项服务部署到美国的一个地区。
  2. 使用以下设置创建外部 HTTP(S) 负载平衡器:
    1. 设置具有两个无服务器 NEG 的全球后端服务。
      1. 在被部署到欧洲的 Cloud Run 服务所在的地区中创建第一个 NEG。
      2. 在被部署到美国的 Cloud Run 服务所在的地区中创建第二个 NEG。
    2. 在您的前端配置中设置优质网络层级。

其余设置可与前文所述相同。您会得到类似如下所示的设置:

将流量分配到无服务器应用(点击可放大)
无服务器应用的多地区路由(具有故障转移)

设置地区路由

从多个地区提供应用的一个常见原因是满足数据位置要求。例如,您可能需要确保欧洲用户发出的请求始终从位于欧洲的某一地区传送。如需进行此项设置,您需要一个分别包含欧盟用户网址和非欧盟用户网址的网址架构,并将您的欧盟用户定向到欧盟网址。

在这种情况下,您可以使用网址映射将请求从特定网址路由到其相应地区。通过这种设置,针对一个地区的请求绝不会传送到其他地区。这样可以在各地区之间实现隔离。另一方面,如果一个地区发生故障,请求并不会被路由到其他地区。因此,此设置并不会增加服务的可用性。

如需设置地区路由,您需要使用优质网络层级,以便将不同的地区合并到一条转发规则中。

如需设置使用地区路由的负载平衡器,请执行以下操作:

  1. 在不同地区中设置两项 Cloud Run(全代管式)服务。假设您已经部署了以下两项 Cloud Run(全代管式)服务:一项 hello-world-eu 服务部署到欧洲的一个地区,另一项 hello-world-us 服务部署到美国的一个地区。
  2. 使用以下设置创建外部 HTTP(S) 负载平衡器:
    1. 在欧洲地区设置一项使用无服务器 NEG 的后端服务。必须在部署到欧洲的 Cloud Run(全代管式)服务所在的同一地区中创建无服务器 NEG。
    2. 在美国设置第二项使用其他无服务器 NEG 的后端服务,此无服务器 NEG 必须在部署到美国的 Cloud Run 服务所在的同一地区中创建。
    3. 使用适当的主机和路径规则设置网址映射,以使一组网址路由到位于欧洲的后端服务,而所有请求都路由到位于美国的后端服务。
    4. 在您的前端配置中设置优质网络层级。

其余设置可与前文所述相同。您会得到类似如下所示的设置:

将流量分配到无服务器应用(点击可放大)
无服务器应用的地区路由(无故障转移)

使用网址掩码

创建无服务器 NEG 时,您可以使用网址掩码来指向同一网域处提供的多项服务,而不必选择特定的 Cloud Run(全代管式)服务。网址掩码是网址架构的模板。无服务器 NEG 将使用此模板从传入请求的网址中提取服务名称,并将请求映射到相应服务。

如果您的服务映射到自定义网域,而不是 Google Cloud 为已部署的服务提供的默认地址,则网址掩码特别有用。借助网址掩码,即使应用使用自定义网址格式,您也可以通过一条规则定位多项服务和版本。

如果您尚未阅读无服务器 NEGS 概览:网址掩码,请务必阅读此项内容。

构建网址掩码

如需为负载平衡器构建网址掩码,请从您的服务网址入手。对于本示例,我们将使用在 https://example.com/login 处运行的示例无服务器应用。这是将提供该应用的 login 服务的网址。

  1. 从该网址中移除 httphttps。仍保留 example.com/login
  2. 将服务名称替换为网址掩码的占位符。
    1. Cloud Run(全代管式):将 Cloud Run(全代管式)服务名称替换为占位符 <service>。如果 Cloud Run(全代管式)服务具有与之关联的标记,请将标记名称替换为占位符 <tag>。 在此示例中,保留的网址掩码是 example.com/<service>
    2. Cloud Functions:将函数名称替换为占位符 <function>。 在此示例中,保留的网址掩码是 <function>.example.com
    3. App Engine:将服务名称替换为占位符 <service>。 如果服务具有与之关联的版本,请将该版本替换为占位符 <version>。 在此示例中,保留的网址掩码是 example.com/<service>
  3. (可选)如果可以从网址的路径部分提取服务名称(或者函数、版本或标记),则可以省略网域。网址掩码的路径部分通过第一个 / 字符区分。如果网址掩码中没有 /,则掩码将被理解为仅代表主机。因此,对于此示例,网址掩码可以缩减至 /<service>/<function>

    同样,如果可以从网址的主机部分提取服务名称,则可以从网址掩码中完全省略路径。

    您还可以省略位于第一个占位符之前的任何主机或子网域组成部分以及位于最后一个占位符之后的任何路径组成部分。在这种情况下,占位符会捕获相应组成部分所需的信息。

以下几个示例演示了这些规则:

Cloud Run

下表假定您有一个名为 example.com 的自定义网域,并且您的所有 Cloud Run(全代管式)服务都映射到此网域

服务名称,标记名称 Cloud Run(全代管式)自定义网域网址 网址掩码
service:login https://login-home.example.com/web <service>-home.example.com
service:login https://example.com/login/web example.com/<service> 或 /<service>
service:login,tag:test https://test.login.example.com/web <tag>.<service>.example.com
service:login,tag:test https://example.com/home/login/test example.com/home/<service>/<tag> 或 /home/<service>/<tag>
service:login,tag:test https://test.example.com/home/login/web <tag>.example.com/home/<service>

Cloud Functions

下表假定您有一个名为 example.com 的自定义网域,并且您的所有 Cloud Functions 服务都映射到此网域。

函数名称 Cloud Functions 自定义网域网址 网址掩码
login https://example.com/login /<function>
login https://example.com/home/login /home/<function>
login https://login.example.com <function>.example.com
login https://login.home.example.com <function>.home.example.com

App Engine

下表假定您有一个名为 example.com 的自定义网域,并且您的所有 App Engine 服务都映射到此网域

服务名称,版本 App Engine 自定义网域网址 网址掩码
service:login https://login.example.com/web <service>.example.com
service:login https://example.com/home/login/web example.com/home/<service> 或 /home/<service>
service:login,version:test https://test.example.com/login/web <version>.example.com/<service>
service:login,version:test https://example.com/login/test example.com/<service>/<version>

使用网址掩码创建无服务器 NEG

gcloud:Cloud Run

如需使用示例网址掩码 example.com/<service> 创建无服务器 NEG,请使用以下命令:

gcloud beta compute network-endpoint-groups create helloworld-serverless-neg \
    --region=us-central1 \
    --network-endpoint-type=serverless \
    --cloud-run-url-mask=example.com/<service>

gcloud:Cloud Functions

如需使用示例网址掩码 example.com/<function> 创建无服务器 NEG,请使用以下命令:

gcloud beta compute network-endpoint-groups create helloworld-serverless-neg \
    --region=us-central1 \
    --network-endpoint-type=serverless \
    --cloud-function-url-mask=example.com/<function>

gcloud:App Engine

如需使用示例网址掩码 example.com/<service> 创建无服务器 NEG,请使用以下命令:

gcloud beta compute network-endpoint-groups create helloworld-serverless-neg \
    --region=us-central1 \
    --network-endpoint-type=serverless \
    --app-engine-url-mask=example.com/<service>

如需了解负载平衡器如何处理网址掩码不匹配的问题,请参阅排查无服务器 NEG 的问题

迁移自定义网域以便由外部 HTTP(S) 负载平衡器处理

如果将无服务器计算应用映射到自定义网域,您可能需要更新 DNS 记录,以便通过负载平衡器路由发送到现有 Cloud Run(全代管式)、Cloud Functions 或 App Engine 自定义网域网址的流量。

例如,如果您有一个名为 example.com 的自定义网域,并且所有 Cloud Run 服务都映射到此网域,则应更新 example.com 的 DNS 记录以使其指向负载平衡器的 IP 地址。

在更新 DNS 记录之前,您可以在本地测试您的配置,方法是将自定义网域的本地 DNS 解析强制设置为负载平衡器的 IP 地址。如需在本地进行测试,请修改本地机器上的 /etc/hosts/ 文件以将 example.com 指向负载平衡器的 IP 地址,或者使用 curl --resolve 标志强制 curl 对该请求使用负载平衡器的 IP 地址。

example.com 的 DNS 记录解析为 HTTP(S) 负载平衡器的 IP 地址时,发送到 example.com 的请求将开始通过负载平衡器进行路由。负载平衡器会根据其网址映射将请求分配到相关后端服务。此外,如果后端服务配置了网址掩码,则无服务器 NEG 会使用该掩码将请求路由到相应的 Cloud Run(全代管式)、Cloud Functions 或 App Engine 服务。

启用 Cloud CDN

通过为 Cloud Run(全代管式)服务启用 Cloud CDN,您可以将内容缓存到您的用户附近,从而优化内容传送。

您可以使用 gcloud compute backend-services update 命令在外部 HTTP(S) 负载平衡器的后端服务上启用 Cloud CDN。

  gcloud compute backend-services update helloworld-backend-service \
    --enable-cdn \
    --global

使用 Cloud Run(全代管式)、Cloud Functions 和 App Engine 后端的后端服务支持 Cloud CDN。

启用 Google Cloud Armor

Google Cloud Armor 是一款安全产品,可为所有 GCLB 代理负载平衡器提供针对分布式拒绝服务 (DDoS) 攻击的保护。Google Cloud Armor 还为通过外部 HTTP(S) 负载平衡器访问的服务提供可配置的安全政策。如需了解有关 HTTP(S) 负载平衡的 Google Cloud Armor 安全政策,请参阅 Google Cloud Armor 安全政策概览

虽然可以为使用 Cloud Run(全代管式)、Cloud Functions 和 App Engine 后端的后端服务配置 Google Cloud Armor,但是此功能存在一些限制,尤其是对于 Cloud Run(全代管式)和 App Engine。 如果用户有权访问 Google Cloud 分配给这些服务的默认网址,则可以绕过负载平衡器并直接转到服务网址,从而规避所有已配置的 Google Cloud Armor 安全政策。

如果您使用的是 Cloud Functions,则可以通过使用 internal-and-gclb Ingress 设置来舒解这种情况,以确保阻止发送到默认 cloudfunctions.net 网址或通过 Cloud Functions 设置的任何其他自定义网域的请求。

删除无服务器 NEG

如果网络端点组已连接到后端服务,则您无法将其删除。在删除某个 NEG 之前,请确保该 NEG 已与后端服务分离。

如需从后端服务中移除无服务器 NEG,您必须指定在其中创建该 NEG 的地区。此外,您还必须指定 --global 标志,因为 helloworld-backend-service 是全球资源。

gcloud beta compute backend-services remove-backend helloworld-backend-service \
    --network-endpoint-group=helloworld-serverless-neg \
    --network-endpoint-group-region=us-central1 \
    --global

如需删除无服务器 NEG,请使用以下命令:

gcloud beta compute network-endpoint-groups delete helloworld-serverless-neg \
    --region=us-central1

后续步骤