外部 HTTPS 负载平衡器及高级流量管理 (Envoy) Codelab

1. 简介

欢迎学习“外部 HTTPS 负载平衡器与高级流量管理 (Envoy)”Codelab!

最新版本的 HTTP(S) 外部负载平衡器支持高级流量管理功能,包含我们现有传统版全球外部 HTTP(S) 负载平衡器的所有功能,但高级流量管理功能还在不断增加。其中一些功能是我们的负载平衡器新推出的功能,还有一些功能则会在现有功能的基础上提供更强大的功能。这些功能的部分功能包括:

  • 加权流量分配
  • 请求镜像
  • 离群值检测
  • 请求重试
  • 故障注入
  • 其他后端会话亲和性选项
  • 其他标头转换选项
  • 跨源资源共享 (CORS)
  • 新的负载均衡算法

学习内容

  • 如何设置代管式实例组以及关联的 VPC 和防火墙规则
  • 如何使用新负载平衡器的高级流量管理功能
  • 如何验证高级流量管理功能是否按预期运行。

所需条件

  • 网络基本知识和 HTTP 知识
  • Unix/Linux 命令行基础知识

Codelab 拓扑和应用场景

dd8bd5e8e1341878.png

图 1 - HTTP 负载平衡器路由拓扑

在此 Codelab 中,您将设置三个代管式实例组,分别位于东部、西部和中部。您将创建一个全球外部 https 负载平衡器。负载平衡器将使用基于 Envoy 的负载平衡器支持的高级功能列表中的多项功能。部署后,您将生成一些模拟负载,并验证您设置的配置是否正常运行。

2. 设置和要求

自定进度的环境设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串,您可以随时对其进行更新。
  • 项目 ID 在所有 Google Cloud 项目中必须是唯一的,并且不可变(一经设置便无法更改)。Cloud Console 会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(它通常标识为 PROJECT_ID),因此如果您不喜欢某个 ID,请再生成一个随机 ID,还可以尝试自己创建一个,并确认是否可用。然后,项目创建后,ID 会处于“冻结”状态。
  • 第三个值是一些 API 使用的项目编号。如需详细了解所有这三个值,请参阅文档
  1. 接下来,您需要在 Cloud Console 中启用结算功能,才能使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。要关闭资源以避免产生超出本教程范围的费用,请按照此 Codelab 末尾提供的任何“清理”说明操作。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

启动 Cloud Shell

虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。

在 GCP 控制台中,点击右上角工具栏上的 Cloud Shell 图标:

55efc1aaa7a4d3ad.png

预配和连接到环境应该只需要片刻时间。完成后,您应该会看到如下内容:

7ffe5cbb04455448.png

这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。只需一个浏览器,即可完成本实验中的所有工作。

准备工作

在 Cloud Shell 中,确保已设置项目 ID

gcloud config list project

gcloud config set project [您的项目名称]

PROJECT_ID=[YOUR-PROJECT-NAME]

echo $PROJECT_ID

启用 API

启用所有必要的服务

gcloud services enable compute.googleapis.com
gcloud services enable logging.googleapis.com
gcloud services enable monitoring.googleapis.com

3. 创建 VPC 网络

创建 VPC 网络

通过 Cloud Shell

gcloud compute networks create httplbs --subnet-mode=auto

输出

Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/httplbs].
NAME: httplbs
SUBNET_MODE: AUTO
BGP_ROUTING_MODE: REGIONAL
IPV4_RANGE:
GATEWAY_IPV4:

创建 VPC 防火墙规则

创建 VPC 后,接下来您需要创建防火墙规则。该防火墙规则将允许所有 IP 通过端口 80 访问测试应用网站的外部 IP,以处理 http 流量。

通过 Cloud Shell

gcloud compute firewall-rules create httplb-allow-http-rule \
--allow tcp:80 \
--network httplbs \
--source-ranges 0.0.0.0/0 \
--priority 700

输出

Creating firewall...working..Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls/httplb-allow-http-rule].
Creating firewall...done.
NAME: httplb-allow-http-rule
NETWORK: httplbs
DIRECTION: INGRESS
PRIORITY: 700
ALLOW: tcp:80
DENY:
DISABLED: False

