使用 Cloud Run 设置跨区域内部应用负载均衡器

本文档介绍如何使用 Cloud Run 部署跨区域内部应用负载均衡器。如需进行此设置,请为负载均衡器使用无服务器 NEG 后端。

借助无服务器 NEG,您可以将 Cloud Run 服务与负载均衡器搭配使用。使用无服务器 NEG 后端配置负载均衡器后,对负载均衡器发出的请求会路由到 Cloud Run 后端。

跨区域负载均衡可实现冗余性,以便在流量无法到达某个区域时自动转移至其他区域。根据 Envoy 的位置,代理流量会按如下所示分配给 Cloud Run 服务:

  • 如果多区域 Cloud Run 服务在 Envoy 所在的区域中配置,则首选与 Envoy 位于同一区域的 NEG。仅当启用了离群值检测并且本地 NEG 健康状况不佳时,流量才会发送到故障切换区域。
  • 如果多区域 Cloud Run 服务未在 Envoy 所在的区域中配置,则流量会在所有 NEG 中均匀分配。不首选位置更近的 NEG。
  • 如果启用了 Identity-Aware Proxy,则仅支持单个无服务器 NEG。但是,您可以配置其他 Cloud Run 服务,但负载均衡器不会向其发送任何流量。

准备工作

在按照本指南进行操作之前,请先熟悉以下内容:

部署 Cloud Run 服务

本页面中的说明假定您已运行 Cloud Run 服务。

对于本页面中的示例,您可以使用任何 Cloud Run 快速入门部署 Cloud Run 服务。

如需阻止从互联网访问 Cloud Run 服务,请将入站流量限制为 internal。来自内部应用负载均衡器的流量被视为内部流量。

将 Cloud Run 服务放在多个区域中有助于防止单个区域发生故障。如需在 REGION_AREGION_B 区域中部署 Cloud Run 服务,请运行以下命令:

gcloud

gcloud run deploy CLOUD_RUN_SERVICE_NAMEA \
   --platform=managed \
   --allow-unauthenticated \
   --ingress=internal \
   --region=REGION_A \
   --image=IMAGE_URLA
gcloud run deploy CLOUD_RUN_SERVICE_NAMEB \
   --platform=managed \
   --allow-unauthenticated \
   --ingress=internal \
   --region=REGION_B \
   --image=IMAGE_URLB

记下您创建的服务的名称。本页面的其余部分介绍了如何设置负载均衡器,以将请求路由到此服务。

设置 SSL 证书资源

按如下所示创建 Certificate Manager SSL 证书资源:

我们建议您使用 Google 管理的证书。

权限

若要按照本指南中的说明进行操作,您必须能够创建实例以及修改项目中的网络。因此,您必须是项目 Owner 或 Editor,或者必须具有以下所有 Compute Engine IAM 角色

任务 所需角色
创建网络、子网和负载均衡器组件 Compute Network Admin
添加和移除防火墙规则 计算安全管理员
创建实例 Compute Instance Admin

如需了解详情,请参阅以下指南:

设置概览

您可以配置跨区域内部应用负载均衡器,如下图所示:

使用 Cloud Run 部署的跨区域内部应用负载均衡器。
使用 Cloud Run 部署的跨区域内部应用负载均衡器(点击可放大)。

如上图所示,此示例在 VPC 网络中创建了一个跨区域内部应用负载均衡器,其中包含一个后端服务以及 REGION_AREGION_B区域。

跨区域内部应用负载均衡器设置的说明如下:

  1. 一个具有以下子网的 VPC 网络:

    • 子网 SUBNET_AREGION_A 中的代理专用子网。
    • 子网 SUBNET_BREGION_B 中的代理专用子网。

    您必须在其中使用跨区域内部应用负载均衡器的 VPC 网络的每个区域中创建代理专用子网。该区域的代理专用子网会在该区域的所有跨区域内部应用负载均衡器之间共享。对于从负载均衡器发送到服务后端的数据包,系统会从代理专用子网分配其来源地址。在此示例中,区域 REGION_A 的代理专用子网的主要 IP 地址范围为 10.129.0.0/23REGION_B 的主要 IP 地址范围为 10.130.0.0/23,这是建议的子网大小。

  2. 允许在您的网络中使用代理专用子网流量的防火墙规则。这意味着添加一个允许来自 10.129.0.0/2310.130.0.0/23(此示例中的代理专用子网范围)的 TCP 端口 804438080 流量的规则。

  3. 另一个用于健康检查探测的防火墙规则。

  4. 具有适用于 REGION_AREGION_B 区域中 Cloud Run 部署的无服务器后端的高可用性设置。如果一个区域中的后端发生故障,则流量会故障切换到另一个区域。

  5. 用于监控后端使用情况和健康状况全球后端服务。 请确保在后端服务上启用离群值检测

  6. 全球网址映射,用于解析请求的网址,并根据请求网址的主机和路径将请求转发到特定后端服务。

  7. 全球目标 HTTP 或 HTTPS 代理,用于接收用户请求并将其转发到网址映射。对于 HTTPS,请配置区域 SSL 证书资源。如果您配置 HTTPS 负载均衡,则目标代理会使用 SSL 证书来解密 SSL 流量。目标代理可以通过 HTTP 或 HTTPS 将流量转发到您的实例。

  8. 包含负载均衡器内部 IP 地址的全局转发规则,用于将每个传入请求转发到目标代理。

    与转发规则关联的内部 IP 地址可以来自同一网络和区域中的任何子网。请注意以下条件:

    • 该 IP 地址可以(但并非必须)与后端实例组来自同一子网。
    • 该 IP 地址不得来自 --purpose 标志设置为 GLOBAL_MANAGED_PROXY 的预留代理专用子网。
    • 如果要将同一内部 IP 地址与多个转发规则结合使用,请将 IP 地址 --purpose 标志设置为 SHARED_LOADBALANCER_VIP
  9. 可选:配置 DNS 路由政策(类型为 GEO),以将客户端流量路由到离客户端最近的区域中的负载均衡器 VIP。

