通过独立区域级 NEG 实现容器原生负载均衡机制


本页面介绍了如何在 Google Kubernetes Engine (GKE) VPC 原生集群中创建由可用区 GCE_VM_IP_PORT 网络端点组 (NEG) 提供支持的 Kubernetes Service。

如需了解容器原生负载均衡的优势、要求和限制,请参阅容器原生负载均衡

概览

NEG 表示一组端点。GKE 支持 GCE_VM_IP_PORT 类型的独立 NEG。GCE_VM_IP_PORT NEG 支持使用虚拟机主要内部 IP 地址或其某一别名 IP 范围内的 IP 地址的端点。

在使用独立 NEG 的 GKE VPC 原生集群的上下文中,每个端点都是一个 Pod IP 地址和目标端口。Pod IP 地址源自节点的 Pod 的别名 IP 地址范围,该范围来自集群的 Pod 的子网次要 IP 地址范围

GKE 提供一个 NEG 控制器来管理 GCE_VM_IP_PORT NEG 的成员资格。您可以将它创建的 NEG 作为后端添加到您在 GKE API 之外配置的负载均衡器的后端服务。

下图描述了 Kubernetes API 对象与 Compute Engine 对象之间的对应关系。

Kubernetes Service 对应于 Compute Engine 网络端点组,而 Kubernetes Pod 则对应于 Compute Engine 网络端点。控制平面的 NEG 控制器组件负责管理这些对应关系。

使用 NEG 的 Ingress

NEG 与 GKE Ingress 搭配使用时,Ingress 控制器会协助创建负载均衡器的所有方面。这包括创建虚拟 IP 地址、转发规则、健康检查、防火墙规则等等。

建议借助 Ingress 来使用容器原生负载均衡,因为它的许多功能都可简化 NEG 的管理。如果 Ingress 管理的 NEG 不符合您的应用场景,则可以选择使用独立 NEG。

独立 NEG

如果没有使用由 Ingress 预配的负载均衡器来部署 NEG ,则会被视为独立 NEG。独立 NEG 通过 NEG 控制器部署和管理,但转发规则、健康检查和其他负载均衡对象都需要手动部署。

独立 NEG 不会与已启用 Ingress 的容器原生负载均衡发生冲突。

下图展示了负载均衡对象在每种场景下的部署方式差异:

使用独立 NEG 以及 Ingress 托管的 NEG 时,GKE 控制平面上的 NEG 控制器负责管理 NEG 和网络端点对象。使用独立 NEG 时,其他所有组件都由用户管理,如前面几段内容所述。

防止泄露 NEG

使用独立 NEG 时,您需要负责管理 NEG 的生命周期以及构成负载均衡器的资源。您可能会通过以下方式泄露 NEG:

  • 删除 GKE 服务时,如果后端服务仍引用 NEG,则不会对关联的 NEG 进行垃圾回收。从后端服务解引用 NEG,以便能够删除 NEG。
  • 删除集群时,独立 NEG 不会被删除。

独立 NEG 的使用场景

独立 NEG 有多种关键用途。独立 NEG 非常灵活。 这与 Ingress(搭配或不搭配 NEG)形成了对比,Ingress 定义了一组经过精选的特定负载均衡对象,目的是方便使用。

独立 NEG 的应用场景包括:

容器和虚拟机的异构服务

NEG 可以同时包含虚拟机和容器 IP 地址。这意味着单个虚拟 IP 地址可指向同时包含 Kubernetes 和非 Kubernetes 工作负载的后端。这也可用于将现有工作负载迁移到 GKE 集群。

独立 NEG 可以指向虚拟机 IP,从而可以手动将负载均衡器配置为指向由同一服务 VIP 的虚拟机和容器组成的后端。

自定义 Ingress 控制器

您可以使用自定义 Ingress 控制器(或者不使用 Ingress 控制器)来配置针对独立 NEG 的负载均衡器。

将 Cloud Service Mesh 与 GKE 搭配使用

您可以将 Cloud Service Mesh 与 GKE 搭配使用。Cloud Service Mesh 使用独立 NEG 为托管式服务网格提供容器原生负载均衡。

将外部代理网络负载均衡器与 GKE 搭配使用

您可以使用独立 NEG,通过 Kubernetes/GKE 不提供原生支持的外部代理网络负载均衡器直接均衡容器负载。

Pod 就绪性

就绪性门控是 Kubernetes 的一项扩展功能,能够向 PodStatus 注入额外的反馈或信号,以允许 Pod 转换为就绪状态。NEG 控制器管理着自定义就绪性门控,以确保从 Compute Engine 负载均衡器到 Pod 的整条网络路径能正常工作。容器原生负载均衡中介绍了 GKE 内的 Pod 就绪性门控。

使用 NEG 的 Ingress 代表负载均衡器部署和管理 Compute Engine 健康检查。不过,独立 NEG 不会对 Compute Engine 健康检查做任何假设,因为它们预期会单独进行部署和管理。Compute Engine 健康检查应始终与负载均衡器一起配置,以防止流量发送到尚未准备好接收的后端。如果没有与 NEG 相关联的健康检查状态(通常是因为未配置任何健康检查),则 NEG 控制器会在其对应端点在 NEG 中编程时将 Pod 就绪性门控的值标记为 True。

要求

您的集群必须是 VPC 原生集群。如需了解详情,请参阅创建 VPC 原生集群

集群必须启用 HttpLoadBalancing 插件。GKE 集群默认启用了 HttpLoadBalancing 插件。

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

使用独立 NEG

以下说明展示了如何在 GKE 上将独立 NEG 与外部 HTTP 负载均衡器配合使用。

您必须创建以下对象:

  • 用于创建和管理 Pod 的 Deployment{track-name="k8sLink" track-type="concept"}。
  • 用于创建 NEG 的 Service
  • 使用 Compute Engine API 创建的负载均衡器。这与通过使用 NEG 的 Ingress 创建的负载均衡器不同;在后一种情况下,Ingress 会为您创建并配置负载均衡器。使用独立 NEG 时,您负责关联 NEG 和后端服务,以将 Pod 连接到负载均衡器。负载均衡器由几个组件组成,如下图所示:

负载均衡器的组件包括转发规则、目标 HTTP 代理、网址映射、健康检查和后端服务。这会将流量引导至包含 Pod IP 地址的 NEG。

创建 VPC 原生集群