4. 设置代管式实例组

您需要设置包含 HTTP 负载平衡器使用的后端资源的模式的代管式实例组。首先,我们将创建实例模板,用于定义要为每个区域创建的虚拟机的配置。接下来,对于每个区域中的后端,我们将创建一个引用实例模板的托管式实例组。

代管式实例组的范围可以是可用区级或区域级。在本实验练习中,我们将创建三个区域级代管式实例组,一个在 us-east1,一个在 us-west1,一个在 us-central1。

在此部分中,您可以看到一个在创建实例时将引用的预先创建的启动脚本。此启动脚本会安装并启用 Web 服务器功能,我们将使用这些功能来模拟 Web 应用。请随意探索此脚本。

创建东方、西方和中央实例模板

第一步是创建 us-east-1 实例模板。

通过 Cloud Shell

gcloud compute instance-templates create us-east1-template \
   --region=us-east1 \
   --network=httplbs \
   --tags=http-server, \
   --image-family=debian-9 \
   --image-project=debian-cloud \
   --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'

输出

Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/instanceTemplates/us-east1-template].
NAME: us-east1-template
MACHINE_TYPE: n1-standard-1
PREEMPTIBLE:
CREATION_TIMESTAMP: 2021-11-11T11:02:37.511-08:00

下一步是创建 us-west-1 实例模板。

通过 Cloud Shell

gcloud compute instance-templates create us-west1-template \
   --region=us-west1 \
   --network=httplbs \
   --tags=http-server, \
   --image-family=debian-9 \
   --image-project=debian-cloud \
   --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'

输出

Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/instanceTemplates/us-west1-template].
NAME: us-west1-template
MACHINE_TYPE: n1-standard-1
PREEMPTIBLE:
CREATION_TIMESTAMP: 2021-11-11T11:03:08.577-08:00

下一步是创建 us-central-1 实例模板。

通过 Cloud Shell

gcloud compute instance-templates create us-central1-template \
   --region=us-central1 \
   --network=httplbs \
   --tags=http-server, \
   --image-family=debian-9 \
   --image-project=debian-cloud \
   --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'

输出

Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/instanceTemplates/us-central1-template].
NAME: us-central1-template
MACHINE_TYPE: n1-standard-1
PREEMPTIBLE:
CREATION_TIMESTAMP: 2021-11-11T11:03:44.179-08:00

现在,您可以使用以下 gcloud 命令验证实例模板已成功创建:

通过 Cloud Shell

gcloud compute instance-templates list

输出

NAME                  MACHINE_TYPE   PREEMPTIBLE  CREATION_TIMESTAMP
us-central1-template   n1-standard-1         2021-11-09T09:25:37.263-08:00
us-east1-template      n1-standard-1         2021-11-09T09:24:35.275-08:00
us-west1-template      n1-standard-1         2021-11-09T09:25:08.016-08:00

创建东方、西方和集中式代管式实例组

现在,我们必须基于之前创建的实例模板创建一个托管式实例组。

通过 Cloud Shell

gcloud compute instance-groups managed create us-east1-mig \
--base-instance-name=us-east1-mig \
--size=1 \
--template=us-east1-template \
--zone=us-east1-b 

输出

Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/us-east1-b/instanceGroupManagers/us-east1-mig].
NAME: us-east1-mig
LOCATION: us-east1-b
SCOPE: zone
BASE_INSTANCE_NAME: us-east1-mig
SIZE: 0
TARGET_SIZE: 1
INSTANCE_TEMPLATE: us-east1-template
AUTOSCALED: no

通过 Cloud Shell

gcloud compute instance-groups managed create us-west1-mig \
--base-instance-name=us-west1-mig \
--size=1 \
--template=us-west1-template \
--zone=us-west1-a  

输出

Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/us-west1-a/instanceGroupManagers/us-west1-mig].
NAME: us-west1-mig
LOCATION: us-west1-a
SCOPE: zone
BASE_INSTANCE_NAME: us-west1-mig
SIZE: 0
TARGET_SIZE: 1
INSTANCE_TEMPLATE: us-west1-template
AUTOSCALED: no

通过 Cloud Shell