配置网络和子网

在 VPC 网络中,在配置了后端的每个区域中配置一个子网。此外,请在要配置负载均衡器的每个区域中配置 proxy-only-subnet

本示例使用以下 VPC 网络、区域和子网:

  • 网络。网络是名为 NETWORK自定义模式 VPC 网络

  • 后端子网REGION_A 区域中名为 SUBNET_A 的子网使用 10.1.2.0/24 作为其主要 IP 范围。REGION_B 区域中名为 SUBNET_A 的子网使用 10.1.3.0/24 作为其主要 IP 范围。

  • 代理子网REGION_A 区域中名为 PROXY_SN_A 的子网使用 10.129.0.0/23 作为其主要 IP 范围。REGION_B 区域中名为 PROXY_SN_B 的子网使用 10.130.0.0/23 作为其主要 IP 范围。

您可以从 VPC 中的任何区域访问跨区域内部应用负载均衡器。因此,来自任何区域的客户端都可以在全球范围内访问负载均衡器后端。

配置后端子网

控制台

  1. 在 Google Cloud 控制台中,进入 VPC 网络页面。

    进入 VPC 网络页面

  2. 点击创建 VPC 网络

  3. 为网络提供名称

  4. 子网部分中,将子网创建模式设置为自定义

  5. 为负载均衡器的后端创建子网。在新子网部分中,输入以下信息:

    • 为子网提供名称
    • 选择区域REGION_A
    • 输入 IP 地址范围10.1.2.0/24
  6. 点击完成

  7. 点击添加子网

  8. 为负载均衡器的后端创建子网。在新子网部分中,输入以下信息:

    • 为子网提供名称
    • 选择区域REGION_B
    • 输入 IP 地址范围10.1.3.0/24
  9. 点击完成

  10. 点击创建

gcloud

  1. 使用 gcloud compute networks create 命令创建自定义 VPC 网络:

    gcloud compute networks create NETWORK --subnet-mode=custom
    
  2. 使用 gcloud compute networks subnets create 命令REGION_A 区域的 NETWORK 网络中创建子网:

    gcloud compute networks subnets create SUBNET_A \
        --network=NETWORK \
        --range=10.1.2.0/24 \
        --region=REGION_A
    
  3. 使用 gcloud compute networks subnets create 命令REGION_B 区域的 NETWORK 网络中创建子网:

    gcloud compute networks subnets create SUBNET_B \
        --network=NETWORK \
        --range=10.1.3.0/24 \
        --region=REGION_B
    

API

networks.insert 方法发出 POST 请求。请将 PROJECT_ID 替换为您的项目 ID。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks

{
 "routingConfig": {
   "routingMode": "regional"
 },
 "name": "NETWORK",
 "autoCreateSubnetworks": false
}

subnetworks.insert 方法发出 POST 请求。请将 PROJECT_ID 替换为您的项目 ID。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_A/subnetworks

{
 "name": "SUBNET_A",
 "network": "projects/PROJECT_ID/global/networks/NETWORK",
 "ipCidrRange": "10.1.2.0/24",
 "region": "projects/PROJECT_ID/regions/REGION_A",
}

subnetworks.insert 方法发出 POST 请求。请将 PROJECT_ID 替换为您的项目 ID。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_B/subnetworks

{
 "name": "SUBNET_B",
 "network": "projects/PROJECT_ID/global/networks/NETWORK",
 "ipCidrRange": "10.1.3.0/24",
 "region": "projects/PROJECT_ID/regions/REGION_B",
}

配置代理专用子网

代理专用子网提供了一组 IP 地址,供 Google Cloud 用于代表您运行 Envoy 代理。 代理会终结来自客户端的连接并创建与后端的连接。

此代理专用子网用于与 VPC 网络位于同一区域的所有基于 Envoy 的区域级负载均衡器。在每个网络中,每个区域只能有一个活跃代理专用子网用于给定目的。

控制台

如果您使用的是 Google Cloud 控制台,则可以稍后在负载均衡页面上创建代理专用子网。

如需立即创建代理专用子网,请按以下步骤操作:

  1. 在 Google Cloud 控制台中,转到 VPC 网络页面。

    转到 VPC 网络页面

  2. 点击 VPC 网络的名称。
  3. 子网标签页上,点击添加子网
  4. 为代理专用子网提供名称
  5. 区域列表中,选择 REGION_A
  6. 用途列表中,选择跨区域托管式代理
  7. IP 地址范围字段中,输入 10.129.0.0/23
  8. 点击添加

