为高可用性应用使用负载平衡功能

本教程介绍了如何将负载均衡功能与区域托管实例组结合使用,以便将流量从繁忙或不可用的虚拟机实例重定向到其他位置,使您即使在地区服务中断时也能确保高可用性。

区域级托管式实例组在多个可用区的多个实例上分发应用。全球负载均衡器通过单个 IP 地址跨多个区域引导流量。通过使用这两项服务在多个地区分发应用,您可以帮助确保应用即使在极端情况下(如地区服务中断时)也可用。

负载平衡器可用于引导各种类型的流量。本教程介绍了如何创建可引导外部 HTTP 流量的全球负载均衡器,但其中的大部分内容仍与其他类型的负载均衡器相关。如需了解可以使用负载均衡器引导的其他类型的流量,请参阅 Cloud Load Balancing 的类型

本教程包含一系列详细步骤,说明了如何在区域托管实例组上启动 Web 应用,如何配置网络访问权限,如何创建用于将流量引导至 Web 应用的负载均衡器,以及如何通过模拟地区服务中断来观察负载均衡器。完成本教程需要大约 45 分钟,具体取决于您对这些功能的熟悉程度。

应用架构

应用包括以下 Compute Engine 组件:

  • VPC 网络: Google Cloud 内的虚拟网络,可通过自己的路由和防火墙规则提供全球连接。
  • 防火墙规则:借助 Google Cloud防火墙,您可以允许或拒绝流向您的实例的流量。
  • 实例模板:用于在托管实例组中创建各个虚拟机实例的模板。
  • 区域级托管式实例组:跨多个可用区运行同一应用的一组虚拟机实例。
  • 全球静态外部 IP 地址:可以在外部网络上访问并且可以连接到全球性资源的静态 IP 地址。
  • 全球负载均衡器:允许后端实例跨多个区域分布的负载均衡器。如果您的用户需要访问相同的应用和内容,并且您希望使用单个 Anycast IP 地址提供访问权限,请使用全球负载均衡器。
  • 健康检查:负载均衡器用来评估应用在每个虚拟机实例上的响应能力的政策。

启动 Web 应用

本教程以存储在 GitHub 上的 Web 应用为例。如果您想详细了解该应用的实现方式,请参阅 GitHub 上的 GoogleCloudPlatform/python-docs-samples 代码库。

通过在实例模板中添加启动脚本的方式在实例组中的每个虚拟机上启动 Web 应用。此外,在专用 VPC 网络中运行实例组,以防止本教程中的防火墙规则干扰您的项目中运行的任何现有资源。

创建 VPC 网络

使用 VPC 网络可防止项目中的现有资源受到您针对本教程创建的资源的影响。 此外,为了限制传入流量,使它必须通过负载均衡器,也需要用到 VPC 网络。

创建 VPC 网络,以封装演示 Web 应用的防火墙规则:

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

    进入 VPC 网络页面

  2. 点击创建 VPC 网络

  3. 名称下,输入 web-app-vpc

  4. 子网创建模式设置为自定义

  5. 按如下步骤创建新子网:

    1. 子网部分中,设置名称字段,输入 web-app-vpc-subnet
    2. 区域下拉菜单中,选择 us-central1
    3. 确保 IP 栈类型选项设置为 IPv4
    4. 主要 IPv4 范围部分中,输入 IPv4 范围 10.2.0.0/24
  6. 点击页面底部的创建

等到 VPC 网络创建完成后再继续。

创建防火墙规则

VPC 网络创建后,设置防火墙规则以允许 HTTP 流量进入 VPC 网络:

  1. 在 Google Cloud 控制台中,前往防火墙页面。

    转到防火墙

  2. 点击创建防火墙规则

  3. 名称字段中,输入 allow-web-app-http

  4. 网络设置为 web-app-vpc

  5. 确保以下选项已按指定方式设置:

    • 流量方向选项设置为入站
    • 对匹配项执行的操作选项设置为允许
  6. 目标下拉菜单中,选择网络中的所有实例

  7. 来源过滤条件设置为 IPv4 ranges

  8. 来源 IP 地址范围 字段中,输入 130.211.0.0/22, 35.191.0.0/16 以允许负载均衡器健康检查。

  9. 协议和端口下,执行以下操作:

    1. 选择指定的协议和端口
    2. 选择 TCP
    3. 端口字段中,输入 80允许访问 HTTP 流量
  10. 点击创建