gcloud compute instance-groups managed create us-central1-mig \
--base-instance-name=us-central1-mig \
--size=1 \
--template=us-central1-template \
--zone=us-central1-a 

输出

Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/us-central1-a/instanceGroupManagers/us-central1-mig].
NAME: us-central1-mig
LOCATION: us-central1-a
SCOPE: zone
BASE_INSTANCE_NAME: us-central1-mig
SIZE: 0
TARGET_SIZE: 1
INSTANCE_TEMPLATE: us-central1-template
AUTOSCALED: no

我们可以使用以下 gcloud 命令验证实例组是否已成功创建:

通过 Cloud Shell

gcloud compute instance-groups list

输出

NAME                  LOCATION      SCOPE   NETWORK         MANAGED INSTANCES
us-central1-mig       us-central1   zone    httplbs          Yes      1
us-west1-mig          us-west1      zone    httplbs          Yes      1
us-east1-mig          us-east1      zone    httplbs          Yes      1

验证 Web 服务器功能

每个实例都配置为使用简单的 PHP 脚本运行 Apache 网络服务器,该脚本可呈现以下内容:

c87ca81d3125ac61.png

为确保您的 Web 服务器正常运行,请前往 Compute Engine ->虚拟机实例确保已根据实例组定义创建新实例(例如 us-east1-mig-xxx)。

现在,请在浏览器中向其发出网络请求,以确保网络服务器正在运行(启动过程可能需要一分钟时间)。在 Compute Engine 下的“虚拟机实例”页面上,选择您的实例组创建的实例,然后点击其外部(公共)IP。

或者,在您的浏览器中,转到 http://<IP_Address>

5. 设置负载平衡器

创建健康检查

首先,我们必须创建基本的健康检查,以确保我们的服务成功启动并运行。我们将创建基本的健康检查,还有许多更高级的自定义可供使用。

通过 Cloud Shell

gcloud compute health-checks create http http-basic-check \
    --port 80

预留外部 IP 地址

对于此步骤,您需要预留一个全局可用的静态 IP 地址,该地址稍后将附加到负载平衡器。

通过 Cloud Shell

gcloud compute addresses create lb-ipv4-2 \
    --ip-version=IPV4 \
    --global

请务必记下预留的 IP 地址。

gcloud compute addresses describe lb-ipv4-2 \
    --format="get(address)" \
    --global

创建后端服务

现在,我们必须为之前创建的每个托管式实例组创建一个后端服务。分别为东部、西部和中部地区。

为东代管式实例组创建后端服务。

通过 Cloud Shell

gcloud compute backend-services create east-backend-service \
    --load-balancing-scheme=EXTERNAL_MANAGED \
    --protocol=HTTP \
    --port-name=http \
    --health-checks=http-basic-check \
    --global

为 West 托管式实例组创建后端服务。

通过 Cloud Shell

gcloud compute backend-services create west-backend-service \
    --load-balancing-scheme=EXTERNAL_MANAGED \
    --protocol=HTTP \
    --port-name=http \
    --health-checks=http-basic-check \
    --global

为中央代管式实例组创建后端服务。

通过 Cloud Shell

gcloud compute backend-services create central-backend-service \
    --load-balancing-scheme=EXTERNAL_MANAGED \
    --protocol=HTTP \
    --port-name=http \
    --health-checks=http-basic-check \
    --global

将 MIG 添加到后端服务

现在,我们已为每个应用集群创建了相应的后端服务,现在必须将之前创建的代管式实例组添加到每个后端服务。

将东 MIG 添加到后端服务。

通过 Cloud Shell

gcloud compute backend-services add-backend east-backend-service \
    --balancing-mode='UTILIZATION' \
    --instance-group=us-east1-mig \
    --instance-group-zone=us-east1-b \
    --global

将 West MIG 添加到后端服务。

通过 Cloud Shell

gcloud compute backend-services add-backend west-backend-service \
    --balancing-mode='UTILIZATION' \
    --instance-group=us-west1-mig \
    --instance-group-zone=us-west1-a \
    --global

将中央 MIG 添加到后端服务。

通过 Cloud Shell

gcloud compute backend-services add-backend central-backend-service \
    --balancing-mode='UTILIZATION' \
    --instance-group=us-central1-mig \
    --instance-group-zone=us-central1-a \
    --global

