设置内部 TCP/UDP 负载平衡

本指南使用示例来介绍 Google Cloud Platform 内部 TCP/UDP 负载平衡的基础知识。在按照本指南中的说明进行操作之前,请先熟悉以下内容:

权限

要按照本指南进行操作,您需要创建实例并修改项目中的网络。您应该具有项目的 Owner 或 Editor 角色,或者应该具有以下 Compute Engine IAM 角色

任务 所需角色
创建网络、子网和负载平衡器组件 Network Admin
添加和移除防火墙规则 Security Admin
创建实例 Instance Admin

设置

本指南介绍如何配置和测试内部 TCP/UDP 负载平衡器。此部分中的步骤介绍了如何配置以下内容:

  1. 带有自定义子网的示例 VPC 网络
  2. 允许后端虚拟机的传入连接的防火墙规则
  3. 四个后端虚拟机:
    • 地区 us-west1-a 中非托管实例组中的两个虚拟机
    • 地区 us-west1-c 中非托管实例组中的两个虚拟机
  4. 一个用于测试连接的客户端虚拟机
  5. 以下内部 TCP/UDP 负载平衡器组件:
    • 后端服务运行状况检查
    • us-west1 区域中的内部后端服务,用于管理两个地区实例组的连接分布
    • 负载平衡器前端的内部转发规则和内部 IP 地址

此示例的架构如下所示:

内部 TCP/UDP 负载平衡示例配置(点击放大)
内部 TCP/UDP 负载平衡示例配置(点击放大)

配置网络、区域和子网

您需要一个至少具有一个子网的 VPC 网络。内部 TCP/UDP 负载平衡器是区域性的。对于 VPC 网络中的流量,如果其来源所在的子网与负载平衡器位于同一区域,那么该流量会被路由到负载平衡器。

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

  • 网络:网络为自定义模式 VPC 网络,名为 lb-network

  • 区域:区域为 us-west1

  • 子网:子网为 lb-subnet,使用 10.1.2.0/24 IP 地址范围。

如需创建示例网络和子网,请按照以下步骤操作。

控制台

  1. 转到 Google Cloud Platform Console 中的“VPC 网络”页面。
    转到“VPC 网络”页面
  2. 点击创建 VPC 网络
  3. 输入 lb-network 作为名称
  4. 子网部分中执行以下操作:
    • 子网创建模式设置为自定义。
    • 新子网部分中,输入以下信息:
      • 名称lb-subnet
      • 区域us-west1
      • IP 地址范围10.1.2.0/24
      • 点击完成
  5. 点击创建

gcloud

  1. 创建自定义 VPC 网络:

    gcloud compute networks create lb-network --subnet-mode=custom
    
  2. us-west1 区域的 lb-network 网络中创建子网:

    gcloud compute networks subnets create lb-subnet \
        --network=lb-network \
        --range=10.1.2.0/24 \
        --region=us-west1
    

api

networks.insert 方法发出 POST 请求。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks
{
  "routingConfig": {
    "routingMode": "REGIONAL"
  },
  "name": "lb-network",
  "autoCreateSubnetworks": false
}

subnetworks.insert 方法发出 POST 请求。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/subnetworks
{
  "name": "lb-subnet",
  "network": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/lb-network",
  "ipCidrRange": "10.1.2.0/24",
  "privateIpGoogleAccess": false
}

配置防火墙规则

此示例使用以下防火墙规则:

  • fw-allow-lb-subnet:适用于 VPC 网络中所有目标的入站规则,允许来自 10.1.2.0/24 范围内来源的流量。此规则允许从 lb-subnet 内的任何来源向负载平衡实例(虚拟机)传入流量。

  • fw-allow-ssh:适用于负载平衡实例的入站规则,该规则允许从任何地址到 TCP 端口 22 的传入 SSH 连接。您可以为此规则选择限制性更高的源 IP 地址范围;例如,您可以仅指定要从中启动 SSH 会话的系统的 IP 地址范围。此示例使用目标标记 allow-ssh 来标识它应该应用到的虚拟机。

  • fw-allow-health-check:适用于负载平衡实例的入站规则,该规则允许来自 GCP 运行状况检查系统(130.211.0.0/2235.191.0.0/16)的流量。此示例使用目标标记 allow-health-check 来标识它应该应用到的实例。

如果不使用上述防火墙规则,则默认拒绝入站规则会阻止传入后端实例的流量。

