LoadBalancer Service 简介


本页面简要介绍在应用 Kubernetes LoadBalancer Service 清单时 Google Kubernetes Engine (GKE) 如何创建和管理 Google Cloud 负载均衡器。它介绍了 LoadBalancer 类型、配置参数,并提供了最佳实践建议。

在阅读本页面内容之前,请确保您熟悉 GKE 网络概念

概览

创建 LoadBalancer Service 时,GKE 会配置一个 Google Cloud 直通式负载均衡器,其特征取决于 Service 清单的参数。

为网络自定义 LoadBalancer Service

在选择要使用哪个 LoadBalancer Service 配置时,请考虑以下几个方面:

LoadBalancer Service 决策树。
图:LoadBalancer Service 决策树

负载均衡器类型 - 内部或外部

在 GKE 中创建 LoadBalancer Service 时,请指定负载均衡器是具有内部还是外部地址

  • 外部 LoadBalancer Service 使用外部直通式网络负载均衡器来实现。位于 VPC 网络外部的客户端和具有互联网访问权限的 Google Cloud虚拟机可以访问外部 LoadBalancer Service。

    如果您创建 LoadBalancer Service 但未指定任何自定义设置,则系统会默认使用此配置。

    最佳实践是在创建外部 LoadBalancer Service 时,在 Service 清单中添加 cloud.google.com/l4-rbs: "enabled" 注解。在 Service 清单中添加此注解会创建基于后端服务的外部直通式网络负载均衡器

    省略 cloud.google.com/l4-rbs: "enabled" 注解的 LoadBalancer Service 清单会创建基于目标池的外部直通式网络负载均衡器。不再建议使用基于目标池的外部直通式网络负载均衡器。

  • 内部 LoadBalancer Service 通过使用内部直通式网络负载均衡器实现。位于同一 VPC 网络或连接到集群 VPC 网络的网络中的客户端可以访问内部 LoadBalancer Service。

    如需创建内部 LoadBalancer Service,请执行以下操作:

    • 最佳实践是确保已启用 GKE 子集,以便 GKE 可以使用 GCE_VM_IP 网络端点组 (NEG) 高效地对节点进行分组。GKE 子集并非必需,但强烈建议使用。

    • 在 Service 清单中添加 networking.gke.io/load-balancer-type: "Internal" 注解。

externalTrafficPolicy 的作用

externalTrafficPolicy 参数可控制以下方面:

  • 哪些节点从负载均衡器接收数据包
  • 在负载均衡器将数据包传送给节点后,数据包是否可能会在集群中的节点之间进行路由
  • 原始客户端 IP 地址是保留还是丢失

externalTrafficPolicy 可为 LocalCluster

  • 使用 externalTrafficPolicy: Local 可确保数据包仅传送到至少有一个已就绪、未终止的服务 Pod 的节点,并保留原始客户端来源 IP 地址。此选项最适合采用具有服务 Pod 且数量相对恒定的节点(即使集群中的节点总数会变化)的工作负载。此选项是支持加权负载均衡所必需的。
  • 如果集群中的节点总数相对恒定,但具有服务 Pod 的节点数量会变化,请使用 externalTrafficPolicy: Cluster。此选项不会保留原始客户端来源 IP 地址,并且可能会增加延迟时间,因为数据包可能会在从负载均衡器传送到某个节点后,再路由到另一个节点上的服务 Pod。此选项与加权负载均衡不兼容。

如需详细了解 externalTrafficPolicy 如何影响节点内的数据包路由,请参阅数据包处理

加权负载均衡

外部 LoadBalancer Service 支持加权负载均衡,这使得具有较多服务 Pod 的节点可以比具有较少服务 Pod 的节点接收更大比例的新连接。

加权负载均衡流量分配。
图:加权负载均衡流量分配

如图所示,启用了加权负载均衡的 Service 会按各个节点上就绪 Pod 数量的比例来分配新连接,从而确保具有更多 Pod 的节点接收更多新连接。

