使用目标池设置外部直通网络负载均衡器

本指南介绍了如何创建具有目标池后端的外部直通网络负载均衡器配置。该示例假定您在 Compute Engine 实例上有多个 Web 服务器,您希望在这些实例之间均衡流量。此场景设置了一个第 4 层负载均衡配置,以在运行状况良好的实例之间分配 HTTP 流量。基本 HTTP 健康检查已配置,确保仅将流量发送给健康状况良好的实例。

虽然此示例是对 HTTP 流量进行负载均衡,但您可以使用基于目标池的外部直通网络负载均衡器来对 TCP、UDP 和 SSL 流量进行负载均衡。在开始之前,请先阅读外部直通网络负载均衡器概览,了解有关外部直通网络负载均衡器的概念信息。

准备工作

安装 Google Cloud CLI。如需全面了解此工具,请参阅 gcloud 工具指南。您可以在 gcloud compute 命令组中找到与负载均衡相关的命令。

您还可以使用 --help 标志获取有关任何 gcloud 命令的详细帮助:

gcloud compute http-health-checks create --help

如果您之前未运行过 Google Cloud CLI,请先运行 gcloud init 进行身份验证。

此外,您还必须为负载均衡器创建一个静态外部 IP 地址。如果您使用的是 Compute Engine 提供的映像,则系统会自动配置虚拟机 (VM) 实例处理此 IP 地址。如果您使用任何其他映像,则必须将此地址配置为 eth0 上的别名或者每个实例上的环回地址。

本指南假定您熟悉 bash

配置 Compute Engine 虚拟机实例

对于此负载均衡场景,您将创建三个 Compute Engine 虚拟机实例并在实例上安装 Apache。您将添加一条允许 HTTP 流量访问这些实例的防火墙规则。

作为外部直通式网络负载均衡器的后端虚拟机参与的实例必须运行相应的 Linux 客机环境Windows 客机环境或提供同等功能的其他进程。

设置后端实例

控制台

  1. 在 Google Cloud 控制台中,转到虚拟机实例页面。

    转到虚拟机实例

  2. 点击创建实例

  3. 名称设置为 www1

  4. 地区设置为 us-central1

  5. 区域设置为 us-central1-b

  6. 启动磁盘下,默认操作系统映像 Debian GNU/Linux 10 (buster) 已选定。

  7. 点击高级选项

  8. 点击网络并配置以下字段:

    1. 对于网络标记,请输入 network-lb-tag
  9. 点击管理。将以下脚本输入启动脚本字段。

     #! /bin/bash
     sudo apt-get update
     sudo apt-get install apache2 -y
     sudo service apache2 restart
     echo '<!doctype html><html><body><h1>www1</h1></body></html>' | tee /var/www/html/index.html
     

    1. 点击创建
  10. 使用相同的设置创建实例 www2,但要在自动化启动脚本字段中插入以下脚本。

      #! /bin/bash
      sudo apt-get update
      sudo apt-get install apache2 -y
      sudo service apache2 restart
      echo '<!doctype html><html><body><h1>www2</h1></body></html>' | tee /var/www/html/index.html
     

  11. 使用相同的设置创建实例 www3,但要在自动化启动脚本字段中插入以下脚本。

        #! /bin/bash
        sudo apt-get update
        sudo apt-get install apache2 -y
        sudo service apache2 restart
        echo '<!doctype html><html><body><h1>www3</h1></body></html>' | tee /var/www/html/index.html
      

gcloud

以下命令都在本地系统上运行,并且采用 bash 命令提示符。

如需查看操作系统映像名称、特性和状态,请使用 gcloud compute images list 命令。

  1. 在给定的区域中创建三个新的虚拟机,并为所有虚拟机分配相同标记。此示例将区域设置为 us-central1-b。通过设置 tags 字段,您可以一次性同时引用所有这些实例,例如使用防火墙规则。这些命令也会在每个实例上安装 Apache,还会为每个实例提供唯一的主页。

    gcloud compute instances create www1 \
      --image-family debian-10 \
      --image-project debian-cloud \
      --zone us-central1-b \
      --tags network-lb-tag \
      --metadata startup-script="#! /bin/bash
        sudo apt-get update
        sudo apt-get install apache2 -y
        sudo service apache2 restart
        echo '<!doctype html><html><body><h1>www1</h1></body></html>' | tee /var/www/html/index.html"
    gcloud compute instances create www2 \
      --image-family debian-10 \
      --image-project debian-cloud \
      --zone us-central1-b \
      --tags network-lb-tag \
      --metadata startup-script="#! /bin/bash
        sudo apt-get update
        sudo apt-get install apache2 -y
        sudo service apache2 restart
        echo '<!doctype html><html><body><h1>www2</h1></body></html>' | tee /var/www/html/index.html"
    gcloud compute instances create www3 \
      --image-family debian-10 \
      --image-project debian-cloud \
      --zone us-central1-b \
      --tags network-lb-tag \
      --metadata startup-script="#! /bin/bash
        sudo apt-get update
        sudo apt-get install apache2 -y
        sudo service apache2 restart
        echo '<!doctype html><html><body><h1>www3</h1></body></html>' | tee /var/www/html/index.html"