默认情况下,Autopilot 集群是 VPC 原生集群,因此您可以跳至部署工作负载

对于 Standard 集群,请在 us-central1-a 可用区中创建 VPC 原生集群:

gcloud container clusters create neg-demo-cluster \
    --create-subnetwork="" \
    --network=default \
    --zone=us-central1-a

创建 Deployment

以下示例清单指定运行容器化 HTTP 服务器的三个实例的 Deployment。该 HTTP 服务器使用应用服务器的主机名(运行服务器所在的 Pod 的名称)来响应请求。

我们建议您使用利用 Pod 就绪性反馈的工作负载。

使用 Pod 就绪性反馈

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: neg-demo-app # Label for the Deployment
  name: neg-demo-app # Name of Deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      run: neg-demo-app
  template: # Pod template
    metadata:
      labels:
        run: neg-demo-app # Labels Pods from this Deployment
    spec: # Pod specification; each Pod created by this Deployment has this specification
      containers:
      - image: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods
        name: hostname
  

使用硬编码延迟

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: neg-demo-app # Label for the Deployment
  name: neg-demo-app # Name of Deployment
spec:
  minReadySeconds: 60 # Number of seconds to wait after a Pod is created and its status is Ready
  replicas: 3
  selector:
    matchLabels:
      run: neg-demo-app
  template: # Pod template
    metadata:
      labels:
        run: neg-demo-app # Labels Pods from this Deployment
    spec: # Pod specification; each Pod created by this Deployment has this specification
      containers:
      - image: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods
        name: hostname
  

将此清单保存为 neg-demo-app.yaml,然后通过运行以下命令创建 Deployment:

kubectl apply -f neg-demo-app.yaml

创建一个 Service

以下清单指定了一个 Service,其中:

  • 具有 run: neg-demo-app 标签的任何 Pod 都是此 Service 的成员。
  • 该 Service 具有一个 ServicePort 字段,相应端口为 80。
  • cloud.google.com/neg 注释指定端口 80 将与 NEG 关联。可选的 name 字段指定 NEG 将命名为 NEG_NAME。如果省略 name 字段,系统会自动生成一个唯一名称。如需了解详情,请参阅为 NEG 命名
  • 每个成员 Pod 必须有一个监听 TCP 端口 9376 的容器。
apiVersion: v1
kind: Service
metadata:
  name: neg-demo-svc
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG_NAME"}}}'
spec:
  type: ClusterIP
  selector:
    run: neg-demo-app # Selects Pods labelled run: neg-demo-app
  ports:
  - port: 80
    protocol: TCP
    targetPort: 9376

NEG_NAME 替换为 NEG 的名称。NEG 名称在其区域中必须是唯一的。

将此清单保存为 neg-demo-svc.yaml,然后通过运行以下命令创建 Service:

kubectl apply -f neg-demo-svc.yaml

在创建 Service 后的几分钟内,将创建一个 NEG。

Service 类型

虽然此示例使用的是 ClusterIP Service,但所有五种 Service 类型都支持独立 NEG。我们建议您使用默认类型 ClusterIP

为 NEG 命名

在 GKE 1.18.18-gke.1200 及更高版本中,您可以为 NEG 指定一个自定义名称,GKE 也可以自动生成名称。以前版本的 GKE 仅支持自动生成的 NEG 名称。

GKE 会在集群使用的每个可用区中创建一个 NEG。NEG 全部使用相同的名称。

指定名称

指定自定义 NEG 名称有助于简化负载均衡器的配置,因为您事先知道 NEG 的名称和可用区。 自定义 NEG 名称必须符合以下要求:

  • 对于可用区级集群而言,该名称在集群的可用区中是唯一的;对于区域级集群而言,该名称在区域中是唯一的。
  • 不得与并非由 GKE NEG 控制器创建的任何现有 NEG 的名称相匹配。
  • 不得包含下划线。

使用 Service 的 cloud.google.com/neg 注释中的 name 字段指定 NEG 名称:

cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG_NAME"}}}'

NEG_NAME 替换为 NEG 的名称。NEG 名称在其区域中必须是唯一的。

使用自动生成的名称

自动生成的 NEG 名称必须是唯一的。 如需使用自动生成的名称,请省略 name 字段:

cloud.google.com/neg: '{"exposed_ports": {"80":{}}}'

自动生成的名称采用以下格式:

k8s1-CLUSTER_UID-NAMESPACE-SERVICE-PORT-RANDOM_HASH

将端口映射到多个 NEG

一个 Service 可以监听多个端口。根据定义,NEG 只有一个 IP 地址和端口。这意味着,如果您指定具有多个端口的 Service,则会为每个端口创建一个 NEG。

cloud.google.com/neg 注释的格式如下:

cloud.google.com/neg: '{
   "exposed_ports":{
      "SERVICE_PORT_1":{},
      "SERVICE_PORT_2":{},
      "SERVICE_PORT_3":{},
      ...
   }
 }'

在此示例中,SERVICE_PORT_N 的每个实例都是不同的端口号,它们引用 Service 的现有 Service 端口。对于列出的每个 Service 端口,NEG 控制器会在集群占用的每个区域中创建一个 NEG。

检索 NEG 状态

使用以下命令可检索集群的 Service 的状态:

kubectl get service neg-demo-svc -o yaml

输出内容类似如下:

cloud.google.com/neg-status: '{
   "network-endpoint-groups":{
      "SERVICE_PORT_1": "NEG_NAME_1",
      "SERVICE_PORT_2": "NEG_NAME_2",
      ...
   },
   "zones":["ZONE_1", "ZONE_2", ...]
}

在此输出中,network-endpoint-groups 映射中的每个元素都是一个 Service 端口(例如 SERVICE_PORT_1)以及相应的托管 NEG 的名称(例如 NEG_NAME_1)。zones 列表包含具有 NEG 的每个可用区(如 ZONE_1)。

输出类似于以下内容:

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{}}}'
    cloud.google.com/neg-status: '{"network_endpoint_groups":{"80":"k8s1-cca197ad-default-neg-demo-app-80-4db81e02"},"zones":["ZONE_1", "ZONE_2"]}'
  labels:
    run: neg-demo-app
  name: neg-demo-app
  namespace: default
  selfLink: /api/v1/namespaces/default/services/neg-demo-app
  ...
spec:
  clusterIP: 10.0.14.252
  ports:
  - port: 80
    protocol: TCP
    targetPort: 9376
  selector:
    run: neg-demo-app
  sessionAffinity: None