如需使用加权负载均衡,您必须满足以下所有要求:

  • 您的 GKE 集群必须使用 1.31.0-gke.1506000 或更高版本。

  • 必须为您的集群启用 HttpLoadBalancing 插件。默认情况下,此插件处于启用状态。它允许集群管理使用后端服务的负载均衡器。

  • 您必须在 LoadBalancer Service 清单中添加 cloud.google.com/l4-rbs: "enabled" 注解,以便 GKE 创建基于后端服务的外部直通式网络负载均衡器。基于目标池的外部直通式网络负载均衡器不支持加权负载均衡。

  • 您必须在 LoadBalancer Service 清单中添加 networking.gke.io/weighted-load-balancing: pods-per-node 注解,才能启用加权负载均衡功能。

  • LoadBalancer Service 清单必须使用 externalTrafficPolicy: Local。GKE 不会阻止您使用 externalTrafficPolicy: Cluster,但 externalTrafficPolicy: Cluster 实际上会停用加权负载均衡,因为数据包可能会在路由到负载均衡器之后路由到其他节点。

如需使用加权负载均衡,请参阅启用加权负载均衡

如需从负载均衡器的角度详细了解加权负载均衡,请参阅基于后端服务的外部直通式网络负载均衡器中的加权负载均衡

内部 LoadBalancer Service 的特殊注意事项

本部分介绍了 GKE 子集选项(这是内部 LoadBalancer Service 所独有的),以及 GKE 子集如何与 externalTrafficPolicy 交互来影响负载均衡节点的最大数量。

GKE 子集

最佳实践

启用 GKE 子集以提高内部 LoadBalancer Service 的可伸缩性。

GKE 子集(也称为适用于第 4 层内部负载均衡器的 GKE 子集)是一种集群级配置选项,可通过更高效地将节点端点分组到 GCE_VM_IP 网络端点组 (NEG) 中,来提高内部直通式网络负载均衡器的可伸缩性。NEG 用作负载均衡器的后端。

下图显示了具有三个节点的可用区级集群中的两个 Service。集群已启用 GKE 子集。每个 Service 都有两个 Pod。GKE 会为每个 Service 创建一个 GCE_VM_IP NEG。每个 NEG 中的端点都是包含相应 Service 的服务 Pod 的节点。

可用区级集群中两个 Service 的 GKE 子集。

您可以在创建集群或更新现有集群时启用 GKE 子集。启用后,您便无法停用 GKE 子集。GKE 子集需要:

  • GKE 版本 1.18.19-gke.1400 或更高版本,以及
  • 为集群启用的 HttpLoadBalancing 插件。默认情况下,此插件处于启用状态。它允许集群管理使用后端服务的负载均衡器。

节点数

如果集群的总节点数(所有节点池)超过 250 个,则停用了 GKE 子集的集群可能会遇到内部 LoadBalancer Service 方面的问题。出现这种情况的原因是,GKE 创建的内部直通式网络负载均衡器只能向 250 个或更少的后端节点虚拟机分发数据包。存在此限制的原因有以下两个:

  • GKE 不使用负载均衡器后端子集
  • 在负载均衡器后端子集处于停用状态时,内部直通式网络负载均衡器仅限于向 250 个或更少的后端分发数据包。

采用 GKE 子集的集群支持总节点数超过 250 个的集群中的内部 LoadBalancer Service。

  • 在启用了 GKE 子集的集群中,使用 externalTrafficPolicy: Local 的内部 LoadBalancer Service 最多可支持 250 个具有为此 Service 提供支持的服务 Pod 的节点。

  • 在启用了 GKE 子集的集群中,使用 externalTrafficPolicy: Cluster 的内部 LoadBalancer Service 不会对具有服务 Pod 的节点数量施加任何限制,因为 GKE 在 GCE_VM_IP NEG 中配置的节点端点不会超过 25 个。如需了解详情,请参阅 GCE_VM_IP NEG 后端中的节点成员资格

会话亲和性和流量分配

借助会话亲和性,您可以控制负载均衡器如何将来自客户端的请求分配给后端,并确保将来自客户端的所有后续请求路由回同一后端。