创建网址映射

网址映射是本实验的高级流量管理功能。我们必须创建一个包含配置的 .yaml 文件。在 .yaml 文件中,我们已在 /roundrobbin 上创建了前缀匹配,因此只有与 /roundrobbin 匹配的流量才会受这些配置的影响。我们已指定,50% 的流量应流向 east-backend-service,50% 的流量应流向 west-backend-service。此外,我们还添加了一个响应标头值 {test},该值将出现在所有响应中。最后,我们添加了所有流量都应镜像到 central-backend-service。系统会复制流量并发送到此处,仅用于测试目的。

将该示例保存为机器上的 .yaml 文件。

defaultService: https://www.googleapis.com/compute/v1/projects/[project_id]/global/backendServices/east-backend-service
kind: compute #urlMap
name: web-map-http
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
pathMatchers:
- defaultService: https://www.googleapis.com/compute/v1/projects/[project_id]/global/backendServices/east-backend-service
  name: matcher1
  routeRules:
  - matchRules:
    - prefixMatch: /roundrobbin
    priority: 2
    headerAction:
        responseHeadersToAdd:
          - headerName: test
            headerValue: value
            replace: True
    routeAction:
        weightedBackendServices:
        - backendService: https://www.googleapis.com/compute/v1/projects/[project_id]/global/backendServices/east-backend-service
          weight: 50
        - backendService: https://www.googleapis.com/compute/v1/projects/[project_id]/global/backendServices/west-backend-service
          weight: 50
        retryPolicy:
            retryConditions: ['502', '504']
            numRetries: 3
            perTryTimeout:
                seconds: 1
                nanos: 50
        requestMirrorPolicy:
          backendService: https://www.googleapis.com/compute/v1/projects/[project_id]/global/backendServices/central-backend-service

创建从计算机导入文档的网址映射。请注意,源路径因保存 .yaml 文件的位置而异。

通过 Cloud Shell

gcloud compute url-maps import web-map-http \
   --source /Users/[USERNAME]/Documents/Codelab/lbconfig.yaml \
   --global

创建 HTTP 前端

创建负载平衡器的最后一步是创建前端。此操作会将您之前预留的 IP 地址映射到您创建的负载平衡器网址映射。

通过 Cloud Shell

gcloud compute target-http-proxies create http-lb-proxy-adv \
    --url-map=web-map-http

接下来,您需要创建一条全局转发规则,将之前预留的 IP 地址映射到 HTTP 代理。

通过 Cloud Shell

gcloud compute forwarding-rules create http-content-rule \
    --load-balancing-scheme EXTERNAL_MANAGED \
    --address=lb-ipv4-2 \
    --global \
    --target-http-proxy=http-lb-proxy-adv \
    --ports=80

6. 验证高级路况功能是否正常运行

为了验证所实现的流量分配功能能否正常运行,您需要生成一些负载。为此,我们将创建一个新的虚拟机来模拟负载。

创建允许 SSH 防火墙规则

为了通过 SSH 连接到我们将从中生成流量的虚拟机,您首先需要创建允许 SSH 流量进入该虚拟机的防火墙规则。

通过 Cloud Shell

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

输出

NAME          NETWORK  DIRECTION  PRIORITY  ALLOW   DENY  DISABLED
fw-allow-ssh  httplbs  INGRESS    1000      tcp:22        False

创建 Siege-vm

现在,您将创建将用于生成负载的 siege-vm

通过 Cloud Shell

gcloud compute instances create siege-vm \
    --network=httplbs \
    --zone=us-east4-c \
    --machine-type=e2-medium \
    --tags=allow-ssh,http-server \
    --metadata=startup-script='sudo apt-get -y install siege'

输出

NAME     ZONE        MACHINE_TYPE INTERNAL_IP  EXTERNAL_IP    STATUS
siege-vm us-east4-c  e2-medium    10.150.0.3   34.85.218.119  RUNNING

接下来,您可以通过 SSH 连接到您创建的虚拟机。创建完成后,点击 SSH 以启动一个终端并进行连接。

连接后,运行以下命令以生成负载。使用您之前为外部 HTTP 负载平衡器预留的 IP 地址。