REGION_B 中创建代理专用子网

  1. 点击添加子网
  2. 为代理专用子网提供名称
  3. 区域列表中,选择 REGION_B
  4. 用途列表中,选择跨区域托管式代理
  5. IP 地址范围字段中,输入 10.130.0.0/23
  6. 点击添加

gcloud

使用 gcloud compute networks subnets create 命令创建代理专用子网。

    gcloud compute networks subnets create PROXY_SN_A \
        --purpose=GLOBAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=REGION_A \
        --network=NETWORK \
        --range=10.129.0.0/23
    
    gcloud compute networks subnets create PROXY_SN_B \
        --purpose=GLOBAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=REGION_B \
        --network=NETWORK \
        --range=10.130.0.0/23
    

API

使用 subnetworks.insert 方法创建代理专用子网,并将 PROJECT_ID 替换为您的项目 ID。

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_A/subnetworks

    {
      "name": "PROXY_SN_A",
      "ipCidrRange": "10.129.0.0/23",
      "network": "projects/PROJECT_ID/global/networks/NETWORK",
      "region": "projects/PROJECT_ID/regions/REGION_A",
      "purpose": "GLOBAL_MANAGED_PROXY",
      "role": "ACTIVE"
    }
   
    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_B/subnetworks

    {
      "name": "PROXY_SN_B",
      "ipCidrRange": "10.130.0.0/23",
      "network": "projects/PROJECT_ID/global/networks/NETWORK",
      "region": "projects/PROJECT_ID/regions/REGION_B",
      "purpose": "GLOBAL_MANAGED_PROXY",
      "role": "ACTIVE"
    }
   

创建无服务器 NEG

  1. 为 Cloud Run 服务创建无服务器 NEG:

    gcloud compute network-endpoint-groups create gl7ilb-serverless-neg-a \
       --region=REGION_A \
       --network-endpoint-type=serverless  \
       --cloud-run-service=CLOUD_RUN_SERVICE_NAMEA
    
    gcloud compute network-endpoint-groups create gl7ilb-serverless-neg-b \
       --region=REGION_B \
       --network-endpoint-type=serverless  \
       --cloud-run-service=CLOUD_RUN_SERVICE_NAMEB
    

配置负载平衡器

从负载均衡器到无服务器 NEG 后端的流量,使用 VPC 外部定义且不受防火墙规则约束的特殊路由。因此,如果您的负载均衡器只有无服务器 NEG 后端,则无需创建防火墙规则即可允许从代理专用子网到无服务器后端的流量。

控制台

开始配置

  1. 在 Google Cloud 控制台中,转到负载均衡页面。

    转到“负载均衡”

  2. 点击创建负载均衡器
  3. 负载均衡器的类型字段中,选择应用负载均衡器 (HTTP/HTTPS),然后点击下一步
  4. 公共或内部字段中,选择内部,然后点击下一步
  5. 跨区域或单区域部署字段中,选择最适合跨区域工作负载,然后点击下一步
  6. 点击配置

基本配置

  1. 为负载均衡器提供名称
  2. 对于网络,请选择 NETWORK

使用两条转发规则配置前端

对于 HTTP:

  1. 点击前端配置
    1. 为转发规则提供名称
    2. Subnetwork region 列表中,选择 REGION_A

      预留代理专用子网

    3. 子网列表中,选择 SUBNET_A
    4. IP 地址列表中,点击创建 IP 地址。系统会打开预留静态内部 IP 地址页面。
      • 为静态 IP 地址提供名称
      • 静态 IP 地址列表中,选择让我选择
      • 自定义 IP 地址字段中,输入 10.1.2.99
      • 选择预留
  2. 点击完成
  3. 如需添加第二条转发规则,请点击添加前端 IP 和端口
    1. 为转发规则提供名称
    2. Subnetwork region 列表中,选择 REGION_B

      预留代理专用子网

    3. 子网列表中,选择 SUBNET_B
    4. IP 地址列表中,点击创建 IP 地址。系统会打开预留静态内部 IP 地址页面。
      • 为静态 IP 地址提供名称
      • 静态 IP 地址列表中,选择让我选择
      • 自定义 IP 地址字段中,输入 10.1.3.99
      • 选择预留
  4. 点击完成

对于 HTTPS:

如果您在客户端和负载均衡器之间使用 HTTPS,则需要一个或多个 SSL 证书资源来配置代理。如需创建 Google 管理的 all-regions 证书,请参阅以下文档:

创建 Google 管理的证书后,请将该证书直接附加到目标代理。跨区域内部应用负载均衡器不支持证书映射。