如果您使用会话亲和性设置为 CLIENT_IP 的内部直通式网络负载均衡器,可能会看到分配到后端的流量不均匀。这是因为负载均衡器始终会将来自给定客户端 IP 地址的流量发送到同一个后端。如果您有少量客户端的流量较高,这可能会导致某些后端过载,而其他后端未充分利用。

如需了解详情,请参阅会话亲和性选项

节点分组

GKE 版本、Service 清单注解以及适用于内部 LoadBalancer Service 的 GKE 子集选项决定了生成的 Google Cloud 负载均衡器和后端类型。负载均衡器和后端类型决定了节点如何分组到 GCE_VM_IP NEG、实例组或目标池中。在所有情况下, Google Cloud直通式负载均衡器都会识别 GKE 节点的网络接口 (NIC),而不是特定节点或 Pod IP 地址。

GKE LoadBalancer Service 生成的 Google Cloud 负载均衡器 节点分组方法
在启用了 GKE 子集的集群中创建的内部 LoadBalancer Service1 内部直通式网络负载均衡器,其后端服务使用 GCE_VM_IP 网络端点组 (NEG) 后端

节点虚拟机根据 Service 的 externalTrafficPolicy 和集群中的节点数按服务分组,依可用区分组到 GCE_VM_IP NEG 中。

Service 的 externalTrafficPolicy 还控制哪些节点通过负载均衡器健康检查以及数据包处理

在停用 GKE 子集的集群中创建内部 LoadBalancer Service 内部直通式网络负载均衡器,其后端服务使用可用区级非代管式实例组后端

所有节点虚拟机都会放入可用区级非代管式实例组中,供 GKE 用作内部直通式网络负载均衡器后端服务的后端。

Service 的 externalTrafficPolicy 控制哪些节点通过负载均衡器健康检查以及数据包处理

由于单个负载均衡实例组限制,相同的非代管实例组用于集群中创建的其他负载均衡器后端服务。

具有 cloud.google.com/l4-rbs: "enabled" 注解的外部 LoadBalancer Service2,应用于运行 GKE 1.32.2-gke.1652000 或更高版本的集群4 基于后端服务的外部直通式网络负载均衡器,其后端服务使用 GCE_VM_IP 网络端点组 (NEG) 后端

节点虚拟机根据 Service 的 externalTrafficPolicy 和集群中的节点数按服务分组,依可用区分组到 GCE_VM_IP NEG 中。

Service 的 externalTrafficPolicy 还控制哪些节点通过负载均衡器健康检查以及数据包处理

具有 cloud.google.com/l4-rbs: "enabled" 注解的外部 LoadBalancer Service2,应用于运行低于 1.32.2-gke.1652000 的 GKE 版本的集群4 基于后端服务的外部直通式网络负载均衡器,其后端服务使用可用区级非代管式实例组后端

所有节点虚拟机都会放入可用区级非代管式实例组中,供 GKE 用作外部直通式网络负载均衡器后端服务的后端。

Service 的 externalTrafficPolicy 控制哪些节点通过负载均衡器健康检查以及数据包处理

由于单个负载均衡实例组限制,相同的非代管实例组用于集群中创建的其他负载均衡器后端服务。

不带 cloud.google.com/l4-rbs: "enabled" 注释的外部 LoadBalancer Service3 基于目标池的外部直通式网络负载均衡器,其目标池包含集群的所有节点

目标池是一种不依赖于实例组的旧版 API。所有节点在目标池中都具有直接成员资格。

Service 的 externalTrafficPolicy 控制哪些节点通过负载均衡器健康检查以及数据包处理

1 只有启用 GKE 子集后创建的内部直通式网络负载均衡器才使用 GCE_VM_IP NEG。在启用 GKE 子集之前创建的任何内部 LoadBalancer Service 会继续使用非代管实例组后端。如需查看示例和配置指导,请参阅创建内部 LoadBalancer Service