API

使用 instances.insert 方法在区域 us-central1-b 中创建实例 www1

POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-b/instances

{
  "canIpForward": false,
  "deletionProtection": false,
  "disks": [
    {
      "type": "PERSISTENT",
      "boot": true,
      "mode": "READ_WRITE",
      "autoDelete": true,
      "deviceName": "www1",
      "initializeParams": {
        "sourceImage": "projects/debian-cloud/global/images/debian-10-buster-v20220719",
        "diskType": "projects/[PROJECT_ID]/zones/us-central1-b/diskTypes/pd-standard",
        "diskSizeGb": "10"
      }
    }
  ],
  "machineType": "projects/[PROJECT_ID]/zones/us-central1-b/machineTypes/e2-standard-2",
  "metadata": {
    "items": [
      {
        "key": "startup-script",
        "value": "sudo apt-get update\nsudo apt-get install apache2 -y\nsudo a2ensite default-ssl\nsudo a2enmod ssl\nsudo service apache2 restart\necho '<!doctype html><html><body><h1>www1</h1></body></html>' | tee /var/www/html/index.html"
      }
    ]
  },
  "name": "www1",
  "networkInterfaces": [
    {
      "network": "projects/[PROJECT_ID]/global/networks/default",
      "subnetwork": "projects/[PROJECT_ID]/regions/us-central1/subnetworks/default"
    }
  ],
  "tags": {
    "items": [
      "network-lb-tag"
    ]
  }
}

使用相同的设置创建实例 www2www3,但需要替换 deviceNamevaluename 字段中的 www1

创建一条防火墙规则以允许外部流量进入这些虚拟机实例

控制台

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

    转到“防火墙政策”

  2. 点击创建防火墙规则

  3. 输入 www-firewall-network-lb 作为名称

  4. 选择要应用防火墙规则的网络默认)。

  5. 目标下,选择指定的目标标记

  6. 目标标记字段中,输入 network-lb-tag

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

  8. 来源 IPv4 地址范围设置为 0.0.0.0/0(允许来自任何来源的流量)。

  9. 指定的协议和端口下,选中 TCP 复选框并输入 80

  10. 点击创建。新的防火墙规则可能需要一段时间才能在控制台中显示,或者您可能需要点击刷新才能看见规则。

gcloud

gcloud compute firewall-rules create www-firewall-network-lb \
    --target-tags network-lb-tag --allow tcp:80

API

使用 firewalls.insert 方法创建允许子网内所有流量通过的防火墙规则

POST https://compute.googleapis.com/compute/projects/[PROJECT_ID]/global/firewalls

{
  "name": "www-firewall-network-lb",
  "direction": "INGRESS",
  "priority": 1000,
  "targetTags": [
    "network-lb-tag"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "80"
      ]
    }
  ],
  "sourceRanges": [
    "0.0.0.0/0"
  ]
}

获取实例的外部 IP 地址并验证它们正在运行

控制台

  1. 在 Google Cloud 控制台中,转到虚拟机实例页面。

    转到虚拟机实例

  2. 外部 IP 列中查看您的实例的地址。

  3. 在实例名称左侧查找绿色对勾标记,以验证您的实例是否正在运行。如果您没有看到绿色对勾标记,请参阅实例的“常规问题排查”页面

gcloud

  1. 列出您的实例,从 EXTERNAL_IP 列中获取其 IP 地址。

    gcloud compute instances list
    
  2. 验证各个实例是否正在运行。

    在命令行中,使用每个实例的外部 IP 地址运行 curl,确认所有实例都能响应。

    curl http://[IP_ADDRESS]
    