如需创建自行管理的 all-regions 证书,请参阅以下文档:部署自行管理的区域级证书

  1. 点击前端配置
    1. 为转发规则提供名称
    2. 协议字段中,选择 HTTPS (includes HTTP/2)
    3. 确保将端口设置为 443
    4. Subnetwork region 列表中,选择 REGION_A

      预留代理专用子网

    5. 子网列表中,选择 SUBNET_A
    6. IP 地址列表中,点击创建 IP 地址。系统会打开预留静态内部 IP 地址页面。
      • 为静态 IP 地址提供名称
      • 静态 IP 地址列表中,选择让我选择
      • 自定义 IP 地址字段中,输入 10.1.3.99
      • 选择预留
    7. 添加证书部分中,选择证书。
    8. 可选:如需添加除了主要 SSL 证书之外的其他证书,请执行以下操作:
      1. 点击添加证书
      2. 从列表中选择证书。
    9. SSL 政策列表中选择一项 SSL 政策。如果您尚未创建任何 SSL 政策,则系统会应用默认 Google Cloud SSL 政策
    10. 点击完成

    添加第二个前端配置:

    1. 为前端配置提供名称
    2. 协议字段中,选择 HTTPS (includes HTTP/2)
    3. 确保将端口设置为 443
    4. Subnetwork region 列表中,选择 REGION_B

      预留代理专用子网

    5. 子网列表中,选择 SUBNET_B
    6. IP 地址列表中,点击创建 IP 地址。系统会打开预留静态内部 IP 地址页面。
      • 为静态 IP 地址提供名称
      • 静态 IP 地址列表中,选择让我选择
      • 自定义 IP 地址字段中,输入 10.1.3.99
      • 选择预留
    7. 添加证书部分中,选择证书。
    8. 可选:如需添加除了主要 SSL 证书之外的其他证书,请执行以下操作:
      1. 点击添加证书
      2. 从列表中选择证书。
    9. SSL 政策列表中选择一项 SSL 政策。如果您尚未创建任何 SSL 政策,则系统会应用默认 Google Cloud SSL 政策
    10. 点击完成
    配置后端服务
    1. 点击后端配置
    2. 创建或选择后端服务列表中,点击创建后端服务
    3. 为后端服务提供名称
    4. 对于协议,选择 HTTP
    5. 对于已命名端口,输入 http
    6. 后端类型列表中,选择无服务器网络端点组
    7. 新后端部分:
      • 无服务器网络端点组列表中,选择 gl7ilb-serverless-neg-a
      • 点击完成
      • 如需添加其他后端,请点击添加后端
      • 无服务器网络端点组列表中,选择 gl7ilb-serverless-neg-b
      • 点击完成

    配置路由规则

    1. 点击路由规则
    2. 对于模式,选择简单主机和路径规则
    3. 确保任何不匹配的主机和任何不匹配的路径都只有一个后端服务。

    检查配置

    1. 点击检查并最终确定
    2. 查看负载均衡器配置设置。
    3. 点击创建

gcloud

  1. 使用 gcloud compute backend-services create 命令定义后端服务。

    gcloud compute backend-services create gil7-backend-service \
      --load-balancing-scheme=INTERNAL_MANAGED \
      --protocol=HTTP \
      --global
    
  2. 使用 gcloud compute backend-services add-backend 命令将后端添加到后端服务。

    gcloud compute backend-services add-backend gil7-backend-service \
      --network-endpoint-group=gl7ilb-serverless-neg-a \
      --network-endpoint-group-region=REGION_A \
      --global
    
    gcloud compute backend-services add-backend gil7-backend-service \
      --network-endpoint-group=gl7ilb-serverless-neg-b \
      --network-endpoint-group-region=REGION_B \
      --global
    
  3. 使用 gcloud compute url-maps create 命令创建网址映射。

    gcloud compute url-maps create gil7-map \
      --default-service=gil7-backend-service \
      --global
    
  4. 创建目标代理。

    对于 HTTP

    使用 gcloud compute target-http-proxies create 命令创建目标代理。

    gcloud compute target-http-proxies create gil7-http-proxy \
      --url-map=gil7-map \
      --global
    

    对于 HTTPS

    如需创建 Google 管理的证书,请参阅以下文档:

    创建 Google 管理的证书后,请将该证书直接附加到目标代理。跨区域内部应用负载均衡器不支持证书映射。

    如需创建自行管理的证书,请参阅以下文档:

    将文件路径分配给变量名称。

    export LB_CERT=PATH_TO_PEM_FORMATTED_FILE
    
    export LB_PRIVATE_KEY=PATH_TO_LB_PRIVATE_KEY_FILE
    

    使用 gcloud certificate-manager certificates create 命令创建所有区域 SSL 证书。

    gcloud certificate-manager certificates create gilb-certificate \
      --private-key-file=$LB_PRIVATE_KEY \
      --certificate-file=$LB_CERT \
      –-scope=all-regions
    

    使用 SSL 证书通过 gcloud compute target-https-proxies create 命令创建目标代理

    gcloud compute target-https-proxies create gil7-https-proxy \
      --url-map=gil7-map \
      --certificate-manager-certificates=gilb-certificate
    
  5. 创建两条转发规则:一条规则使用 REGION_B 区域中的 VIP (10.1.2.99),另一条规则使用 REGION_A 区域中的 VIP (10.1.3.99)。

    对于自定义网络,必须在转发规则中引用子网。请注意,这是虚拟机 (VM) 实例子网,而非代理子网。

    对于 HTTP

    gcloud compute forwarding-rules create 命令与正确的标志结合使用。

    gcloud compute forwarding-rules create gil7-forwarding-rule-a \
      --load-balancing-scheme=INTERNAL_MANAGED \
      --network=NETWORK \
      --subnet=SUBNET_B \
      --subnet-region=REGION_B \
      --address=10.1.3.99 \
      --ports=80 \
      --target-http-proxy=gil7-http-proxy \
      --global
    
    gcloud compute forwarding-rules create gil7-forwarding-rule-b \
      --load-balancing-scheme=INTERNAL_MANAGED \
      --network=NETWORK \
      --subnet=SUBNET_A \
      --subnet-region=REGION_A \
      --address=10.1.2.99 \
      --ports=80 \
      --target-http-proxy=gil7-http-proxy \
      --global
    

    对于 HTTPS

    gcloud compute forwarding-rules create 命令与正确的标志结合使用来创建转发规则。

    gcloud compute forwarding-rules create gil7-forwarding-rule-a \
      --load-balancing-scheme=INTERNAL_MANAGED \
      --network=NETWORK \
      --subnet=SUBNET_B \
      --address=10.1.3.99 \
      --ports=443 \
      --target-https-proxy=gil7-https-proxy \
      --global
    
    gcloud compute forwarding-rules create gil7-forwarding-rule-b \
      --load-balancing-scheme=INTERNAL_MANAGED \
      --network=NETWORK \
      --subnet=SUBNET_A \
      --address=10.1.2.99 \
      --ports=443 \
      --target-https-proxy=gil7-https-proxy \
      --global
    