2GKE 不会自动将现有的外部 LoadBalancer Service 从基于目标池的外部直通式网络负载均衡器迁移到基于后端服务的外部直通式网络负载均衡器。如需创建由基于后端服务的外部直通式网络负载均衡器提供支持的外部 LoadBalancer Service,您必须在创建时在 Service 清单中添加 cloud.google.com/l4-rbs: "enabled" 注解。

3从由基于后端服务的外部直通式网络负载均衡器提供支持的现有外部 LoadBalancer Service 中移除 cloud.google.com/l4-rbs: "enabled" 注解,不会导致 GKE 创建基于目标池的外部直通式网络负载均衡器。如需创建由基于目标池的外部直通式网络负载均衡器提供支持的外部 LoadBalancer Service,您必须在创建时在 Service 清单中省略 cloud.google.com/l4-rbs: "enabled" 注解。

4GKE 不会自动将由基于后端服务且具有实例组后端的外部直通式网络负载均衡器提供支持的现有外部 LoadBalancer Service 迁移到基于后端服务且具有 GCE_VM_IP NEG 后端的外部直通式网络负载均衡器。如需创建由基于后端服务且使用 GCE_VM_IP NEG 后端的外部直通式网络负载均衡器提供支持的外部 LoadBalancer Service,您必须在 Service 清单中添加 cloud.google.com/l4-rbs: "enabled" 注解,并将该清单应用于运行 GKE 1.32.2-gke.1652000 或更高版本的集群。如需了解手动迁移说明,请参阅迁移到 GCE_VM_IP NEG 后端

GCE_VM_IP NEG 后端中的节点成员资格

为集群启用 GKE 子集后,或者在 GKE 1.32.2-gke.1652000 或更高版本上创建了具有 cloud.google.com/l4-rbs: "enabled" 的外部直通式网络负载均衡器后,GKE 会在每个可用区内为每个 LoadBalancer Service 创建一个唯一的 GCE_VM_IP NEG。与实例组不同,节点可以是多个负载均衡 GCE_VM_IP NEG 的成员。Service 的 externalTrafficPolicy 和集群中的节点数决定了将哪些节点作为端点添加到 Service 的 GCE_VM_IP NEG。

集群的控制平面根据 Service 的 externalTrafficPolicy 值和集群中的节点数量,将节点作为端点添加到 GCE_VM_IP NEG,如下表所示。

内部直通式网络负载均衡器中的节点

externalTrafficPolicy 集群中的节点数 端点成员资格
Cluster 1-25 个节点 GKE 使用集群中的所有节点作为服务 NEG 的端点,即使节点不包含 Service 的服务 Pod 也是如此。
Cluster 超过 25 个节点 GKE 使用多达 25 个节点的随机子集作为 Service NEG 的端点,即使节点不包含 Service 的服务 Pod 也是如此。
Local 任意数量的节点1 GKE 仅使用至少具有一个 Service 服务 Pod 的节点作为 Service NEG 的端点。

1限制为 250 个具有服务 Pod 的节点。集群中可以存在超过 250 个节点,但是当停用内部直通式网络负载均衡器后端子集时,内部直通式网络负载均衡器只能分配给 250 个后端虚拟机。即使启用了 GKE 子集,GKE 也不会通过内部直通式网络负载均衡器后端子集配置内部直通式网络负载均衡器。如需详细了解此限制,请参阅每个内部后端服务的虚拟机实例数上限

外部直通式网络负载均衡器中的节点

externalTrafficPolicy 集群中的节点数 端点成员资格
Cluster 1 到 250 个节点 GKE 使用集群中的所有节点作为服务 NEG 的端点,即使节点不包含 Service 的服务 Pod 也是如此。
Cluster 超过 250 个节点 GKE 使用多达 250 个节点中的随机子集作为 Service NEG 的端点,即使节点不包含 Service 的服务 Pod 也是如此。
Local 任意数量的节点1 GKE 仅使用至少具有一个 Service 服务 Pod 的节点作为 Service NEG 的端点。