创建实例模板

创建将用于创建一组虚拟机实例的模板。基于模板创建的每个实例都会通过启动脚本启动演示 Web 应用。

  1. 在 Google Cloud 控制台中,转到实例模板页面。

    转到“实例模板”

  2. 点击创建实例模板

  3. 名称下,输入 load-balancing-web-app-template

  4. 机器配置下,将机器类型设置为 e2-medium

  5. 点击高级选项部分以展开。

  6. 点击网络部分,然后执行以下操作:

    1. 网络接口部分中,点击现有网络接口旁边的 图标,以删除这些接口。
    2. 点击添加网络接口,然后选择 web-app-vpc 网络。这会强制使用此模板创建的每个实例在先前创建的网络上运行。
    3. 子网下拉菜单中,选择 web-app-vpc-subnet
    4. 点击完成
  7. 点击管理部分,然后执行以下操作:

    1. 自动化部分中,输入以下启动脚本:

      apt-get update
      apt-get -y install git python3-pip python3-venv
      git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
      python3 -m venv venv
      ./venv/bin/pip3 install -Ur ./python-docs-samples/compute/managed-instances/demo/requirements.txt
      ./venv/bin/pip3 install gunicorn
      ./venv/bin/gunicorn --bind 0.0.0.0:80 app:app --daemon --chdir ./python-docs-samples/compute/managed-instances/demo
      

      该脚本会在虚拟机实例启动时获取、安装和启动 Web 应用。

  8. 其他选项保留默认值。

  9. 点击创建

等到模板创建完成后再继续。

创建区域托管实例组

如需运行 Web 应用,请使用实例模板创建区域级托管式实例组:

  1. 在 Google Cloud 控制台中,前往实例群组页面。

    进入“实例组”

  2. 点击创建实例组

  3. 对于名称,输入 load-balancing-web-app-group

  4. 对于实例模板,请选择 load-balancing-web-app-template

  5. 实例数设置为 6。 如果此字段已停用,请先关闭自动扩缩功能。

    如需关闭自动扩缩,请前往自动扩缩部分。在自动扩缩模式下拉菜单中,选择关闭:不自动扩缩

  6. 对于位置,选择多个可用区

  7. 对于区域,选择 us-central1

  8. 对于可用区,请从下拉列表中选择以下可用区:

    • us-central1-b
    • us-central1-c
    • us-central1-f
  9. 其他选项保留默认值。

  10. 点击创建。这会使您返回实例组页面。

    您可能需要等待几分钟,直到组中的所有实例都处于运行状态。

配置负载平衡器

为了使用负载均衡器将流量引导至您的 Web 应用,必须保留一个外部 IP 地址来接收所有传入流量。然后,创建一个负载均衡器,用于接受来自该 IP 地址的流量,并将该流量重定向到实例组。

保留静态 IP 地址

使用全局静态外部 IP 地址为负载平衡器提供单一入口点,以接收所有用户流量。即使您更改或删除任何关联的 Google Cloud 资源,Compute Engine 也会保留静态 IP 地址。这样一来,Web 应用始终具有同一入口点,即使 Web 应用的其他部分可能发生更改也是如此。

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

    进入“IP 地址”

  2. 点击预留外部静态 IP 地址

  3. 名称字段中,输入 web-app-ipv4

  4. IP 版本设置为 IPv4

  5. 类型设置为全局

  6. 点击保留

创建负载均衡器

本部分介绍了创建可引导 HTTP 流量的全局负载均衡器所需的步骤。

此负载均衡器使用前端接收传入流量,使用后端将此流量分配到运行状况良好的实例。由于负载均衡器由多个组件组成,因此此任务分为下列五个部分:

  • 选择负载均衡器类型
  • 为负载均衡器命名
  • 配置前端
  • 配置后端
  • 检查并最终确定

完成创建负载均衡器的所有部分。

选择负载均衡器类型

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

    转到“负载均衡”

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

为负载均衡器命名

  1. 在左侧面板中,对于负载均衡器名称,输入 web-app-load-balancer

配置前端

  1. 前端配置页面的名称下,输入 web-app-ipv4-frontend
  2. 协议设置为 HTTP
  3. IP 版本设置为 IPv4
  4. IP 地址设置为 web-app-ipv4
  5. 端口设置为 80
  6. 点击完成以创建前端。