status:
  loadBalancer: {}

此示例的注解表明,Service 端口 80 已开放给名为 k8s1-cca197ad-default-neg-demo-app-80-4db81e02 的 NEG。

验证 NEG 创建

在创建 Service 后的几分钟内,将创建一个 NEG。如果存在与 Service 清单中指定的标签匹配的 Pod,则 NEG 在创建时将包含 Pod 的 IP 地址。

有两种方法可以验证 NEG 是否已创建并正确配置。在 GKE 1.18.6-gke.6400 及更高版本中,自定义资源 ServiceNetworkEndpointGroup 会存储由 Service Controller 创建的 NEG 的状态信息。在以前的版本中,您必须直接检查 NEG。

ServiceNetworkEndpointGroup 资源

通过获取所有 ServiceNetworkEndpointGroup 资源来列出集群中的 NEG:

kubectl get svcneg

通过检查 ServiceNetworkEndpointGroup 资源的状态来观察 NEG 的状态:

kubectl get svcneg NEG_NAME -o yaml

NEG_NAME 替换为您要检查的单个 NEG 的名称。

此命令的输出内容包括状态部分,该部分可能包含错误消息。某些错误报告为服务事件。您可以通过查询 Service 对象找到更多详细信息:

kubectl describe service SERVICE_NAME

SERVICE_NAME 替换为相关 Service 的名称。

如需验证 NEG 控制器是否已成功同步 NEG,请检查包含 type:Synced 的条件的 ServiceNetworkEndpointGroup 资源的状态字段。最近一次同步的时间位于 status.lastSyncTime 字段中。

ServiceNetworkEndpointGroup 资源仅存在于 GKE 1.18 及更高版本中。

直接检查 NEG

验证该 NEG 是否存在,方法是列出 Google Cloud 项目中的 NEG,并检查是否有 NEG 与您创建的 Service 相匹配。该 NEG 的名称采用以下格式:

k8s1-CLUSTER_UID-NAMESPACE-SERVICE-PORT-RANDOM_HASH

使用以下命令列出 NEG:

gcloud compute network-endpoint-groups list

输出内容类似如下:

NAME                                          LOCATION       ENDPOINT_TYPE   SIZE
k8s1-70aa83a6-default-my-service-80-c9710a6f  ZONE_NAME      GCE_VM_IP_PORT  3

此输出表明 NEG 的 SIZE 是 3,这意味着它有三个端点,分别对应于 Deployment 中的三个 Pod。

使用以下命令标识各个端点:

gcloud compute network-endpoint-groups list-network-endpoints NEG_NAME

NEG_NAME 替换为要为其显示各个端点的 NEG 的名称。

输出显示了三个端点,每个端点都有一个 Pod 的 IP 地址和端口:

INSTANCE                                           IP_ADDRESS  PORT
gke-cluster-3-default-pool-4cc71a15-qlpf  10.12.1.43  9376
gke-cluster-3-default-pool-4cc71a15-qlpf  10.12.1.44  9376
gke-cluster-3-default-pool-4cc71a15-w9nk  10.12.2.26  9376

将外部应用负载均衡器连接到独立 NEG

您可以使用 Compute Engine API 将 NEG 用作外部应用负载均衡器的后端。

  1. 创建防火墙规则。 负载均衡器需要访问集群端点才能执行健康检查。以下命令会创建一条防火墙规则以允许访问:

    gcloud compute firewall-rules create fw-allow-health-check-and-proxy \
       --network=NETWORK_NAME \
       --action=allow \
       --direction=ingress \
       --target-tags=GKE_NODE_NETWORK_TAGS \
       --source-ranges=130.211.0.0/22,35.191.0.0/16 \
       --rules=tcp:9376
    

    替换以下内容:

    • NETWORK_NAME:运行集群的网络。
    • GKE_NODE_NETWORK_TAGS:GKE 节点上的网络标记

    如果您没有为节点创建自定义网络标记,则 GKE 会自动为您生成标记。您可以通过运行以下命令来查找这些生成的标记:

    gcloud compute instances describe INSTANCE_NAME
    

    INSTANCE_NAME 替换为运行 GKE 节点的主机 Compute Engine 虚拟机实例的名称。例如,上一部分中的输出在 GKE 节点的 INSTANCE 列中显示实例名称。 对于 Standard 集群,您还可以运行 gcloud compute instances list 来列出项目中的所有实例。

  2. 为负载均衡器创建全局虚拟 IP 地址:

    gcloud compute addresses create hostname-server-vip \
        --ip-version=IPV4 \
        --global
    
  3. 创建健康检查。负载均衡器会使用健康检查来检测 NEG 中各个端点的活跃度。

    gcloud compute health-checks create http http-basic-check \
        --use-serving-port
    
  4. 创建后端服务,指明这是一个全球外部应用负载均衡器:

    gcloud compute backend-services create my-bes \
        --protocol HTTP \
        --health-checks http-basic-check \
        --global
    
  5. 为负载均衡器创建网址映射目标代理。这个示例非常简单直接,因为本指南中使用的 serve_hostname 应用只有一个端点,且不包含网址。

    gcloud compute url-maps create web-map \
        --default-service my-bes
    
    gcloud compute target-http-proxies create http-lb-proxy \
        --url-map web-map
    
  6. 创建转发规则。 这个过程会创建负载均衡器。

    gcloud compute forwarding-rules create http-forwarding-rule \
        --address=HOSTNAME_SERVER_VIP \
        --global \
        --target-http-proxy=http-lb-proxy \
        --ports=80
    

    HOSTNAME_SERVER_VIP 替换为用于负载均衡器的 IP 地址。如果省略 --address,GKE 会自动分配一个临时 IP 地址。 您也可以预留新的静态外部 IP 地址

检查点

下面列出了到目前为止您已创建的资源:

  • 外部虚拟 IP 地址
  • 转发规则
  • 防火墙规则
  • 目标 HTTP 代理
  • 网址映射 Compute Engine 健康检查
  • 后端服务
  • Compute Engine 健康检查

这些资源之间的关系如下图所示:

您创建的资源之间的关系。

这些资源共同构成了负载均衡器。在下一步中,您将向负载均衡器添加后端。

此处所示的独立 NEG 的优势之一在于,负载均衡器和后端的生命周期可以完全独立。负载均衡器可在应用、相关 Service 或 GKE 集群删除后继续运行。您可以向负载均衡器添加新的 NEG 或移除多个 NEG,而无需更改任何前端负载均衡器对象。