控制台

  1. 转到 Google Cloud Platform Console 中的“防火墙规则”页面。
    转到“防火墙规则”页面
  2. 点击创建防火墙规则并输入以下信息,以创建允许子网流量的规则:
    • 名称fw-allow-lb-subnet
    • 网络lb-network
    • 优先级1000
    • 流量方向:入站
    • 对匹配项执行操作:允许
    • 目标:网络中的所有实例
    • 来源过滤条件IP ranges
    • 来源 IP 地址范围10.1.2.0/24
    • 协议和端口:允许全部
  3. 点击创建
  4. 再次点击创建防火墙规则,以创建允许传入 SSH 连接的规则:
    • 名称fw-allow-ssh
    • 网络lb-network
    • 优先级1000
    • 流量方向:入站
    • 对匹配项执行操作:允许
    • 目标:指定的目标标记
    • 目标标记allow-ssh
    • 来源过滤条件IP ranges
    • 来源 IP 地址范围0.0.0.0/0
    • 协议和端口:选择指定的协议和端口,然后输入:tcp:22
  5. 点击创建
  6. 第三次点击创建防火墙规则,以创建允许 GCP 运行状况检查的规则:
    • 名称fw-allow-health-check
    • 网络lb-network
    • 优先级1000
    • 流量方向:入站
    • 对匹配项执行操作:允许
    • 目标:指定的目标标记
    • 目标标记allow-health-check
    • 来源过滤条件IP ranges
    • 来源 IP 地址范围130.211.0.0/2235.191.0.0/16
    • 协议和端口:允许全部
  7. 点击创建

gcloud

  1. 创建 fw-allow-lb-subnet 防火墙规则以允许与子网通信:

    gcloud compute firewall-rules create fw-allow-lb-subnet \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --source-ranges=10.1.2.0/24 \
        --rules=tcp,udp,icmp
    
  2. 创建 fw-allow-ssh 防火墙规则,允许通过 SSH 连接到网络标记为 allow-ssh 的虚拟机。如果省略 source-ranges,则 GCP 会将规则解读为表示任何来源

    gcloud compute firewall-rules create fw-allow-ssh \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --target-tags=allow-ssh \
        --rules=tcp:22
    
  3. 创建 fw-allow-health-check 规则以允许执行 GCP 运行状况检查。

    gcloud compute firewall-rules create fw-allow-health-check \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --target-tags=allow-health-check \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --rules=tcp,udp,icmp
    

api

firewalls.insert 方法发出 POST 请求,以创建 fw-allow-lb-subnet 防火墙规则。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/firewalls
{
  "name": "fw-allow-lb-subnet",
  "network": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/lb-network",
  "priority": 1000,
  "sourceRanges": [
    "10.1.2.0/24"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp"
    },
    {
      "IPProtocol": "udp"
    },
    {
      "IPProtocol": "icmp"
    }
  ],
  "direction": "INGRESS",
  "logConfig": {
    "enable": false
  },
  "disabled": false
}

firewalls.insert 方法发出 POST 请求,以创建 fw-allow-ssh 防火墙规则。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/firewalls
{
  "name": "fw-allow-ssh",
  "network": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/lb-network",
  "priority": 1000,
  "sourceRanges": [
    "0.0.0.0/0"
  ],
  "targetTags": [
    "allow-ssh"
  ],
  "allowed": [
   {
     "IPProtocol": "tcp",
     "ports": [
       "22"
     ]
   }
  ],
 "direction": "INGRESS",
 "logConfig": {
   "enable": false
 },
 "disabled": false
}

firewalls.insert 方法发出 POST 请求,以创建 fw-allow-health-check 防火墙规则。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/firewalls
{
  "name": "fw-allow-health-check",
  "network": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/lb-network",
  "priority": 1000,
  "sourceRanges": [
    "130.211.0.0/22",
    "35.191.0.0/16"
  ],
  "targetTags": [
    "allow-health-check"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp"
    },
    {
      "IPProtocol": "udp"
    },
    {
      "IPProtocol": "icmp"
    }
  ],
  "direction": "INGRESS",
  "logConfig": {
    "enable": false
  },
  "disabled": false
}

创建后端虚拟机和实例组

此示例使用了两个非托管实例组,每个实例组都有两个后端(服务器)虚拟机。为了演示内部 TCP/UDP 负载平衡的区域特性,这两个实例组分别位于 us-west1-aus-west1-c 地区。

  • 实例组 ig-a 包含以下两个虚拟机:
    • vm-a1
    • vm-a2
  • 实例组 ig-c 包含以下两个虚拟机:
    • vm-c1
    • vm-c2

传入到四个后端虚拟机的流量都经过负载平衡。四个后端虚拟机均在 TCP 端口 80 和 443 上运行 Apache 网络服务器。每个虚拟机均分配有 lb-subnet 的内部 IP 地址和临时外部(公共)IP 地址。您稍后可以移除外部 IP 地址

后端虚拟机的外部 IP 地址不是必需的;但是它们对于此示例很有用,因为它们允许后端虚拟机从互联网下载 Apache,并且便于您通过 SSH 进行连接