API

使用 instances.get 方法获取有关实例 www1 的信息

确保 status 字段显示 RUNNING,然后在 natIP 字段中查找外部 IP 地址。

GET https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-b/instances/www1

{
 "kind": "compute#instance",
 "id": "6734015273571474749",
 "creationTimestamp": "2018-11-09T11:45:23.487-08:00",
 "name": "www1",
 "description": "",
 "tags": {
  "items": [
   "network-lb-tag"
  ],
  "fingerprint": "9GVlO4gPawg="
 },
 "machineType": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-b/machineTypes/e2-standard-2",
 "status": "RUNNING",
 "zone": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-b",
 "canIpForward": false,
 "networkInterfaces": [
  {
   "kind": "compute#networkInterface",
   "network": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/default",
   "subnetwork": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-central1/subnetworks/default",
   "networkIP": "10.128.0.2",
   "name": "nic0",
   "accessConfigs": [
    {
     "kind": "compute#accessConfig",
     "type": "ONE_TO_ONE_NAT",
     "name": "External NAT",
     "natIP": "35.192.37.233",
     "networkTier": "PREMIUM"
    }
   ],
   "fingerprint": "lxD5f5ua_sw="
  }
 ],
 "disks": [
  {
   "kind": "compute#attachedDisk",
   "type": "PERSISTENT",
   "mode": "READ_WRITE",
   "source": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-b/disks/www1",
   "deviceName": "www1",
   "index": 0,
   "boot": true,
   "autoDelete": true,
   "licenses": [
    "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/licenses/debian-10-buster"
   ],
   "interface": "SCSI",
   "guestOsFeatures": [
    {
     "type": "VIRTIO_SCSI_MULTIQUEUE"
    }
   ]
  }
 ],
 "metadata": {
  "kind": "compute#metadata",
  "fingerprint": "IyHRmHoJx6E=",
  "items": [
   {
    "key": "startup-script",
    "value": "#! /bin/bash\n sudo apt-get update\n sudo apt-get install apache2 -y\n sudo service apache2 restart\n echo '\u003c!doctype html\u003e\u003chtml\u003e\u003cbody\u003e\u003ch1\u003ewww1\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e' | tee /var/www/html/index.html"
   }
  ]
 },
 "serviceAccounts": [
  {
   "email": "674259759219-compute@developer.gserviceaccount.com",
   "scopes": [
    "https://www.googleapis.com/auth/devstorage.read_only",
    "https://www.googleapis.com/auth/logging.write",
    "https://www.googleapis.com/auth/monitoring.write",
    "https://www.googleapis.com/auth/servicecontrol",
    "https://www.googleapis.com/auth/service.management.readonly",
    "https://www.googleapis.com/auth/trace.append"
   ]
  }
 ],
 "selfLink": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-b/instances/www1",
 "scheduling": {
  "onHostMaintenance": "MIGRATE",
  "automaticRestart": true,
  "preemptible": false
 },
 "cpuPlatform": "Intel Haswell",
 "labelFingerprint": "42WmSpB8rSM=",
 "startRestricted": false,
 "deletionProtection": false
}

www2www3 重复此 API 调用。

配置负载均衡服务

接下来,设置负载均衡服务。

配置负载均衡服务时,虚拟机实例将接收发往您配置的静态外部 IP 地址的数据包。如果您使用的是 Compute Engine 提供的映像,则系统会自动配置您的实例处理此 IP 地址。如果您使用任何其他映像,则必须将此地址配置为 eth0 上的别名或者每个实例上的环回地址。

控制台

您无法使用 Google Cloud 控制台创建基于目标池的外部直通式网络负载均衡器。请改用 gcloud 或 REST API。