通过 Cloud Shell

siege -c 250 http://$lb-ipv4-2/roundrobbin

输出

New configuration template added to /home/cloudcurriculumdeveloper/.siege
Run siege -C to view the current settings in that file
[alert] Zip encoding disabled; siege requires zlib support to enable it: No such file or directory
** SIEGE 4.0.2
** Preparing 250 concurrent users for battle.
The server is now under siege...

检查负载分布

既然 Siege 正在运行,现在是时候检查流量是否均匀分配给了东西代管式实例组,此外,您还可以检查流量镜像是否工作正常,以及流量是否正在发送到中央代管式实例组。

在 Cloud 控制台的导航菜单中,点击“网络服务 >”负载均衡。选择负载平衡器 web-map-http。转到“监控”标签页,您可以看到下面的图表。

f4d6803db44be253.png

您可以实时查看到此 MIG 的流量分配情况。由于您配置了 50/50 轮循分配比例,流量将被均分。

如需检查您创建的流量镜像政策是否有效,您需要检查中央后端服务代管式实例组的利用率。为此,请前往 Compute Engine、Compute Engine、实例组,然后选择 us-central1-mig。接下来,前往“监控”标签页。

cf25e44d511529e7.png

您将看到填充的图表,说明流量已镜像到此代管式实例组。

阻止重围

现在,您已经证明了高级流量拆分可以正常工作,是时候阻止攻击了。为此,请返回 siege-vm 的 SSH 终端,然后按 CTRL+C 停止运行 siege。

验证发送的响应标头

在清理之前,您可以快速验证 HTTP 负载平衡器正在发送相应的响应标头。您已将其配置为发送包含内容值的标头测试。从 Cloud Shell 运行 curl 命令将得到预期响应。

通过 Cloud Shell

curl -svo /dev/null http://lb-ipv4-2/roundrobbin

输出

*   Trying lb-ipv4-2..
* TCP_NODELAY set
* Connected to  lb-ipv4-2 ( lb-ipv4-2) port 80 (#0)
> GET /roundrobbin HTTP/1.1
> Host:  lb-ipv4-2
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 404 Not Found
< date: Wed, 10 Nov 2021 17:05:27 GMT
< server: envoy
< Content-Length: 273
< content-type: text/html; charset=iso-8859-1
< via: 1.1 google
< test: value
<
{ [273 bytes data]
* Connection #0 to host 34.149.2.26 left intact
* Closing connection 0

7. 实验清理

现在我们已经完成了实验室环境的搭建,接下来该清理环境了。请运行以下命令以删除测试环境。

通过 Cloud Shell

gcloud compute instances delete siege-vm --zone=us-east4-c

gcloud compute forwarding-rules delete http-content-rule --global
gcloud compute target-http-proxies delete http-lb-proxy-adv
gcloud compute url-maps delete web-map-http
gcloud compute backend-services delete east-backend-service --global
gcloud compute backend-services delete west-backend-service --global
gcloud compute backend-services delete central-backend-service --global

gcloud compute addresses delete lb-ipv4-2 --global
gcloud compute health-checks delete http-basic-check 

gcloud compute instance-groups managed delete us-east1-mig --zone us-east1-b
gcloud compute instance-groups managed delete us-west1-mig --zone us-west1-a
gcloud compute instance-groups managed delete us-central1-mig --zone us-central1-a

gcloud compute instance-templates delete "us-east1-template" 
gcloud compute instance-templates delete "us-west1-template" 
gcloud compute instance-templates delete "us-central1-template" 

gcloud compute firewall-rules delete httplb-allow-http-rule
gcloud compute firewall-rules delete fw-allow-ssh

gcloud compute networks delete httplbs 

8. 恭喜!

您已完成“外部 HTTPS 负载平衡器与高级流量管理 (Envoy)”Codelab!

所学内容

  • 如何设置代管式实例组以及关联的 VPC 和防火墙规则
  • 如何使用新负载平衡器的高级流量管理功能
  • 如何验证高级流量管理功能是否按预期运行。

后续步骤

  • 试用一些其他高级路由功能,例如网址重写、添加 CORS 标头等等 ( link)