1限制为 3,000 个具有服务 Pod 的节点。集群中可以存在超过 3,000 个节点,但当 GKE 创建基于后端服务且使用 GCE_VM_IP NEG 后端的外部直通式网络负载均衡器时,仅支持创建最多 3,000 个端点。

单个负载均衡实例组限制

Compute Engine API 禁止虚拟机成为多个负载均衡实例组的成员。GKE 节点受到此限制的约束。

使用非代管实例组后端时,GKE 会创建或更新非代管实例组,其中包含集群使用的每个可用区中所有节点池的所有节点。这些非代管实例组用于:

  • 停用 GKE 子集时为内部 LoadBalancer Service 创建的内部直通式网络负载均衡器。
  • 使用 cloud.google.com/l4-rbs: "enabled" 注解为外部 LoadBalancer Service 创建的基于后端服务的外部直通式网络负载均衡器。
  • 使用 GKE Ingress 控制器取代容器原生负载均衡,为外部 GKE Ingress 资源创建的外部应用负载均衡器。

由于节点虚拟机不能成为多个负载均衡实例组的成员,因此如果满足以下任何一个条件,GKE 就无法创建和管理内部直通式网络负载均衡器、基于后端服务的外部直通式网络负载均衡器和外部应用,以及为 GKE Ingress 资源创建的外部应用负载均衡器

  • 在 GKE 外部,您创建了至少一个基于后端服务的负载均衡器,并使用集群的代管实例组作为负载均衡器后端服务的后端。
  • 在 GKE 外部,您可以创建包含集群的部分或所有节点的自定义非代管实例组,然后将该自定义非代管实例组关联到负载均衡器的后端服务。

如需解决此限制,您可以指示 GKE 尽可能使用 NEG 后端:

  • 启用 GKE 子集。因此,新的内部 LoadBalancer Service 会改用 GCE_VM_IP NEG。
  • 配置外部 GKE Ingress 资源以使用容器原生负载均衡。如需了解详情,请参阅 GKE 容器原生负载均衡

负载均衡器健康检查

所有 GKE LoadBalancer Service 都会实施负载均衡器健康检查。负载均衡器健康检查系统在集群外部运行,并且与 Pod 就绪性、活跃性或启动探测不同。

负载均衡器健康检查数据包由在每个节点上运行的 kube-proxy(旧版数据平面)或 cilium-agent (GKE Dataplane V2) 软件进行响应。LoadBalancer Service 的负载均衡器健康检查无法由 Pod 进行响应。

Service 的 externalTrafficPolicy 决定哪些节点可通过负载均衡器健康检查:

externalTrafficPolicy 哪些节点通过了健康检查 使用哪个端口
Cluster 集群的所有节点都会通过健康检查,包括没有服务 Pod 的节点。如果节点上存在至少一个服务 Pod,则该节点会通过负载均衡器健康检查,无论其 Pod 的状态如何。 负载均衡器的健康检查端口必须是 TCP 端口 10256。它无法自定义。
Local

如果节点上至少存在一个已就绪、未终止的服务 Pod,负载均衡器健康检查便会将相应节点视为健康状况良好,无论任何其他 Pod 的状态如何。没有服务 Pod 的节点、其服务 Pod 全部无法通过就绪性探测的节点以及服务 Pod 全部终止的节点将无法通过负载均衡器的健康检查。

在状态转换期间,节点仍会通过负载均衡器健康检查,直到达到负载均衡器健康检查的健康状况不佳阈值。当节点上的所有服务 Pod 开始无法通过就绪性探测或节点上的所有服务 Pod 终止时,转换状态会出现。在此情况下,数据包的处理方式取决于 GKE 版本。如需了解详情,请参阅下一部分数据包处理

除非您指定自定义健康检查端口,否则 Kubernetes 控制平面会从节点端口范围分配健康检查端口。

启用加权负载均衡后,kube-proxycilium-agent 软件会在其对负载均衡器健康检查的响应中包含响应标头。此响应标头定义的权重与节点上已就绪、未终止的服务 Pod 数量成正比。负载均衡器会根据此权重将新连接路由到服务 Pod。