默认情况下,Apache 配置为绑定到任何 IP 地址。内部 TCP/UDP 负载平衡器通过保留目标 IP 地址来传送数据包。确保在后端虚拟机上运行的服务器软件在监听负载平衡器内部转发规则的 IP 地址。如果您配置了多条内部转发规则,请确保您的软件会监听与每条规则关联的内部 IP 地址。由内部 TCP/UDP 负载平衡器传送到后端虚拟机的数据包的目标 IP 地址是转发规则的内部 IP 地址。

为便于说明,这些后端虚拟机均运行 Debian GNU/Linux 9。

控制台

创建后端虚拟机

  1. 转到 Google Cloud Platform Console 中的“虚拟机实例”页面。
    转到“虚拟机实例”页面
  2. 使用以下名称和地区组合重复执行以下步骤,以创建四个虚拟机。
    • 名称:vm-a1,地区:us-west1-a
    • 名称:vm-a2,地区:us-west1-a
    • 名称:vm-c1,地区:us-west1-c
    • 名称:vm-c2,地区:us-west1-c
  3. 点击创建实例
  4. 按照第 2 步中的说明设置名称
  5. 对于区域,选择 us-west1,然后按照第 2 步中的说明选择一个地区。
  6. 启动磁盘部分,确保所选映像为 Debian GNU/Linux 9 Stretch。如有必要,请点击选择更改映像。
  7. 点击管理、安全、磁盘、网络、单独租用并进行以下更改:

    • 点击网络并添加以下网络标记:allow-sshallow-health-check
    • 点击网络接口下的修改按钮并进行以下更改,然后点击完成:
      • 网络lb-network
      • 子网lb-subnet
      • 主要内部 IP:临时(自动)
      • 外部 IP:临时
    • 点击管理。在启动脚本字段中,复制并粘贴以下脚本内容。所有四个虚拟机的脚本内容均相同:

      #! /bin/bash
      apt-get update
      apt-get install apache2 -y
      a2ensite default-ssl
      a2enmod ssl
      vm_hostname="$(curl -H "Metadata-Flavor:Google" \
      http://169.254.169.254/computeMetadata/v1/instance/name)"
      echo "Page served from: $vm_hostname" | \
      tee /var/www/html/index.html
      systemctl restart apache2
      
  8. 点击创建

创建实例组

  1. 转到 Google Cloud Platform Console 中的“实例组”页面。
    转到“实例组”页面
  2. 使用这些组合重复执行以下步骤,以创建两个非托管实例组,每个组包含两个虚拟机。
    • 实例组:ig-a,地区:us-west1-a,虚拟机:vm-a1vm-a2
    • 实例组:ig-c,地区:us-west1-c,虚拟机:vm-c1vm-c2
  3. 点击创建实例组
  4. 按照第 2 步中的说明设置名称
  5. 位置部分选择单地区,为区域选择 us-west1,然后按照第 2 步中的说明选择一个地区。
  6. 组类型部分中,选择非托管实例组。
  7. 对于网络,请输入 lb-network
  8. 对于子网,请输入lb-subnet
  9. 虚拟机实例部分中,添加第 2 步中说明的虚拟机。
  10. 点击创建

gcloud

  1. 使用 [VM-NAME][ZONE] 的下列四种组合运行以下命令四次,创建四个虚拟机。全部四个虚拟机的脚本内容均相同。

    • [VM-NAME]vm-a1[ZONE]us-west1-a
    • [VM-NAME]vm-a2[ZONE]us-west1-a
    • [VM-NAME]vm-c1[ZONE]us-west1-c
    • [VM-NAME]vm-c2[ZONE]us-west1-c
    gcloud compute instances create [VM-NAME] \
        --zone=[ZONE] \
        --image-family=debian-9 \
        --image-project=debian-cloud \
        --tags=allow-ssh,allow-health-check \
        --subnet=lb-subnet \
        --metadata=startup-script='#! /bin/bash
    apt-get update
    apt-get install apache2 -y
    a2ensite default-ssl
    a2enmod ssl
    vm_hostname="$(curl -H "Metadata-Flavor:Google" \
    http://169.254.169.254/computeMetadata/v1/instance/name)"
    echo "Page served from: $vm_hostname" | \
    tee /var/www/html/index.html
    systemctl restart apache2'
    
  2. 在每个地区中创建两个非托管实例组:

    gcloud compute instance-groups unmanaged create ig-a \
        --zone=us-west1-a
    gcloud compute instance-groups unmanaged create ig-c \
        --zone=us-west1-c
    
  3. 将虚拟机添加到相应的实例组中:

    gcloud compute instance-groups unmanaged add-instances ig-a \
        --zone=us-west1-a \
        --instances=vm-a1,vm-a2
    gcloud compute instance-groups unmanaged add-instances ig-c \
        --zone=us-west1-c \
        --instances=vm-c1,vm-c2
    

api