向负载均衡器添加后端

使用 gcloud compute backend-services add-backend 将 NEG 连接到负载均衡器,方法是将其添加为 my-bes 后端服务的后端:

gcloud compute backend-services add-backend my-bes \
    --global \
    --network-endpoint-group=NEG_NAME \
    --network-endpoint-group-zone=NEG_ZONE \
    --balancing-mode RATE --max-rate-per-endpoint 5

替换以下内容:

  • NEG_NAME:您的网络端点组的名称。名称是创建 NEG 时指定的名称,或自动生成的名称。如果您没有为 NEG 指定名称,请参阅下面的说明以查找自动生成的名称。
  • NEG_ZONE:网络端点组所在的可用区。请参阅以下说明查找此值。

使用以下命令获取 NEG 的名称和位置:

gcloud compute network-endpoint-groups list

输出类似于以下内容:

NAME                                          LOCATION       ENDPOINT_TYPE   SIZE
k8s1-70aa83a6-default-my-service-80-c9710a6f  ZONE_NAME      GCE_VM_IP_PORT  3

在此示例输出中,NEG 的名称为 k8s1-70aa83a6-default-my-service-80-c9710a6f

您可以将多个 NEG 添加到同一后端服务。全局后端服务(如 my-bes)可在不同地区具有 NEG 后端,而地区后端服务只能在单个地区中具有后端。

验证负载均衡器是否正常运行

有两种方法可以验证您设置的负载均衡器是否正常运行:

  • 验证健康检查是否已正确配置且通过报告表明它运行正常。
  • 访问应用并验证其响应。

验证健康检查

检查后端服务是否与健康检查和网络端点组相关联,以及各个端点是否运行正常。

使用以下命令检查后端服务是否与您的健康检查和网络端点组相关联:

gcloud compute backend-services describe my-bes --global

输出内容类似如下:

backends:
- balancingMode: RATE
  capacityScaler: 1.0
  group: ... /networkEndpointGroups/k8s1-70aa83a6-default-my-service-80-c9710a6f
...
healthChecks:
- ... /healthChecks/http-basic-check
...
name: my-bes
...

接下来,检查各个端点的运行状况:

gcloud compute backend-services get-health my-bes --global

输出的 status: 部分如下所示:

status:
  healthStatus:
  - healthState: HEALTHY
    instance: ... gke-cluster-3-default-pool-4cc71a15-qlpf
    ipAddress: 10.12.1.43
    port: 50000
  - healthState: HEALTHY
    instance: ... gke-cluster-3-default-pool-4cc71a15-qlpf
    ipAddress: 10.12.1.44
    port: 50000
  - healthState: HEALTHY
    instance: ... gke-cluster-3-default-pool-4cc71a15-w9nk
    ipAddress: 10.12.2.26
    port: 50000

访问应用

通过负载均衡器的 IP 地址访问应用,以确认是否一切正常。

首先,获取负载均衡器的虚拟 IP 地址:

gcloud compute addresses describe hostname-server-vip --global | grep "address:"

输出将包含 IP 地址。接下来,向该 IP 地址(在此示例中为 34.98.102.37)发送请求:

curl 34.98.102.37

来自 serve_hostname 应用的响应应为 neg-demo-app

将内部应用负载均衡器连接到独立 NEG

您可以使用 NEG 为在独立 GKE Pod 中运行的服务配置内部应用负载均衡器。

配置代理专用子网

代理专用子网用于负载均衡器的区域中的所有区域级内部应用负载均衡器。

控制台

如果您使用的是 Google Cloud 控制台,则可以稍后再创建代理专用子网。

gcloud

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

gcloud compute networks subnets create proxy-only-subnet \
    --purpose=REGIONAL_MANAGED_PROXY \
    --role=ACTIVE \
    --region=COMPUTE_REGION \
    --network=lb-network \
    --range=10.129.0.0/23

COMPUTE_REGION 替换为子网的 Compute Engine 区域。

API

使用 subnetworks.insert 方法创建代理专用子网。

POST https://compute.googleapis.com/compute/projects/PROJECT_ID/regions/COMPUTE_REGION/subnetworks
{
  "name": "proxy-only-subnet",
  "ipCidrRange": "10.129.0.0/23",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "region": "projects/PROJECT_ID/regions/COMPUTE_REGION",
  "purpose": "REGIONAL_MANAGED_PROXY",
  "role": "ACTIVE"
}

替换以下内容:

  • PROJECT_ID:您的项目 ID。
  • COMPUTE_REGION:子网的 Compute Engine 区域。

配置防火墙规则

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

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

  • fw-allow-health-check:适用于负载均衡实例的入站流量规则,该规则允许来自 Google Cloud 健康检查系统(130.211.0.0/2235.191.0.0/16)的所有 TCP 流量。此示例使用目标标记 load-balanced-backend 来标识它应该应用到的实例。

  • fw-allow-proxies:适用于负载均衡实例的入站流量规则,该规则允许从内部 HTTP(S) 负载均衡器的托管式代理发送到端口 9376 的 TCP 流量。此示例使用目标标记 load-balanced-backend 来标识它应该应用到的实例。

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

控制台

  1. 转到 Google Cloud 控制台中的防火墙政策页面。

    转到防火墙政策

  2. 点击创建防火墙规则 ,以创建允许传入 SSH 连接的规则:

    • 名称fw-allow-ssh
    • 网络lb-network
    • 流量方向:入站
    • 对匹配项执行的操作:允许
    • 目标:指定的目标标记
    • 目标标记allow-ssh
    • 来源过滤条件IPv4 ranges
    • 来源 IPv4 范围0.0.0.0/0
    • 协议和端口
      • 选择指定的协议和端口
      • 选中 tcp 复选框并指定端口 22
  3. 点击创建

  4. 再次点击创建防火墙规则 以创建允许 Google Cloud 健康检查的规则:

    • 名称fw-allow-health-check
    • 网络lb-network
    • 流量方向:入站
    • 对匹配项执行的操作:允许
    • 目标:指定的目标标记
    • 目标标记load-balanced-backend
    • 来源过滤条件IPv4 ranges
    • 来源 IPv4 范围130.211.0.0/2235.191.0.0/16
    • 协议和端口
      • 选择指定的协议和端口
      • 选中 tcp 复选框并指定端口 80。最佳做法是将此规则限制为仅使用与健康检查所使用的协议和端口匹配的协议和端口。如果您使用 tcp:80 协议和端口,则 Google Cloud 可以使用 HTTP 协议通过端口 80 联系您的虚拟机,但无法使用 HTTPS 协议通过端口 443 联系这些虚拟机。
  5. 点击创建

  6. 再次点击创建防火墙规则 ,以创建允许负载均衡器的代理服务器连接后端的规则:

    • 名称fw-allow-proxies
    • 网络lb-network
    • 流量方向:入站
    • 对匹配项执行的操作:允许
    • 目标:指定的目标标记
    • 目标标记load-balanced-backend
    • 来源过滤条件IPv4 ranges
    • 来源 IPv4 范围10.129.0.0/23
    • 协议和端口
      • 选择指定的协议和端口
      • 选中 tcp 复选框并指定端口 9376
  7. 点击创建