配置后端

  1. 在左侧面板中,点击后端配置
  2. 点击后端服务和后端存储桶下拉菜单以打开一个菜单,然后点击创建后端服务
  3. 在新窗口中,对于后端服务的名称,输入 web-app-backend
  4. 后端部分,执行以下操作:
    1. 实例组设置为 load-balancing-web-app-group
    2. 端口号设置为 80。这允许 HTTP 流量在负载均衡器和实例组之间传输。
    3. 平衡模式下,选择利用率
    4. 点击完成
  5. 为负载均衡器的后端创建健康检查,如下所示:

    1. 点击健康检查下拉菜单,然后点击创建健康检查。此时会出现一个新窗口。
    2. 在新窗口中的名称下,输入 web-app-load-balancer-check
    3. 协议设置为 HTTP
    4. 端口下,输入 80
    5. 对于本教程,将请求路径设置为 /health,这是演示 Web 应用设置为进行响应的路径。
    6. 设置以下运行状况判断标准

      1. 检查间隔设置为 3 秒。这定义了从一次探测开始到下一次探测开始之间的时间间隔。
      2. 超时设置为 3 秒。这定义了 Google Cloud 等待探测响应的时间量。其值必须小于或等于检查间隔时间。
      3. 状况良好判断阈值设置为连续成功 2 次。这定义了要将实例视为运行状况良好必须成功的连续探测次数。
      4. 状况不佳判断阈值设置为连续失败 2 次。这定义了要将实例视为运行状况不佳所必须失败的连续探测次数。
    7. 点击创建以创建健康检查。

  6. 其他选项保留默认值。

  7. 点击创建以创建后端服务。

检查并最终确定

在创建负载均衡器之前验证负载均衡设置:

  1. 创建全球外部应用负载均衡器页面的左侧面板中,点击检查并最终确定
  2. 检查并最终确定页面上,验证前端是否使用协议HTTP 的 IP 地址。

  3. 在同一页面上,验证以下后端设置:

    • 后端服务web-app-backend
    • 端点协议HTTP
    • 健康检查web-app-load-balancer-check
    • 实例组load-balancing-web-app-group
  4. 点击创建以完成负载均衡器的创建。

您可能需要等待几分钟,以便负载均衡器完成创建。

测试负载均衡器

验证可以使用负载均衡器连接到 Web 应用,如下所示:

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

    转到“负载均衡”

  2. 名称列中,点击 web-app-load-balancer 以展开刚刚创建的负载均衡器。

  3. 如需使用外部静态 IP 地址连接到 Web 应用,请执行以下操作:

    1. 前端部分中,复制 IP:端口列中显示的 IP 地址。
    2. 打开新的浏览器标签页并将 IP 地址粘贴到地址栏中。此时应该显示演示 Web 应用:

      演示 Web 应用。

    请注意,无论何时刷新页面,负载均衡器都会连接到不同区域中的不同实例。之所以发生这种情况,是因为您没有直接连接到实例;您连接的是负载均衡器,该负载均衡器选择了您要重定向到的实例。

    完成后,关闭演示 Web 应用所在的浏览器标签页。

模拟地区服务中断