对于四个虚拟机,请使用以下虚拟机名称和地区:

  • [VM-NAME]vm-a1[ZONE]us-west1-a
  • [VM-NAME]vm-a2[ZONE]us-west1-a
  • [VM-NAME]vm-c1[ZONE]us-west1-c
  • [VM-NAME]vm-c2[ZONE]us-west1-c

instances.insert 方法发出四个 POST 请求,以创建四个后端虚拟机。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances
{
  "name": "[VM-NAME]",
  "tags": {
    "items": [
      "allow-health-check",
      "allow-ssh"
    ]
  },
  "machineType": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/machineTypes/n1-standard-1",
  "canIpForward": false,
  "networkInterfaces": [
    {
      "network": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/lb-network",
      "subnetwork": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/subnetworks/lb-subnet",
      "accessConfigs": [
        {
          "type": "ONE_TO_ONE_NAT",
          "name": "external-nat",
          "networkTier": "PREMIUM"
        }
      ]
    }
  ],
  "disks": [
    {
      "type": "PERSISTENT",
      "boot": true,
      "mode": "READ_WRITE",
      "autoDelete": true,
      "deviceName": "[VM-NAME]",
      "initializeParams": {
        "sourceImage": "projects/debian-cloud/global/images/debian-9-stretch-v20190618",
        "diskType": "projects/[PROJECT_ID]/zones/us-west1-a/diskTypes/pd-standard",
        "diskSizeGb": "10"
      }
    }
  ]
  "metadata": {
    "items": [
      {
        "key": "startup-script",
        "value": "#! /bin/bash\napt-get update\napt-get install apache2 -y\na2ensite default-ssl\na2enmod ssl\nvm_hostname=\"$(curl -H \"Metadata-Flavor:Google\" \\\nhttp://169.254.169.254/computeMetadata/v1/instance/name)\"\necho \"Page served from: $vm_hostname\" | \\\ntee /var/www/html/index.html\nsystemctl restart apache2"
      }
    ]
  },
  "scheduling": {
    "preemptible": false
  },
  "deletionProtection": false
}

instanceGroups.insert 方法发出一个 POST 请求,以创建两个实例组。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-a/instanceGroups
{
  "name": "ig-a",
  "network": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/lb-network",
  "subnetwork": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/subnetworks/lb-subnet"
}

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-c/instanceGroups
{
  "name": "ig-c",
  "network": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/lb-network",
  "subnetwork": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/subnetworks/lb-subnet"
}

instanceGroups.addInstances 方法发出一个 POST 请求,为每个实例组添加实例。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-a/instanceGroups/ig-a/addInstances
{
  "instances": [
    {
      "instance": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-a/instances/vm-a1",
      "instance": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-a/instances/vm-a2"
    }
  ]
}

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-c/instanceGroups/ig-c/addInstances
{
  "instances": [
    {
      "instance": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-c/instances/vm-c1",
      "instance": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-c/instances/vm-c2"
    }
  ]
}

创建客户端虚拟机

此示例在后端(服务器)虚拟机所在的同一区域创建一个客户端虚拟机 (vm-client)。该客户端用于验证负载平衡器的配置并演示测试部分中所述的预期行为。

控制台

  1. 转到 Google Cloud Platform Console 中的“虚拟机实例”页面。
    转到“虚拟机实例”页面
  2. 点击创建实例
  3. 名称设置为 vm-client
  4. 地区设置为 us-west1-a
  5. 点击管理、安全、磁盘、网络、单独租用并进行以下更改:
    • 点击网络并将 allow-ssh 添加到网络标记。
    • 点击网络接口下的修改按钮并进行以下更改,然后点击完成:
      • 网络lb-network
      • 子网lb-subnet
      • 主要内部 IP:临时(自动)
      • 外部 IP:临时
  6. 点击创建

gcloud

客户端虚拟机可以位于负载平衡器所在的同一区域的任何地区中,并且可以使用该区域中的任何子网。在此示例中,客户端位于 us-west1-a 地区,并使用与后端虚拟机相同的子网。

gcloud compute instances create vm-client \
    --zone=us-west1-a \
    --image-family=debian-9 \
    --image-project=debian-cloud \
    --tags=allow-ssh \
    --subnet=lb-subnet

api

instances.insert 方法发出 POST 请求。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-a/instances
{
  "name": "vm-client",
  "tags": {
    "items": [
      "allow-ssh"
    ]
  },
  "machineType": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-a/machineTypes/n1-standard-1",
  "canIpForward": false,
  "networkInterfaces": [
    {
      "network": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/lb-network",
      "subnetwork": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/subnetworks/lb-subnet",
      "accessConfigs": [
        {
          "type": "ONE_TO_ONE_NAT",
          "name": "external-nat",
          "networkTier": "PREMIUM"
        }
      ]
    }
  ],
  "disks": [
    {
      "type": "PERSISTENT",
      "boot": true,
      "mode": "READ_WRITE",
      "autoDelete": true,
      "deviceName": "[VM-NAME]",
      "initializeParams": {
        "sourceImage": "projects/debian-cloud/global/images/debian-9-stretch-v20190618",
        "diskType": "projects/[PROJECT_ID]/zones/us-west1-a/diskTypes/pd-standard",
        "diskSizeGb": "10"
      }
    }
  ]
  "scheduling": {
    "preemptible": false
  },
  "deletionProtection": false
}