gcloud

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

    gcloud compute firewall-rules create fw-allow-ssh \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --target-tags=allow-ssh \
        --rules=tcp:22
    
  2. 创建 fw-allow-health-check 规则以允许 Google Cloud 健康检查。本示例允许来自健康检查探测工具的所有 TCP 流量;但是,您可以根据自己的需求配置较小范围的端口集。

    gcloud compute firewall-rules create fw-allow-health-check \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --target-tags=load-balanced-backend \
        --rules=tcp
    
  3. 创建 fw-allow-proxies 规则以允许内部 HTTP(S) 负载均衡器的代理连接到您的后端。

    gcloud compute firewall-rules create fw-allow-proxies \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --source-ranges=10.129.0.0/23 \
        --target-tags=load-balanced-backend \
        --rules=tcp:9376
    

API

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

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

PROJECT_ID 替换为您的项目 ID。

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

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "name": "fw-allow-health-check",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "sourceRanges": [
    "130.211.0.0/22",
    "35.191.0.0/16"
  ],
  "targetTags": [
    "load-balanced-backend"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp"
    }
  ],
  "direction": "INGRESS"
}

通过 firewalls.insert 方法创建 fw-allow-proxies 防火墙规则,以允许代理子网内的 TCP 流量。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "name": "fw-allow-proxies",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "sourceRanges": [
    "10.129.0.0/23"
  ],
  "targetTags": [
    "load-balanced-backend"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "9376"
      ]
    }
  ],
  "direction": "INGRESS"
}

PROJECT_ID 替换为您的项目 ID。

配置负载均衡器

对于转发规则的 IP 地址,请使用后端子网。如果您尝试使用代理专用子网,则无法创建转发规则。

控制台

选择负载均衡器类型

  1. 转到 Google Cloud 控制台中的创建负载均衡器页面。 转到创建负载均衡器
  2. HTTP(S) 负载均衡下,点击开始配置
  3. 选择“仅在我的虚拟机之间”。此设置表示负载均衡器是内部的。
  4. 点击继续

准备负载均衡器

  1. 对于负载均衡器的名称,请输入 l7-ilb-gke-map
  2. 对于区域,选择创建子网的区域。
  3. 对于网络,请选择 lb-network

预留代理专用子网

预留代理专用子网:

  1. 点击 Reserve a Subnet(预留子网)。
  2. 名称输入 proxy-only-subnet
  3. 对于 IP 地址范围,请输入 10.129.0.0/23
  4. 点击添加

配置后端服务

  1. 点击后端配置
  2. 创建或选择后端服务菜单中,选择创建后端服务
  3. 将后端服务的名称设置为 l7-ilb-gke-backend-service
  4. 对于后端类型,选择网络端点组
  5. 后端部分的新建后端卡片中执行以下操作:
    1. 网络端点组设置为由 GKE 创建的 NEG。如需获取 NEG 名称,请参阅验证 NEG 创建
    2. 对于 RPS 上限,指定每个端点的最大速率 (5 RPS)。必要时 Google Cloud 将超过此上限。
    3. 点击完成
  6. 健康检查下拉列表中,选择创建健康检查,然后指定以下参数:
    1. 名称l7-ilb-gke-basic-check
    2. 协议:HTTP
    3. 端口指定:正在服务的端口
    4. 点击保存并继续
  7. 点击创建

配置网址映射

  1. 点击路由规则。确保 l7-ilb-gke-backend-service 是任何不匹配的主机和任何不匹配的路径的唯一后端服务。

配置前端

点击前端配置并执行以下步骤:

对于 HTTP

  1. 点击前端配置
  2. 点击添加前端 IP 和端口
  3. 名称设置为 l7-ilb-gke-forwarding-rule
  4. 协议设置为 HTTP
  5. 子网设置为 backend-subnet
  6. 内部 IP 下,选择“预留静态内部 IP 地址”
  7. 在显示的面板中提供以下详细信息:
    1. 名称l7-ilb-gke-ip
    2. 静态 IP 地址部分,选择“让我选择”
    3. 自定义 IP 地址部分,输入 10.1.2.199
    4. 点击预留
  8. 端口设置为 80
  9. 点击完成

对于 HTTPS

如果您在客户端和负载均衡器之间使用 HTTPS,则需要一个或多个 SSL 证书资源来配置代理。请参阅 SSL 证书,了解如何创建 SSL 证书资源。内部 HTTP(S) 负载均衡器不支持由 Google 管理的证书。

  1. 点击前端配置
  2. 点击添加前端 IP 和端口
  3. 名称字段中,输入 l7-ilb-gke-forwarding-rule
  4. 协议字段中,选择 HTTPS (includes HTTP/2)
  5. 子网设置为 backend-subnet
  6. 内部 IP 下,选择“预留静态内部 IP 地址”
  7. 在显示的面板中提供以下详细信息:
    1. 名称l7-ilb-gke-ip
    2. 静态 IP 地址部分,选择“让我选择”
    3. 自定义 IP 地址部分,输入 10.1.2.199
    4. 点击预留
  8. 确保将端口设置为 443,以允许 HTTPS 流量。
  9. 点击证书下拉列表。
    1. 如果您已经拥有要用作主要 SSL 证书的自行管理的 SSL 证书资源,请从下拉菜单中选择该证书。
    2. 否则,请选择创建新证书
      1. 填写名称 l7-ilb-cert
      2. 在相应字段中上传您的 PEM 格式的文件:
        • 公钥证书
        • 证书链
        • 私钥
      3. 点击创建
  10. 如需添加除了主要 SSL 证书资源之外的其他证书资源,请执行以下操作:
    1. 点击添加证书
    2. 证书列表中选择一个证书,或点击创建新证书并按照说明操作。
  11. 点击完成