API

backendServices.insert 方法发出 POST 请求来创建全球后端服务,并将 PROJECT_ID 替换为您的项目 ID。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices

{
"name": "gil7-backend-service",
"backends": [
  {
    "group": "projects/PROJECT_ID/zones/ZONE_A/instanceGroups/gl7ilb_serverless_negwest",
    "balancingMode": "UTILIZATION"
  },
  {
    "group": "projects/PROJECT_ID/zones/ZONE_B/instanceGroups/gl7ilb_serverless_negeast",
  }
],
"loadBalancingScheme": "INTERNAL_MANAGED"
}

urlMaps.insert 方法发出 POST 请求来创建网址映射,并将 PROJECT_ID 替换为您的项目 ID。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/urlMaps

{
"name": "l7-ilb-map",
"defaultService": "projects/PROJECT_ID/global/backendServices/gil7-backend-service"
}

对于 HTTP

targetHttpProxies.insert 方法发出 POST 请求来创建目标 HTTP 代理,并将 PROJECT_ID 替换为您的项目 ID。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/targetHttpProxy

{
"name": "l7-ilb-proxy",
"urlMap": "projects/PROJECT_ID/global/urlMaps/l7-ilb-map"
}

globalforwardingRules.insert 方法发出 POST 请求来创建转发规则,并将 PROJECT_ID 替换为您的项目 ID。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules

{
"name": "gil7-forwarding-rule-a",
"IPAddress": "10.1.2.99",
"IPProtocol": "TCP",
"portRange": "80-80",
"target": "projects/PROJECT_ID/global/targetHttpProxies/l7-ilb-proxy",
"loadBalancingScheme": "INTERNAL_MANAGED",
"subnetwork": "projects/PROJECT_ID/regions/REGION_A/subnetworks/SUBNET_A",
"network": "projects/PROJECT_ID/global/networks/NETWORK",
"networkTier": "PREMIUM"
}
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules

{
"name": "gil7-forwarding-rule-b",
"IPAddress": "10.1.3.99",
"IPProtocol": "TCP",
"portRange": "80-80",
"target": "projects/PROJECT_ID/global/targetHttpProxies/l7-ilb-proxy",
"loadBalancingScheme": "INTERNAL_MANAGED",
"subnetwork": "projects/PROJECT_ID/regions/REGION_B/subnetworks/SUBNET_B",
"network": "projects/PROJECT_ID/global/networks/NETWORK",
"networkTier": "PREMIUM"
}

对于 HTTPS

读取证书和私钥文件,然后创建 SSL 证书。以下示例展示了如何使用 Python 执行此操作。

targetHttpsProxies.insert 方法发出 POST 请求来创建目标 HTTPS 代理,并将 PROJECT_ID 替换为您的项目 ID。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/targetHttpsProxy

{
"name": "l7-ilb-proxy",
"urlMap": "projects/PROJECT_ID/global/urlMaps/l7-ilb-map",
"sslCertificates": /projects/PROJECT_ID/global/sslCertificates/SSL_CERT_NAME
}

globalForwardingRules.insert 方法发出 POST 请求来创建转发规则,并将 PROJECT_ID 替换为您的项目 ID。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules

{
"name": "gil7-forwarding-rule-a",
"IPAddress": "10.1.2.99",
"IPProtocol": "TCP",
"portRange": "80-80",
"target": "projects/PROJECT_ID/global/targetHttpsProxies/l7-ilb-proxy",
"loadBalancingScheme": "INTERNAL_MANAGED",
"subnetwork": "projects/PROJECT_ID/regions/REGION_A/subnetworks/SUBNET_A",
"network": "projects/PROJECT_ID/global/networks/NETWORK",
"networkTier": "PREMIUM"
}
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules

{
"name": "gil7-forwarding-rule-b",
"IPAddress": "10.1.3.99",
"IPProtocol": "TCP",
"portRange": "80-80",
"target": "projects/PROJECT_ID/global/targetHttpsProxies/l7-ilb-proxy",
"loadBalancingScheme": "INTERNAL_MANAGED",
"subnetwork": "projects/PROJECT_ID/regions/REGION_B/subnetworks/SUBNET_B",
"network": "projects/PROJECT_ID/global/networks/NETWORK",
"networkTier": "PREMIUM"
}

测试负载均衡器

现在负载均衡服务已运行,您可以将流量发送到转发规则并会发现流量被分散到不同的实例。

配置防火墙规则

此示例要求测试客户端虚拟机的 fw-allow-ssh 防火墙规则。fw-allow-ssh 是适用于测试客户端虚拟机的入站流量规则,允许从任何地址到 TCP 端口 22 的传入 SSH 连接。您可以为此规则选择限制性更高的来源 IP 地址范围;例如,您可以仅指定要从中启动 SSH 会话的系统的 IP 地址范围。此示例使用目标标记 allow-ssh

gcloud

  1. 创建 fw-allow-ssh 防火墙规则,允许通过 SSH 连接到网络标记为 allow-ssh 的虚拟机。如果省略 source-ranges,Google Cloud 会将规则解释为表示所有来源

    gcloud compute firewall-rules create fw-allow-ssh \
        --network=NETWORK \
        --action=allow \
        --direction=ingress \
        --target-tags=allow-ssh \
        --rules=tcp:22
    

创建虚拟机实例以测试连接性

  1. 创建客户端虚拟机:

    gcloud compute instances create l7-ilb-client-a \
        --image-family=debian-12 \
        --image-project=debian-cloud \
        --network=NETWORK \
        --subnet=SUBNET_A \
        --zone=ZONE_A \
        --tags=allow-ssh
    
    gcloud compute instances create l7-ilb-client-b \
        --image-family=debian-12 \
        --image-project=debian-cloud \
        --network=NETWORK \
        --subnet=SUBNET_B \
        --zone=ZONE_B \
        --tags=allow-ssh
    
  2. 使用 SSH 连接到每个客户端实例。

    gcloud compute ssh l7-ilb-client-a \
       --zone=ZONE_A
    
    gcloud compute ssh l7-ilb-client-b \
       --zone=ZONE_B
    
  3. 验证 IP 地址是否提供其主机名。

    • 验证客户端虚拟机是否可以访问以下两个 IP 地址。 该命令会成功并返回处理请求的后端虚拟机的名称:

      curl 10.1.2.99
      
      curl 10.1.3.99
      

      对于 HTTPS 测试,请将 curl 替换为:

      curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.2.99:443
      
      curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.3.99:443
      

      -k 标志会导致 curl 跳过证书验证。

    • 可选:使用配置的 DNS 记录来解析 IP 地址。

      curl service.example.com
      

运行 100 个请求并确认它们已进行负载均衡

对于 HTTP

  {
    RESULTS=
    for i in {1..100}
    do
      RESULTS="$RESULTS:$(curl --silent 10.1.2.99)"
    done
    echo ""
    echo " Results of load-balancing to 10.1.2.99: "
    echo "***"
    echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
    echo
  }
  

  {
    RESULTS=
    for i in {1..100}
    do
      RESULTS="$RESULTS:$(curl --silent 10.1.3.99)"
    done
    echo ""
    echo " Results of load-balancing to 10.1.3.99: "
    echo "***"
    echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
    echo
  }
  

对于 HTTPS

  {
    RESULTS=
    for i in {1..100}
    do
      RESULTS="$RESULTS:$(curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.2.99:443)"
    done
    echo ""
    echo " Results of load-balancing to 10.1.2.99: "
    echo "***"
    echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
    echo
  }
  

  {
    RESULTS=
    for i in {1..100}
    do
        RESULTS="$RESULTS:$(curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.3.99:443)"
    done
    echo ""
    echo " Results of load-balancing to 10.1.3.99: "
    echo "***"
    echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
    echo
  }
  

测试故障切换

  1. REGION_B 区域中的后端健康状况不佳或无法访问时,验证故障切换到 REGION_A 区域的后端。我们通过从 REGION_B 中移除所有后端来进行模拟:

    gcloud compute backend-services remove-backend gil7-backend-service \
       --network-endpoint-group=gl7ilb-serverless-neg-b \
       --network-endpoint-group-zone=ZONE_B
    
  2. 使用 SSH 连接到 REGION_B 中的客户端虚拟机。

    gcloud compute ssh l7-ilb-client-b \
       --zone=ZONE_B
    
  3. REGION_B 区域中的负载均衡 IP 地址发送请求。命令输出会显示来自 REGION_A 中的后端虚拟机的响应:

    {
    RESULTS=
    for i in {1..100}
    do
      RESULTS="$RESULTS:$(curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.3.99:443)"
    done
    echo "***"
    echo "*** Results of load-balancing to 10.1.3.99: "
    echo "***"
    echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
    echo
    }
    