配置负载平衡器组件

以下步骤配置所有内部 TCP/UDP 负载平衡器组件,从运行状况检查和后端服务开始,然后配置前端组件:

  • 运行状况检查:在此示例中,我们使用仅检查 HTTP 200 (OK) 响应的 HTTP 运行状况检查。如需了解详情,请参阅内部 TCP/UDP 负载平衡概览中的“运行状况检查”部分

  • 后端服务:由于我们需要通过内部负载平衡器传递 HTTP 流量,因此需要使用 TCP,而不是 UDP。

  • 转发规则:本示例创建了一条内部转发规则。

  • 内部 IP 地址:在本示例中,我们在创建转发规则时指定了内部 IP 地址 10.1.2.99

控制台

创建负载平衡器并配置后端服务

  1. 转到 Google Cloud Platform Console 中的“负载平衡”页面。
    转到“负载平衡”页面
  2. 点击创建负载平衡器
  3. TCP 负载平衡下,点击开始配置。
  4. 面向互联网或仅限内部下选择仅在我的虚拟机之间。
  5. 点击继续
  6. 名称设置为 be-ilb
  7. 点击后端配置 并进行以下更改:
    1. 区域us-west1
    2. 网络lb-network
    3. 后端下的新建内容部分,选择 ig-a 实例组,然后点击完成。
    4. 点击添加后端。在显示的新建内容部分,选择 ig-c 实例组,然后再次点击完成
    5. 运行状况检查中,选择另创建一项运行状况检查,输入以下信息,然后点击保存并继续:
      • 名称hc-http-80
      • 协议HTTP
      • 端口80
      • 代理协议NONE
      • 请求路径/
    6. 请先确认后端配置旁边是否有蓝色对勾标记,然后再继续操作。如果没有,请检查此步骤。
  8. 点击前端配置。在新建前端 IP 和端口部分,进行以下更改:
    1. 名称fr-ilb
    2. 子网ilb-subnet
    3. 内部 IP 中,选择保留静态内部 IP 地址,输入以下信息,然后点击保留:
      • 名称ip-ilb
      • 静态 IP 地址:让我选择
      • 自定义 IP 地址10.1.2.99
    4. 端口:选择单个,然后输入 80 作为端口号。
    5. 请先确认前端配置旁边是否有蓝色对勾标记,然后再继续操作。如果没有,请检查此步骤。
  9. 点击检查并最终确定。仔细检查您的设置。
  10. 点击创建

gcloud

  1. 创建一个新的 HTTP 运行状况检查,以测试到端口 80 上的虚拟机的 TCP 连接。

    gcloud compute health-checks create http hc-http-80 \
        --port=80
    
  2. 为 HTTP 流量创建后端服务:

    gcloud compute backend-services create be-ilb \
        --load-balancing-scheme=internal \
        --protocol=tcp \
        --region=us-west1 \
        --health-checks=hc-http-80
    
  3. 将两个实例组添加到后端服务:

    gcloud compute backend-services add-backend be-ilb \
        --region=us-west1 \
        --instance-group=ig-a \
        --instance-group-zone=us-west1-a
    gcloud compute backend-services add-backend be-ilb \
        --region=us-west1 \
        --instance-group=ig-c \
        --instance-group-zone=us-west1-c
    
  4. 为后端服务创建转发规则。创建转发规则时,请指定 10.1.2.99 作为子网中的内部 IP 地址。

    gcloud compute forwarding-rules create fr-ilb \
        --region=us-west1 \
        --load-balancing-scheme=internal \
        --network=lb-network \
        --subnet=lb-subnet \
        --address=10.1.2.99 \
        --ip-protocol=TCP \
        --ports=80 \
        --backend-service=be-ilb \
        --backend-service-region=us-west1
    

api

healthChecks.insert 方法发出 POST 请求,以创建运行状况检查。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/healthChecks
{
  "name": "hc-http-80",
  "type": "HTTP",
  "httpHealthCheck": {
    "port": 80
  }
}

regionBackendServices.insert 方法发出 POST 请求,以创建区域后端服务。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/backendServices
{
  "name": "be-ilb",
  "backends": [
    {
      "group": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-a/instanceGroups/ig-a",
      "balancingMode": "CONNECTION"
    }
    {
      "group": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-c/instanceGroups/ig-c",
      "balancingMode": "CONNECTION"
    }
  ],
  "healthChecks": [
    "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/healthChecks/hc-http-80"
  ],
  "loadBalancingScheme": "INTERNAL",
  "connectionDraining": {
    "drainingTimeoutSec": 0
  }
}