完成配置

点击创建

gcloud

  1. 使用 gcloud compute health-checks create http 命令定义 HTTP 健康检查。

    gcloud compute health-checks create http l7-ilb-gke-basic-check \
        --region=COMPUTE_REGION \
        --use-serving-port
    
  2. 使用 gcloud compute backend-services create 命令定义后端服务。

    gcloud compute backend-services create l7-ilb-gke-backend-service \
        --load-balancing-scheme=INTERNAL_MANAGED \
        --protocol=HTTP \
        --health-checks=l7-ilb-gke-basic-check \
        --health-checks-region=COMPUTE_REGION \
        --region=COMPUTE_REGION
    
  3. 设置 DEPLOYMENT_NAME 变量:

    export DEPLOYMENT_NAME=NEG_NAME
    

    NEG_NAME 替换为 NEG 的名称。

  4. 使用 gcloud compute backend-services add-backend 命令将 NEG 后端添加到后端服务。

    gcloud compute backend-services add-backend l7-ilb-gke-backend-service \
        --network-endpoint-group=$DEPLOYMENT_NAME \
        --network-endpoint-group-zone=COMPUTE_ZONE-b \
        --region=COMPUTE_REGION \
        --balancing-mode=RATE \
        --max-rate-per-endpoint=5
    
  5. 使用 gcloud compute url-maps create 命令创建网址映射。

    gcloud compute url-maps create l7-ilb-gke-map \
        --default-service=l7-ilb-gke-backend-service \
        --region=COMPUTE_REGION
    
  6. 创建目标代理。

    对于 HTTP

    使用 gcloud compute target-http-proxies create 命令。

    gcloud compute target-http-proxies create l7-ilb-gke-proxy \
        --url-map=l7-ilb-gke-map \
        --url-map-region=COMPUTE_REGION \
        --region=COMPUTE_REGION
    

    对于 HTTPS

    请参阅 SSL 证书,了解如何创建 SSL 证书资源。内部 HTTP(S) 负载均衡器不支持由 Google 管理的证书。

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

    export LB_CERT=PATH_TO_PEM_FORMATTED_FILE
    
    export LB_PRIVATE_KEY=PATH_TO_PEM_FORMATTED_FILE
    

    使用 gcloud compute ssl-certificates create 命令创建区域性 SSL 证书。

    gcloud compute ssl-certificates create

    gcloud compute ssl-certificates create l7-ilb-cert \
        --certificate=$LB_CERT \
        --private-key=$LB_PRIVATE_KEY \
        --region=COMPUTE_REGION
    

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

    gcloud compute target-https-proxies create l7-ilb-gke-proxy \
        --url-map=l7-ilb-gke-map \
        --region=COMPUTE_REGION \
        --ssl-certificates=l7-ilb-cert
    
  7. 创建转发规则。

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

    对于 HTTP

    使用带有正确标志的 gcloud compute forwarding-rules create 命令。

    gcloud compute forwarding-rules create l7-ilb-gke-forwarding-rule \
        --load-balancing-scheme=INTERNAL_MANAGED \
        --network=lb-network \
        --subnet=backend-subnet \
        --address=10.1.2.199 \
        --ports=80 \
        --region=COMPUTE_REGION \
        --target-http-proxy=l7-ilb-gke-proxy \
        --target-http-proxy-region=COMPUTE_REGION
    

    对于 HTTPS

    使用带有正确标志的 gcloud compute forwarding-rules create 命令。

    gcloud compute forwarding-rules create l7-ilb-gke-forwarding-rule \
        --load-balancing-scheme=INTERNAL_MANAGED \
        --network=lb-network \
        --subnet=backend-subnet \
        --address=10.1.2.199 \
        --ports=443 \
        --region=COMPUTE_REGION \
        --target-https-proxy=l7-ilb-gke-proxy \
        --target-https-proxy-region=COMPUTE_REGION
    

API

regionHealthChecks.insert 方法发出 POST 请求,以创建健康检查。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/healthChecks
{
   "name": "l7-ilb-gke-basic-check",
   "type": "HTTP",
   "httpHealthCheck": {
     "portSpecification": "USE_SERVING_PORT"
   }
}

PROJECT_ID 替换为项目 ID。

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

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/backendServices
{
  "name": "l7-ilb-gke-backend-service",
  "backends": [
    {
      "group": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/COMPUTE_ZONE/networkEndpointGroups/NEG_NAME",
      "balancingMode": "RATE",
      "maxRatePerEndpoint": 5
    }
  ],
  "healthChecks": [
    "projects/PROJECT_ID/regions/COMPUTE_REGION/healthChecks/l7-ilb-gke-basic-check"
  ],
  "loadBalancingScheme": "INTERNAL_MANAGED"
}

替换以下内容:

  • PROJECT_ID:项目 ID。
  • NEG_NAME:NEG 的名称。

regionUrlMaps.insert 方法发出 POST 请求,以创建网址映射。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/urlMaps
{
  "name": "l7-ilb-gke-map",
  "defaultService": "projects/PROJECT_ID/regions/COMPUTE_REGION/backendServices/l7-ilb-gke-backend-service"
}

PROJECT_ID 替换为项目 ID。

regionTargetHttpProxies.insert 方法发出 POST 请求,以创建目标 HTTP 代理。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/targetHttpProxy
{
  "name": "l7-ilb-gke-proxy",
  "urlMap": "projects/PROJECT_ID/global/urlMaps/l7-ilb-gke-map",
  "region": "COMPUTE_REGION"
}

PROJECT_ID 替换为项目 ID。

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

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/forwardingRules
{
  "name": "l7-ilb-gke-forwarding-rule",
  "IPAddress": "10.1.2.199",
  "IPProtocol": "TCP",
  "portRange": "80-80",
  "target": "projects/PROJECT_ID/regions/COMPUTE_REGION/targetHttpProxies/l7-ilb-gke-proxy",
  "loadBalancingScheme": "INTERNAL_MANAGED",
  "subnetwork": "projects/PROJECT_ID/regions/COMPUTE_REGION/subnetworks/backend-subnet",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "networkTier": "PREMIUM",
}

PROJECT_ID 替换为项目 ID。

测试