数据包处理

以下部分详细介绍了负载均衡器和集群节点如何协同工作来路由为 LoadBalancer Service 接收的数据包。

直通式负载均衡

直通式网络负载均衡器将数据包路由到 GKE 集群节点的 nic0 接口。节点接收的每个负载均衡数据包都具有以下特征:

  • 数据包的目标 IP 地址与负载均衡器的转发规则 IP 地址匹配。
  • 数据包的协议和目标端口与以下两项匹配:
    • Service 清单的 spec.ports[] 中指定的协议和端口
    • 在负载均衡器的转发规则上配置的协议和端口

节点上的目标网络地址转换

节点接收数据包后,会执行其他数据包处理。在使用旧版数据平面的 GKE 集群中,节点使用 iptables 处理负载均衡数据包。在启用了 GKE Dataplane V2 的 GKE 集群中,节点会改用 eBPF。节点级层数据包处理始终包含以下操作:

  • 节点对数据包执行目标网络地址转换 (DNAT),将其目标 IP 地址设置为服务 Pod IP 地址。
  • 节点将数据包的目标端口更改为相应 Service 的 spec.ports[]targetPort

节点上的来源网络地址转换

externalTrafficPolicy 确定节点级数据包处理是否也执行来源网络地址转换 (SNAT),以及确定数据包从节点到 Pod 的路径:

externalTrafficPolicy 节点 SNAT 行为 路由行为
Cluster

在没有 GKE Dataplane V2 的 GKE 集群中,节点会更改负载均衡数据包的来源 IP 地址,以与从负载均衡器接收相应数据包的节点的 IP 地址相匹配。

在使用 GKE Dataplane V2 的 GKE 集群中,节点在将流量转发到同一节点上的服务 Pod 时,不会更改负载均衡数据包的来源 IP 地址。不过,如果流量被转发到其他节点上的 Pod,则会执行 SNAT。

节点将数据包路由到任何服务 Pod。服务 Pod 不一定位于同一节点上。

如果从负载均衡器接收数据包的节点缺少就绪和服务 Pod,则该节点会将数据包路由到包含就绪 Pod 和服务 Pod 的其他节点。Pod 的响应数据包会从其节点路由回到从负载均衡器接收请求数据包的节点。然后,第一个节点使用直接服务器返回功能将响应数据包发送到原始客户端。

Local 节点不会更改负载均衡数据包的来源 IP 地址。

在大多数情况下,节点会将数据包路由到在从负载均衡器接收数据包的节点上运行的服务 Pod。该节点使用直接服务器返回功能将响应数据包发送到原始客户端。这是此类流量政策的主要意图。

在某些情况下,即使节点缺少 Service 的已就绪、未终止的服务 Pod,也会从负载均衡器接收数据包。当负载均衡器的健康检查尚未达到其故障阈值,但之前的已就绪服务 Pod 不再就绪或正在终止(例如,执行滚动更新时)时,会出现此情况。这种情况下数据包的处理方式取决于 GKE 版本、集群是否使用 GKE Dataplane V2 以及 externalTrafficPolicy 的值:

  • 不使用 GKE Dataplane V2,在 GKE 1.26 及更高版本中;使用 GKE Dataplane V2,在 GKE 1.26.4-gke.500 及更高版本中,代理终止端点已启用。如果满足以下所有条件,作为最后的补救手段,数据包将路由到终止 Pod:
    • 所有服务 Pod 终止且 externalTrafficPolicyCluster
    • 节点上的所有服务 Pod 终止且 externalTrafficPolicyLocal
  • 对于所有其他 GKE 版本,数据包由节点的内核通过 TCP 重置进行响应。

价格和配额

网络价格适用于负载均衡器处理的数据包。如需了解详情,请参阅 Cloud Load Balancing 和转发规则价格。您还可以使用 Google Cloud 价格计算器来估算结算费用。

您可以创建的转发规则数由负载均衡器配额控制:

后续步骤