forwardingRules.insert 方法发出 POST 请求,以创建转发规则。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/forwardingRules
{
  "name": "fr-ilb",
  "IPAddress": "10.1.2.99",
  "IPProtocol": "TCP",
  "ports": [
    "80"
  ],
  "loadBalancingScheme": "INTERNAL",
  "subnetwork": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/subnetworks/lb-subnet",
  "network": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/lb-network",
  "backendService": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/backendServices/be-ilb",
  "networkTier": "PREMIUM"
}

测试

这部分中的测试展示了如何验证负载平衡器配置并了解其预期行为。

测试负载平衡

此测试通过单独的客户端虚拟机连接负载平衡器;也就是说,并非使用负载平衡器的后端虚拟机。预期的行为是流量在四个后端虚拟机中分布,因为没有配置会话粘性

  1. 连接到客户端虚拟机实例。

    gcloud compute ssh vm-client --zone=us-west1-a
    
  2. 使用 curl 连接负载平衡器的 IP 地址,通过这种方式向负载平衡器发送 Web 请求。重复该请求,您可以看到响应来自不同的后端虚拟机。根据每个后端虚拟机上 /var/www/html/index.html 的内容,生成响应的虚拟机的名称会显示在 HTML 响应的文本中。预期响应如 Page served from: vm-a1Page served from: vm-a2 等。

    curl http://10.1.2.99
    
    • 如果您为内部转发规则添加服务标签,则可以使用内部 DNS通过其服务名称连接负载平衡器。

      curl http://web-test.fr-ilb.il4.us-west1.lb.[PROJECT_ID].internal
      

对负载平衡器的 IP 地址执行 ping 操作

此测试演示了预期的行为:您无法对负载平衡器的 IP 地址执行 ping 操作。这是因为内部 TCP/UDP 负载平衡器采用虚拟网络编程实现 - 它们不是单独的设备

  1. 连接到客户端虚拟机实例。

    gcloud compute ssh vm-client --zone=us-west1-a
    
  2. 尝试对负载平衡器的 IP 地址执行 ping 操作。请注意,在此示例中,您没有收到响应,并且 ping 命令在 10 秒后超时。

    timeout 10 ping 10.1.2.99
    

从负载平衡虚拟机发送请求

此测试表明,从任何后端虚拟机(经过负载平衡的服务器虚拟机)发送到负载平衡器的请求始终由发出该请求的虚拟机应答。

内部 TCP/UDP 负载平衡是通过虚拟网络编程和访客操作系统中的虚拟机配置实现的。在 Linux 虚拟机上,Linux 访客环境通过在访客操作系统路由表中安装路由来执行本地配置。由于存在此本地路由,传入负载平衡器的 IP 地址的流量会保留在负载平衡虚拟机上。(此本地路由与 VPC 网络中的路由不同。)

  1. 连接到后端虚拟机,例如 vm-a1

    gcloud compute ssh vm-a1 --zone=us-west1-a
    
  2. 使用 curl 向负载平衡器发出 Web 请求(通过 IP 地址或服务名称)。重复该请求,并注意响应是从发出请求的后端虚拟机发送的。从 vm-a1 进行测试时的预期响应始终为 Page served from: vm-a1

    curl http://10.1.2.99
    
  3. 检查本地路由表,查找与负载平衡器本身的 IP 地址 10.1.2.99 匹配的目标。此路由是内部 TCP/UDP 负载平衡的必要部分,但也说明了由负载平衡器的后端虚拟机发出的请求始终由同一虚拟机响应的原因。

    ip route show table local | grep 10.1.2.99
    

其他配置选项

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

配置托管实例组

示例配置创建了两个非托管实例组。您也可以将托管实例组(包括地区和区域托管实例组)用作内部 TCP/UDP 负载平衡的后端。

托管实例组要求您创建实例模板。此过程演示了如何使用单个区域托管实例组替换示例中的两个非托管地区实例组。区域托管实例组会自动在区域内的多个地区中创建虚拟机,以便更轻松地在地区之间分布生产流量。

托管实例组还支持自动扩缩自动修复。如果您将自动扩缩和内部 TCP/UDP 负载平衡结合使用,则无法根据负载平衡进行扩缩。

此过程展示了如何修改示例内部 TCP/UDP 负载平衡器的后端服务,以使其使用区域托管实例组。

控制台