在地区中创建虚拟机实例以测试连接:

gcloud compute instances create l7-ilb-client \
    --image-family=debian-9 \
    --image-project=debian-cloud \
    --zone=COMPUTE_ZONE \
    --network=lb-network \
    --subnet=backend-subnet \
    --tags=l7-ilb-client,allow-ssh

登录客户端实例,检查是否可以使用内部应用负载均衡器的转发规则 IP 地址访问后端的 HTTP(S) 服务,以及流量是否正在 NEG 中的端点之间进行负载均衡。

使用 SSH 连接到每个客户端实例:

gcloud compute ssh l7-ilb-client \
    --zone=COMPUTE_ZONE-b

验证 IP 是否提供其主机名:

curl 10.1.2.199

对于 HTTPS 测试,请运行以下命令:

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

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

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

对于 HTTP

{
RESULTS=
for i in {1..100}
do
    RESULTS="$RESULTS:$(curl --silent 10.1.2.199)"
done
echo "***"
echo "*** Results of load-balancing to 10.1.2.199: "
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.199:443
)"
done
echo "***"
echo "*** Results of load-balancing to 10.1.2.199: "
echo "***"
echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
echo
}

实现异构服务(虚拟机和容器)

负载均衡器可以作为混合 Kubernetes 和非 Kubernetes 工作负载的前端。这可能是从虚拟机到容器的迁移的一部分,也可能是受益于共享负载均衡器的永久架构。这可以通过创建针对不同类型的后端(包括独立 NEG 在内)的负载均衡器来实现。

同一后端服务中的虚拟机和容器

此示例展示了如何创建指向运行某工作负载的现有虚拟机的 NEG,以及如何将此 NEG 添加为现有 backendService 的另一个后端。这样,单个负载均衡器就可以均衡虚拟机与 GKE 容器之间的负载。

此示例拓展了使用外部 HTTP 负载均衡器的上一个示例

由于所有端点都由同一 backendService 分组,因此,虚拟机和容器端点会被视为同一服务。这意味着主机或路径匹配将根据网址映射规则以完全相同的方式处理所有后端。

所述架构。之前创建的负载均衡器指向两个 NEG,即之前创建的容器的 NEG 以及包含虚拟机 IP 地址的新 NEG。

在将 NEG 用作后端服务的后端时,该后端服务中的所有其他后端也必须是 NEG。您不能将实例组和 NEG 用作同一后端服务的后端。此外,容器和虚拟机不能作为端点存在于同一 NEG 中,因此,它们必须始终配置单独的 NEG。

  1. 使用以下命令将虚拟机部署到 Compute Engine:

    gcloud compute instances create vm1 \
        --zone=COMPUTE_ZONE \
        --network=NETWORK \
        --subnet=SUBNET \
        --image-project=cos-cloud \
        --image-family=cos-stable --tags=vm-neg-tag
    

    替换以下内容:

    • COMPUTE_ZONE:区域的名称。
    • NETWORK:网络的名称。
    • SUBNET:与网络关联的子网的名称。
  2. 将应用部署到虚拟机:

    gcloud compute ssh vm1 \
        --zone=COMPUTE_ZONE \
        --command="docker run -d --rm --network=host registry.k8s.io/serve_hostname:v1.4 && sudo iptables -P INPUT ACCEPT"
    

    此命令会将之前示例中的那个示例应用部署到虚拟机。为简单起见,应用作为 Docker 容器运行,但这不是必需的。如需允许防火墙访问正在运行的容器,必须使用 iptables 命令。

  3. 验证应用是否在端口 9376 上运行并且通过报告表明它正在 vm1 上运行:

    gcloud compute ssh vm1 \
        --zone=COMPUTE_ZONE \
        --command="curl -s localhost:9376"
    

    服务器会返回 vm1 响应。

  4. 创建一个能与虚拟机端点配合使用的 NEG。容器和虚拟机可以均为 NEG 端点,但单个 NEG 不能同时具有虚拟机和容器端点。

    gcloud compute network-endpoint-groups create vm-neg \
        --subnet=SUBNET \
        --zone=COMPUTE_ZONE
    
  5. 将虚拟机端点连接到 NEG:

    gcloud compute network-endpoint-groups update vm-neg \
        --zone=COMPUTE_ZONE \
        --add-endpoint="instance=vm1,ip=VM_PRIMARY_IP,port=9376"
    

    VM_PRIMARY_IP 替换为虚拟机的主要 IP 地址。

  6. 确认 NEG 具有虚拟机端点:

    gcloud compute network-endpoint-groups list-network-endpoints vm-neg \
        --zone COMPUTE_ZONE
    
  7. 使用用于添加容器后端的命令将 NEG 附加到后端服务:

    gcloud compute backend-services add-backend my-bes
        --global \
        --network-endpoint-group vm-neg \
        --network-endpoint-group-zone COMPUTE_ZONE \
        --balancing-mode RATE --max-rate-per-endpoint 10
    
  8. 打开防火墙以允许执行虚拟机健康检查:

    gcloud compute firewall-rules create fw-allow-health-check-to-vm1 \
        --network=NETWORK \
        --action=allow \
        --direction=ingress \
        --target-tags=vm-neg-tag \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --rules=tcp:9376
    
  9. 通过发送测试流量,验证负载均衡器是否正将流量转发到新的 vm1 后端和现有容器后端:

    for i in `seq 1 100`; do curl ${VIP};echo; done
    

    您应该会看到来自容器 (neg-demo-app) 和虚拟机 (vm1) 端点的响应。

不同后端服务的虚拟机和容器

此示例展示了如何创建指向运行某工作负载的现有虚拟机的 NEG,以及如何将此 NEG 添加为新 backendService 的后端。如果容器和虚拟机是不同的 Service,但需要共用同一 L7 负载均衡器(例如,Service 共用同一 IP 地址或域名),则此方法非常有用。

此示例扩展了上文中在与容器后端相同的后端服务中具有虚拟机后端的那个示例。此示例重复使用了那个虚拟机。

由于容器和虚拟机端点被分组到不同的后端服务中,因此它们被视为不同的 Service。这意味着,网址映射会匹配后端,并根据主机名将流量引导至虚拟机或容器。

下图显示了单个虚拟 IP 地址如何与两个主机名对应,继而又对应于基于容器的后端服务和基于虚拟机的后端服务。

单个虚拟 IP 地址映射到两个主机名,一个主机名用于基于容器的后端,另一个用于基于虚拟机的后端。