gcloud

  1. 为负载均衡器创建静态外部 IP 地址

    gcloud compute addresses create network-lb-ip-1 \
        --region us-central1
    
  2. 添加旧版 HTTP 健康检查资源

    本示例使用健康检查机制的默认设置,但您也可以自行自定义健康检查。

    gcloud compute http-health-checks create basic-check
    
  3. 添加目标池

    在虚拟机实例所在的区域中添加目标池。使用上一步为此目标池创建的健康检查。目标池需要健康检查服务才能正常工作。

    gcloud compute target-pools create www-pool \
        --region us-central1 --http-health-check basic-check
    
  4. 将实例添加到目标池

    gcloud compute target-pools add-instances www-pool \
        --instances www1,www2,www3 \
        --instances-zone us-central1-b
    

    目标池中的实例必须属于同一地区,但可以分布在同一地区内的不同区域中。例如,在一个目标池中,您可以具有区域 us-central1-f 中的实例和区域 us-central1-b 中的实例,因为这些区域位于同一地区 us-central1

  5. 添加转发规则

    添加转发规则,以代表指向目标池的外部 IP 地址和端口范围传送数据。对于 --address 字段,请使用数字 IP 地址或其完全限定名称。

    gcloud compute forwarding-rules create www-rule \
        --region us-central1 \
        --ports 80 \
        --address network-lb-ip-1 \
        --target-pool www-pool
    

API

  1. 为负载均衡器创建静态外部 IP 地址

    POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID/regions/us-central1/addresses
    {
      "name": "network-lb-ip-1"
    }
    
  2. 添加旧版 HTTP 健康检查

    本示例使用健康检查机制的默认设置,但您也可以自行自定义健康检查机制。

    POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/httpHealthChecks
    {
      "name": "basic-check"
    }
    
  3. 添加目标池

    在虚拟机实例所在的区域中添加目标池。使用上一步为此目标池创建的健康检查。目标池需要健康检查服务才能正常工作。

    POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-central1/targetPools
    {
      "name": "www-pool",
      "healthChecks": [
        "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/httpHealthChecks/basic-check"
      ]
    }
    
  4. 将实例添加到目标池

    POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-central1/targetPools/www-pool/addInstance
    {
      "instances": [
        {
          "instance": "projects/[PROJECT_ID]/zones/us-central1-b/instances/www1"
        }
      ]
    }
    

    对实例 www2www3 重复此 API 调用。

    目标池中的实例必须属于同一地区,但可以分布在同一地区内的不同区域中。例如,在一个目标池中,您可以具有区域 us-central1-f 中的实例和区域 us-central1-b 中的实例,因为这些区域位于同一地区 us-central1

  5. 添加转发规则

    POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-central1/forwardingRules
    {
      "name": "www-rule",
      "portRange": "80",
      "loadBalancingScheme": "EXTERNAL",
      "target": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-central1/targetPools/www-network-lb"
    }
    

将流量发送到您的实例

在配置了负载均衡服务后,您可以开始将流量发送到转发规则并观察流量分散到不同的实例。

查找转发规则的外部 IP 地址

控制台

  1. 转到 Google Cloud Console 中高级负载均衡页面上的转发规则标签页。
    转到“转发规则”标签页
  2. 找到 www-rule,即负载均衡器使用的转发规则。
  3. www-ruleIP 地址列中,记下列出的外部 IP 地址。

gcloud

输入以下命令,查看负载均衡器使用的 www-rule 转发规则的外部 IP 地址。

gcloud compute forwarding-rules describe www-rule --region us-central1

API

使用 forwardingRules.get 方法查看 www-rule 转发规则的外部 IP 地址

在输出中,查找 IPAddress 字段。

GET https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-central1/forwardingRules/www-rule
{
  "kind": "compute#forwardingRule",
  "id": "5133886346582800002",
  "creationTimestamp": "2018-11-09T14:21:33.574-08:00",
  "name": "www-rule",
  "description": "",
  "region": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-central1",
  "IPAddress": "35.232.228.9",
  "IPProtocol": "TCP",
  "portRange": "80-80",
  "target": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-central1/targetPools/www-network-lb",
  "selfLink": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-central1/forwardingRules/www-rule",
  "loadBalancingScheme": "EXTERNAL",
  "networkTier": "PREMIUM"
}

后端实例不支持 ICMP

外部直通式网络负载均衡器不会向后端实例递送 ICMP 数据包。如果您发送 ICMP 数据包(例如,使用 pingtraceroute),则响应并非来自负载均衡器的后端实例。

即使您的防火墙规则可禁止负载均衡器后端实例上的 ICMP 流量,Google Cloud 基础架构也可能会发送 ICMP 回复。此行为无法更改。

使用 curl 命令访问外部 IP 地址

来自 curl 命令的响应会在三个实例之间随机交替。如果响应最初不成功,您可能需要等待大约 30 秒才能完全加载配置,并在再次尝试前将实例的状态标记为运行状况良好:

$ while true; do curl -m1 IP_ADDRESS; done

后续步骤