实例模板

  1. 转到 Google Cloud Platform Console 中的“虚拟机实例模板”页面。
    转到“虚拟机实例模板”页面
  2. 点击创建实例模板
  3. 名称设置为 template-vm-ilb
  4. 选择机器类型
  5. 对于启动磁盘,请点击更改,选择“Debian GNU/Linux 9 Stretch”,然后点击选择。
  6. 点击管理、安全、磁盘、网络、单独租用
    • 点击网络并进行以下更改:
      • 网络lb-network
      • 子网lb-subnet
      • 网络标记allow-sshallow-health-check
    • 点击管理。在启动脚本字段中,复制并粘贴以下脚本内容:
      #! /bin/bash
      apt-get update
      apt-get install apache2 -y
      a2ensite default-ssl
      a2enmod ssl
      vm_hostname="$(curl -H "Metadata-Flavor:Google" 
      http://169.254.169.254/computeMetadata/v1/instance/name)" echo "Page served from: $vm_hostname" |
      tee /var/www/html/index.html systemctl restart apache2
  7. 点击创建

托管实例组

  1. 转到 Google Cloud Platform Console 中的“虚拟机实例”页面。
    转到“虚拟机实例组”页面
  2. 点击创建实例组
  3. 名称设置为 ig-ilb
  4. 对于位置,选择多地区,并将区域 设置为 us-west1
  5. 实例模板设置为 template-vm-ilb
  6. (可选)配置自动扩缩。您无法根据 HTTP 负载平衡使用情况来自动扩缩实例组,因为实例组是内部 TCP/UDP 负载平衡的后端。
  7. 实例数下限设置为 1,将实例数上限设置为 6
  8. (可选)配置自动修复。如果您配置了自动修复功能,请对内部 TCP/UDP 负载平衡器使用与后端服务相同的运行状况检查。在此示例中,请使用 hc-http-80
  9. 点击创建

gcloud

  1. 创建实例模板。您也可以为要使用的映像模版设置其他参数,如机器类型

    gcloud compute instance-templates create template-vm-ilb \
        --image-family=debian-9 \
        --image-project=debian-cloud \
        --tags=allow-ssh,allow-health-check \
        --subnet=lb-subnet \
        --region=us-west1 \
        --network=lb-network \
        --metadata=startup-script='#! /bin/bash
    apt-get update
    apt-get install apache2 -y
    a2ensite default-ssl
    a2enmod ssl
    vm_hostname="$(curl -H "Metadata-Flavor:Google" \
    http://169.254.169.254/computeMetadata/v1/instance/name)"
    echo "Page served from: $vm_hostname" | \
    tee /var/www/html/index.html
    systemctl restart apache2'
    
  2. 使用模板创建一个区域托管实例组:

    gcloud compute instance-groups managed create ig-ilb \
        --template=template-vm-ilb \
        --region=us-west1 \
        --size=6
    
  3. 将区域托管实例组作为后端添加到您已创建的后端服务

    gcloud compute backend-services add-backend be-ilb \
        --region=us-west1 \
        --instance-group=ig-ilb \
        --instance-group-region=us-west1
    
  4. 断开两个非托管(地区)实例组与后端服务的连接:

    gcloud compute backend-services remove-backend be-ilb \
        --region=us-west1 \
        --instance-group=ig-a \
        --instance-group-zone=us-west1-a
    gcloud compute backend-services remove-backend be-ilb \
        --region=us-west1 \
        --instance-group=ig-c \
        --instance-group-zone=us-west1-c
    

从后端虚拟机中移除外部 IP 地址

当您创建后端虚拟机时,系统会为每个虚拟机分配一个临时外部 IP 地址,以便其通过启动脚本下载 Apache。由于后端虚拟机仅供内部负载平衡器使用,因此您可以移除其外部 IP 地址。移除外部 IP 地址可防止后端虚拟机直接访问互联网。

控制台

  1. 转到 Google Cloud Platform Console 中的“虚拟机实例”页面。
    转到“虚拟机实例”页面
  2. 对每个后端虚拟机重复执行以下步骤。
  3. 点击后端虚拟机的名称(例如 vm-a1)以查看“虚拟机实例详情”页面
  4. 点击修改
  5. 网络接口部分,点击修改按钮。
  6. 外部 IP 弹出式窗口中选择无,然后点击完成。
  7. 点击保存

gcloud

  1. 如需查询实例的地区(例如,如果您使用的是区域托管实例组),请为每个实例运行以下命令以确定其所在地区。将 [SERVER-VM] 替换为要查询的虚拟机的名称。

    gcloud compute instances list --filter="name=[SERVER-VM]"
    
  2. 对每个后端虚拟机重复执行以下步骤。将 [SERVER-VM] 替换为虚拟机的名称,并将 [ZONE] 替换为虚拟机所在的地区。

    gcloud compute instances delete-access-config [SERVER-VM] \
        --zone=[ZONE] \
        --access-config-name=external-nat
    

api

针对每个后端虚拟机向 instances.deleteAccessConfig 方法发出 POST 请求,将 vm-a1 替换为虚拟机的名称,然后将 us-west1-a 替换为虚拟机所在的地区。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-west1-a/instances/v1-a1/deleteAccessConfig?accessConfig=external-nat&networkInterface=None