下图展示了上一部分中介绍的架构:

该架构有两个 NEG,一个针对使用容器实现的 Service,另一个针对使用虚拟机实现的 Service。每个 NEG 都有一个后端服务对象。网址映射对象会根据请求的网址将流量引导至正确的后端服务。

  1. 为虚拟机创建新的后端服务:

    gcloud compute backend-services create my-vm-bes \
       --protocol HTTP \
       --health-checks http-basic-check \
       --global
    
  2. 将虚拟机的 NEG vm-neg 附加到后端服务:

    gcloud compute backend-services add-backend my-vm-bes \
        --global \
        --network-endpoint-group vm-neg \
        --network-endpoint-group-zone COMPUTE_ZONE \
        --balancing-mode RATE --max-rate-per-endpoint 10
    
  3. 网址映射添加一条主机规则,以将对 container.example.com 主机的请求引导至容器后端服务:

    gcloud compute url-maps add-path-matcher web-map \
        --path-matcher-name=container-path --default-service=my-bes \
        --new-hosts=container.example.com --global
    
  4. 向网址映射添加另一条主机规则,以将对 vm.example.com 主机的请求引导至虚拟机后端服务:

    gcloud compute url-maps add-path-matcher web-map \
        --path-matcher-name=vm-path --default-service=my-vm-bes \
        --new-hosts=vm.example.com --global
    
  5. 验证负载均衡器是否根据请求的路径将流量发送到虚拟机后端:

    curl -H "HOST:vm.example.com" VIRTUAL_IP
    

    VIRTUAL_IP 替换为虚拟 IP 地址。

独立 NEG 所受的限制

  • 注释验证错误通过 Kubernetes 事件向用户显示。
  • NEG 所受的限制也适用于独立 NEG。

价格

如需详细了解负载均衡器的价格,请参阅价格页面的负载均衡部分。NEG 不会额外产生费用。

问题排查

本部分介绍了您在使用独立 NEG 时可能会遇到的常见问题的问题排查步骤。

未配置独立 NEG

具体情况:未创建 NEG。

可能的解决方法

  • 检查与 Service 相关联的事件,并查找错误消息。
  • 验证独立 NEG 注释是否为格式正确的 JSON,以及显示的端口是否与服务规范中的现有端口匹配。
  • 验证 NEG 状态注释,并查看预期的服务端口是否具有相应的 NEG。
  • 使用命令 gcloud compute network-endpoint-groups list 验证是否在预期的地区中创建了 NEG。
  • 如果使用 GKE 1.18 或更高版本,请检查 Service 的 svcneg 资源是否存在。如果存在,请检查 Initialized 条件中是否存在任何错误信息。
  • 如果您使用的是自定义 NEG 名称,请确保其中每个 NEG 名称在其区域中是唯一的。

流量未到达端点

具体情况:出现 502 错误或连接被拒。

可能的解决方法

  • 配置 Service 后,如果新端点能够响应健康检查,那么在将新端点附加到 NEG 后,通常就可以访问新端点。
  • 如果在此之后,流量仍然无法到达端点,从而导致出现 HTTP(S) 的 502 错误代码或 TCP/SSL 负载均衡器的连接被拒,请检查以下内容:
    • 验证防火墙规则是否允许传入的 TCP 流量传输到以下范围内的端点:130.211.0.0/2235.191.0.0/16
    • 使用 Google Cloud CLI 或者通过在 backendService 上调用 getHealth API 或在 NEG 上调用 listEndpoints API 并将 showHealth 参数设置为 SHOW,验证端点是否健康。

停止发布

具体情况:发布更新后 Deployment 的操作处于停止状态,并且最新副本的数量与所选的副本数量不一致。

可能的解决方法

Deployment 的健康检查失败。容器映像可能已损坏,或者健康检查的配置可能有误。Pod 的滚动替换会等待新启动的 Pod 通过其 Pod 就绪性门控。仅当 Pod 正在响应负载均衡器健康检查时,才会出现这种情况。如果 Pod 没有响应,或者健康检查的配置有误,则无法满足就绪性门控条件,并且无法继续发布。

  • 如果您使用的是 kubectl 1.13 或更高版本,则可以使用以下命令检查 Pod 就绪性门控的状态:

    kubectl get my-Pod -o wide
    

    查看 READINESS GATES 列。

    kubectl 1.12 及更低版本中不存在此列。标记为 READY 状态的 Pod 的就绪性门控可能已失败。如需就此进行验证,请使用以下命令:

    kubectl get my-pod -o yaml
    

    输出中会列出就绪性门控及其状态。

  • 验证 Deployment 的 Pod 规范中的容器映像是否正常运行,以及是否能够响应健康检查。

  • 验证健康检查是否已正确配置。

NEG 并非处于垃圾回收状态

症状:应该删除的 NEG 仍然存在。

可能的解决方法

  • 如果后端 Service 引用了 NEG,则 NEG 并非处于垃圾回收状态。如需了解详情,请参阅防止泄露 NEG
  • 如果使用 1.18 或更高版本,则可以使用服务 NEG 过程检查 ServiceNetworkEndpointGroup 资源中的事件。
  • 检查服务是否仍需要 NEG。检查与 NEG 相对应的服务的 svcneg 资源,并检查 Service 注释是否存在。

NEG 未与 Service 同步

症状:NEG 中不存在预期 (Pod IP) 端点、NEG 未同步或出现错误 Failed to sync NEG_NAME (will not retry): neg name NEG_NAME is already in use, found a custom named neg with an empty description

可能的解决方法

如果您使用的是 GKE 1.18 或更高版本,请查看 svcneg 资源,了解相关信息:

  • 检查 status.lastSyncTime 值以验证 NEG 最近是否同步。
  • 检查 Synced 条件,了解在最近同步期间遇到的任何错误。

如果您使用的是 GKE 1.19.9 或更高版本,请检查是否存在这样一个 NEG,它的名称和可用区与 GKE NEG 控制器需要创建的 NEG 的名称和可用区相匹配。例如,您可能已使用 gcloud CLI 或 Google Cloud 控制台在集群的可用区(或集群的某个可用区)中创建 NEG 控制器需要使用其名称的 NEG。在这种情况下,您必须删除现有的 NEG,然后 NEG 控制器才能同步其端点。独立 NEG 的创建和成员资格根据设计由 NEG 控制器管理。

后续步骤