其他配置选项

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

使用网址掩码

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

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

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

构建网址掩码

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

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

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

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

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

下表假定您有一个名为 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>

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

控制台

对于新的负载均衡器,您可以使用与本文档前面介绍的相同的端到端流程。配置后端服务时,请不要选择特定服务,而是输入网址掩码。

如果您已有负载均衡器,则可以修改后端配置,并让无服务器 NEG 指向网址掩码而不是特定服务。

如需将基于网址掩码的无服务器 NEG 添加到现有的后端服务,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到负载均衡页面。
    前往“负载均衡”页面
  2. 点击包含您要修改的后端服务的负载均衡器的名称。
  3. 负载均衡器详情页面上,点击 修改
  4. 修改全球外部应用负载均衡器页面上,点击后端配置
  5. 后端配置页面上,点击您要修改的后端服务对应的 修改
  6. 点击添加后端
  7. 选择创建无服务器网络端点组
    1. 名称输入 helloworld-serverless-neg
    2. 区域下会显示负载均衡器所在的区域。
    3. 无服务器网络端点组类型下,Cloud Run 是唯一受支持的网络端点组类型。
      1. 选择使用网址掩码
      2. 输入网址掩码。如需了解如何创建网址掩码,请参阅构建网址掩码
      3. 点击创建

  8. 新建后端中,点击完成
  9. 点击更新

gcloud

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

gcloud compute network-endpoint-groups create SERVERLESS_NEG_MASK_NAME \
    --region=REGION \
    --network-endpoint-type=serverless \
    --cloud-run-url-mask="example.com/<service>"

在多个内部转发规则中使用同一 IP 地址

如果多个内部转发规则共用同一内部 IP 地址,您必须预留该 IP 地址,并将其 --purpose 标志设置为 SHARED_LOADBALANCER_VIP

gcloud

gcloud compute addresses create SHARED_IP_ADDRESS_NAME \
    --region=REGION \
    --subnet=SUBNET_NAME \
    --purpose=SHARED_LOADBALANCER_VIP
如果您需要将 HTTP 流量重定向到 HTTPS,则可以创建两个共用一个 IP 地址的转发规则。如需了解详情,请参阅为内部应用负载均衡器设置 HTTP 到 HTTPS 重定向

配置 DNS 路由政策

如果您的客户端位于多个区域,则建议您在这些区域中使用 VIP 使跨区域内部应用负载均衡器可供访问。这种多区域设置可最大限度地减少延迟和网络传输费用。此外,您还可以设置基于 DNS 的全球负载均衡解决方案,以应对区域级服务中断。如需了解详情,请参阅管理 DNS 路由政策和健康检查

gcloud

如需创建 TTL 为 30 秒 DNS 条目,请使用 gcloud dns record-sets create 命令

gcloud dns record-sets create DNS_ENTRY --ttl="30" \
  --type="A" --zone="service-zone" \
  --routing-policy-type="GEO" \
  --routing-policy-data="REGION_A=gil7-forwarding-rule-a@global;REGION_B=gil7-forwarding-rule-b@global" \
  --enable-health-checking

请替换以下内容:

  • DNS_ENTRY:记录集的 DNS 或域名

    例如 service.example.com

  • REGION_AREGION_B:您在其中配置了负载均衡器的区域

API

通过向 ResourceRecordSets.create 方法发出 POST 请求来创建 DNS 记录。请将 PROJECT_ID 替换为您的项目 ID。

POST https://www.googleapis.com/dns/v1/projects/PROJECT_ID/managedZones/SERVICE_ZONE/rrsets
{
  "name": "DNS_ENTRY",
  "type": "A",
  "ttl": 30,
  "routingPolicy": {
    "geo": {
      "items": [
        {
          "location": "REGION_A",
          "healthCheckedTargets": {
            "internalLoadBalancers": [
              {
                "loadBalancerType": "globalL7ilb",
                "ipAddress": "IP_ADDRESS",
                "port": "80",
                "ipProtocol": "tcp",
                "networkUrl": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/lb-network",
                "project": "PROJECT_ID"
              }
            ]
          }
        },
        {
          "location": "REGION_B",
          "healthCheckedTargets": {
            "internalLoadBalancers": [
              {
                "loadBalancerType": "globalL7ilb",
                "ipAddress": "IP_ADDRESS_B",
                "port": "80",
                "ipProtocol": "tcp",
                "networkUrl": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/lb-network",
                "project": "PROJECT_ID"
              }
            ]
          }
        }
      ]
    }
  }
}

启用离群值检测

您可以在全球后端服务上启用离群值检测,以识别运行状况不佳的无服务器 NEG 并减少发送到运行状况不佳的无服务器 NEG 的请求数。

可以使用以下方法之一在后端服务上启用离群值检测:

  • consecutiveErrors 方法 (outlierDetection.consecutiveErrors),其中 5xx 系列 HTTP 状态代码被视为错误。
  • consecutiveGatewayFailure 方法 (outlierDetection.consecutiveGatewayFailure),其中只有 502503504 HTTP 状态代码被视为错误。