在多个端口上接收流量

内部转发规则是用于控制传入流量的端口的组件。此过程说明如何将端口 80 的转发规则替换为接收端口 80 和 443 上的流量的转发规则。在创建后端虚拟机时,安装和配置 Apache 的启动脚本还会将其配置为在端口 443 上传送 HTTPS 流量。您必须替换转发规则,因为 GCP 不支持更新转发规则。

gcloud

  1. 删除现有的转发规则 fr-ilb

    gcloud compute forwarding-rules delete fr-ilb \
        --region=us-west1
    
  2. 为端口 80 和 443 创建一个具有相同名称的替换转发规则。此规则的其他参数,包括 IP 地址和后端服务,都与之前相同。

    gcloud compute forwarding-rules create fr-ilb \
        --region=us-west1 \
        --load-balancing-scheme=internal \
        --network=lb-network \
        --subnet=lb-subnet \
        --address=10.1.2.99 \
        --ip-protocol=TCP \
        --ports=80,443 \
        --backend-service=be-ilb \
        --backend-service-region=us-west1
    
  3. 连接到客户端虚拟机实例并测试 HTTP 和 HTTPS 连接。

    • 连接到客户端虚拟机:

      gcloud compute ssh vm-client --zone=us-west1-a
      
    • 测试 HTTP 连接:

      curl http://10.1.2.99
      
    • 测试 HTTPS 连接。--insecure 标志是必需的,因为示例设置中的 Apache 服务器配置使用自签名证书。

      curl https://10.1.2.99 --insecure
      
    • 测试结果显示,HTTP 请求(在端口 80 上)和 HTTPS 请求(在端口 443 上)由所有后端虚拟机进行处理。

使用会话粘性

示例配置创建的后端服务没有会话粘性。

此过程说明如何更新示例内部 TCP/UDP 负载平衡器的后端服务,使其根据客户端 IP 地址使用会话粘性。

负载平衡器根据从客户端的 IP 地址和负载平衡器的 IP 地址(内部转发规则的内部 IP 地址)创建的哈希,将特定客户端的请求定向到同一个后端虚拟机。

控制台

  1. 转到 Google Cloud Platform Console 中的“负载平衡”页面。
    转到“负载平衡”页面
  2. 点击 be-ilb(您为此示例创建的后端服务的名称),然后点击修改。
  3. “修改内部负载平衡器”页面,点击后端配置
  4. 会话粘性弹出式菜单中选择客户端 IP。
  5. 点击更新

gcloud

使用以下 gcloud 命令更新 be-ilb 后端服务,指定客户端 IP 会话粘性:

gcloud compute backend-services update be-ilb \
    --session-affinity CLIENT_IP

api

regionBackendServices/patch 方法发出 PATCH 请求。

PATCH https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/backendServices/be-ilb
{
  "sessionAffinity": "CLIENT_IP"
}

如需了解如何使用会话粘性影响流量分配以及每个选项的说明,请参阅流量分配

在其他子网中创建转发规则

此过程会在另一个子网中创建第二个 IP 地址和转发规则,以证明您可以为一个内部 TCP/UDP 负载平衡器创建多个转发规则。转发规则的区域必须与后端服务的区域一致。

根据防火墙规则,区域中任何子网中的客户端都可以连接任一内部 TCP/UDP 负载平衡器 IP 地址。

  1. us-west1 区域的 lb-network 网络中创建第二个子网:

    gcloud compute networks subnets create second-subnet \
        --network=lb-network \
        --range=10.5.6.0/24 \
        --region=us-west1
    
  2. 为端口 80 和 443 创建第二个转发规则。此规则的其他参数,包括 IP 地址和后端服务,均与主要转发规则 fr-ilb 相同。

    gcloud compute forwarding-rules create fr-ilb-2 \
        --region=us-west1 \
        --load-balancing-scheme=internal \
        --network=lb-network \
        --subnet=second-subnet \
        --address=10.5.6.99 \
        --ip-protocol=TCP \
        --ports=80,443 \
        --backend-service=be-ilb \
        --backend-service-region=us-west1
    
  3. 连接到客户端虚拟机实例并测试与 IP 地址的 HTTP 和 HTTPS 连接。

    • 连接到客户端虚拟机:
    gcloud compute ssh vm-client --zone=us-west1-a
    
    • 测试与 IP 地址的 HTTP 连接:
    curl http://10.1.2.99
    curl http://10.5.6.99
    
    • 测试 HTTPS 连接。必须使用 --insecure,因为示例设置中的 Apache 服务器配置使用自签名证书。
    curl https://10.1.2.99 --insecure
    curl https://10.5.6.99 --insecure
    
    • 测试结果显示,无论使用何种协议(HTTP 或 HTTPS)或 IP 地址,请求均由所有后端虚拟机进行处理。

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
负载平衡