您可以通过模拟地区服务中断时的大面积不可用情况来观察负载平衡器的功能。此模拟的工作原理是强制位于指定地区的所有实例在 /health 请求路径上报告运行状况不佳这一状态。当这些实例报告健康状况不佳这一状态时,它们将无法通过负载均衡健康检查,这会提示负载均衡器停止将流量引导到其中。

  1. 监控负载均衡器将流量引导至哪些地区。

    1. 在 Google Cloud 控制台中,前往 Cloud Shell

      打开 Cloud Shell

      Cloud Shell 会在Google Cloud 控制台窗格中打开。该会话可能需要几秒钟来完成初始化。

    2. 按如下所示保存负载均衡器的静态外部 IP 地址:

      1. 通过在终端中输入以下命令,从负载均衡器的前端转发规则中获取外部 IP 地址:

        gcloud compute forwarding-rules describe web-app-ipv4-frontend --global
        

        输出如下所示。从输出结果中复制 EXTERNAl_IP_ADDRESS

        IPAddress: EXTERNAl_IP_ADDRESS
        ...
        
      2. 创建一个本地 bash 变量:

        export LOAD_BALANCER_IP=EXTERNAl_IP_ADDRESS
        

        EXTERNAl_IP_ADDRESS 替换为您复制的外部 IP 地址。

    3. 如需监控负载均衡器将流量定向到哪些区域,请运行以下 bash 脚本:

      while true
      do
          BODY=$(curl -s "$LOAD_BALANCER_IP")
          NAME=$(echo -n "$BODY" | grep "load-balancing-web-app-group" | perl -pe 's/.+?load-balancing-web-app-group-(.+?)<.+/\1/')
          ZONE=$(echo -n "$BODY" | grep "us-" | perl -pe 's/.+?(us-.+?)<.+/\1/')
          echo $ZONE
          sleep 2 # Wait for 2 seconds
      done
      

      此脚本会不断尝试通过负载均衡器前端的 IP 地址连接到 Web 应用,并输出 Web 应用在其中针对每个连接运行的区域。

      生成的输出结果应包括 us-central1-bus-central1-cus-central1-f 区域:

      us-central1-f
      us-central1-b
      us-central1-c
      us-central1-f
      us-central1-f
      us-central1-c
      us-central1-f
      us-central1-c
      us-central1-c
      

      保持此终端处于打开状态。

  2. 在监控运行时,开始模拟地区性中断。

    1. 在 Cloud Shell 中,点击 添加按钮打开第二个终端会话
    2. 为项目 ID 创建本地 bash 变量:

      export PROJECT_ID=PROJECT_ID
      

      其中,PROJECT_ID 是当前项目的 ID,它显示在 Cloud Shell 中的每个新行上:

      user@cloudshell:~ (PROJECT_ID)$
      
    3. 为要停用的地区创建本地 bash 变量。如需模拟地区 us-central1-f 出现故障的情况,请使用以下命令:

      export DISABLE_ZONE=us-central1-f
      

      然后,运行以下 bash 脚本。此脚本会导致停用地区中的演示 Web 应用实例对负载均衡器的健康检查输出健康状况不佳的响应。运行状况不佳的响应会提示负载平衡器将流量引导离开这些实例。

      export MACHINES=$(gcloud --project=$PROJECT_ID compute instances list --filter="zone:($DISABLE_ZONE)" --format="csv(name,networkInterfaces[0].accessConfigs[0].natIP)" | grep "load-balancing-web-app-group")
      for i in $MACHINES;
      do
        NAME=$(echo "$i" | cut -f1 -d,)
        IP=$(echo "$i" | cut -f2 -d,)
        echo "Simulating zonal failure for zone $DISABLE_ZONE, instance $NAME"
        curl -q -s "http://$IP/makeUnhealthy" >/dev/null --retry 2
      done
      

      短暂延迟后,负载均衡器会停止将流量引导至运行状况不佳的地区,因此第一个终端窗口的输出结果会停止列出地区 us-central1-f

      us-central1-c
      us-central1-c
      us-central1-c
      us-central1-b
      us-central1-b
      us-central1-c
      us-central1-b
      us-central1-c
      us-central1-c
      

      这表明负载平衡器仅将流量引导至运行状况良好且响应迅速的实例。

      请使两个终端都保持打开状态。

    4. 在第二个终端中,为要恢复的地区创建本地 bash 变量。如需恢复引导到地区 us-central1-f 的流量,请使用以下命令:

      export ENABLE_ZONE=us-central1-f
      

      然后,运行以下 bash 脚本。此脚本会导致启用地区中的演示 Web 应用实例对负载均衡器的健康检查输出健康状况良好的响应。运行状况良好的响应会提示负载平衡器开始将流量重新分配到这些实例。

      export MACHINES=$(gcloud --project=$PROJECT_ID compute instances list --filter="zone:($ENABLE_ZONE)" --format="csv(name,networkInterfaces[0].accessConfigs[0].natIP)" | grep "load-balancing-web-app-group")
      for i in $MACHINES;
      do
        NAME=$(echo "$i" | cut -f1 -d,)
        IP=$(echo "$i" | cut -f2 -d,)
        echo "Simulating zonal restoration for zone $ENABLE_ZONE, instance $NAME"
        curl -q -s "http://$IP/makeHealthy" >/dev/null --retry 2
      done
      

      几分钟后,第一个终端窗口的输出结果会再次逐步列出可用区 us-central1-f

      us-central1-b
      us-central1-b
      us-central1-c
      us-central1-f
      us-central1-c
      us-central1-c
      us-central1-b
      us-central1-c
      us-central1-f
      

      这表明负载平衡器正在重新将传入流量引导至所有地区。

      完成后关闭这两个终端。