请按照以下步骤为现有后端服务启用离群值检测。请注意,即使在启用离群值检测后,某些请求也可以发送到运行状况不佳的服务,并向客户端返回 5xx 状态代码。为了进一步降低错误率,您可以为离群值检测参数配置更激进的值。如需了解详情,请参阅 outlierDetection 字段

控制台

  1. 在 Google Cloud 控制台中,转到负载均衡页面。

    转到“负载均衡”

  2. 点击要修改其后端服务的负载均衡器的名称。

  3. 负载均衡器详情页面上,点击 修改

  4. 修改跨区域内部应用负载均衡器页面上,点击后端配置

  5. 后端配置页面上,针对要修改的后端服务点击 修改

  6. 向下滚动并展开高级配置部分。

  7. 离群值检测部分中,选中启用复选框。

  8. 点击 修改以配置离群值检测。

    验证以下选项是否配置了这些值:

    属性
    连续错误数 5
    间隔时间 1000
    基本移除时间 30000
    最大移除百分比 50
    引发强制执行的连续错误数 100

    在此示例中,离群值检测分析每秒运行一次。如果 Envoy 代理收到的连续 HTTP 5xx 状态代码数为 5 个或更多,则后端端点会从 Envoy 代理的负载均衡池中移除 30 秒。当强制百分比设置为 100% 时,后端服务会在每次运行离群值检测分析时从这些特定 Envoy 代理的负载均衡池中逐出运行状况不佳的端点。如果满足移除条件,则最多可以从负载均衡池中移除 50% 的后端端点。

  9. 点击保存

  10. 如需更新后端服务,请点击更新

  11. 如需更新负载均衡器,请在修改跨区域内部应用负载均衡器页面上,点击更新

gcloud

  1. 将后端服务导出到 YAML 文件。

    gcloud compute backend-services export BACKEND_SERVICE_NAME \
      --destination=BACKEND_SERVICE_NAME.yaml --global
    

    BACKEND_SERVICE_NAME 替换为后端服务的名称。

  2. 修改后端服务的 YAML 配置,以添加离群值检测字段,如 outlierDetection 部分中的以下 YAML 配置所示。

    在此示例中,离群值检测分析每秒运行一次。如果 Envoy 代理收到的连续 HTTP 5xx 状态代码数为 5 个或更多,则后端端点会从 Envoy 代理的负载均衡池中移除 30 秒。当强制百分比设置为 100% 时,后端服务会在每次运行离群值检测分析时从这些特定 Envoy 代理的负载均衡池中逐出运行状况不佳的端点。如果满足移除条件,则最多可以从负载均衡池中移除 50% 的后端端点。

    name: BACKEND_SERVICE_NAME
    backends:
    - balancingMode: UTILIZATION
      capacityScaler: 1.0
      group: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_A/networkEndpointGroups/SERVERLESS_NEG_NAME
    - balancingMode: UTILIZATION
      capacityScaler: 1.0
      group: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_B/networkEndpointGroups/SERVERLESS_NEG_NAME_2
    outlierDetection:
      baseEjectionTime:
        nanos: 0
        seconds: 30
      consecutiveErrors: 5
      enforcingConsecutiveErrors: 100
      interval:
        nanos: 0
        seconds: 1
      maxEjectionPercent: 50
    port: 80
    selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_NAME
    sessionAffinity: NONE
    timeoutSec: 30
    ...
    

    请替换以下内容:

    • BACKEND_SERVICE_NAME:后端服务的名称
    • PROJECT_ID:您的项目的 ID
    • REGION_AREGION_B:已配置负载均衡器的区域。
    • SERVERLESS_NEG_NAME:第一个无服务器 NEG 的名称
    • SERVERLESS_NEG_NAME_2:第二个无服务器 NEG 的名称
  3. 通过导入最新配置来更新后端服务。

    gcloud compute backend-services import BACKEND_SERVICE_NAME \
      --source=BACKEND_SERVICE_NAME.yaml --global
    

    离群值检测现已在后端服务上启用。

删除无服务器 NEG

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

控制台

  1. 如需确保您要删除的无服务器 NEG 未被任何后端服务使用,请前往负载均衡组件页面上的后端服务标签页。
    前往“后端服务”标签页
  2. 如果无服务器 NEG 正在使用,请执行以下操作:
    1. 点击正在使用无服务器 NEG 的后端服务的名称。
    2. 点击修改
    3. 后端列表中,点击 以从后端服务中移除无服务器 NEG 后端。
    4. 点击保存

  3. 转到 Google Cloud 控制台中的网络端点组页面。
    前往“网络端点组”页面
  4. 选中您要删除的无服务器 NEG 对应的复选框。
  5. 点击删除
  6. 再次点击删除进行确认。

gcloud

如需从后端服务中移除无服务器 NEG,您必须指定在其中创建该 NEG 的区域。

gcloud compute backend-services remove-backend BACKEND_SERVICE_NAME \
    --network-endpoint-group=SERVERLESS_NEG_NAME \
    --network-endpoint-group-region=REGION \
    --region=REGION

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

gcloud compute network-endpoint-groups delete SERVERLESS_NEG_NAME \
    --region=REGION

后续步骤