本页面简要介绍在应用 Kubernetes LoadBalancer Services 清单时 Google Kubernetes Engine (GKE) 如何创建和管理 Google Cloud 负载均衡器。其中介绍了不同类型的负载均衡器以及 externalTrafficPolicy
和 L4 内部负载均衡器的 GKE 子集等设置决定了负载均衡器的配置方式。
在阅读本页面内容之前,您应该先熟悉 GKE 网络概念。
概览
创建 LoadBalancer Service 时,GKE 会配置一个 Google Cloud 直通式负载均衡器,其特征取决于 Service 清单的参数。
选择 LoadBalancer Service
在选择要使用哪个 LoadBalancer 服务配置时,请考虑以下几个方面:
- LoadBalancer 的 IP 地址的类型。负载均衡器可以具有内部或外部 IP 地址。
- LoadBalancer 支持的节点数量和类型。
在确定您的网络架构要求后,使用以下决策树来确定为网络配置选择哪个 LoadBalancer Service。
外部负载均衡与内部负载均衡
在 GKE 中创建 LoadBalancer Service 时,请指定负载均衡器是具有内部还是外部地址:
如果客户端位于同一 VPC 网络或连接到集群 VPC 网络的网络,则使用内部 LoadBalancer Service。 内部 LoadBalancer Service 通过使用内部直通式网络负载均衡器实现。位于同一 VPC 网络或连接到集群 VPC 网络的网络中的客户端可以使用负载均衡器的 IP 地址访问 Service。
如需创建内部 LoadBalancer Service,请在 Service 清单的
metadata.annotations[]
中添加以下注解之一:networking.gke.io/load-balancer-type: "Internal"
(GKE 1.17 及更高版本)cloud.google.com/load-balancer-type: "Internal"
(1.17 之前的版本)
如果客户端位于 VPC 网络外部,则使用外部 LoadBalancer Service。您可以使用可通过互联网访问的以下某一类型的外部直通式网络负载均衡器(包括可访问互联网的 Google Cloud 虚拟机):
- (推荐)通过在清单的
metadata.annotations[]
中添加以下内容来创建基于后端服务的外部直通式网络负载均衡器:cloud.google.com/l4-rbs: "enabled"
- 通过省略
cloud.google.com/l4-rbs: "enabled"
注解来创建基于目标池的外部直通式网络负载均衡器。
- (推荐)通过在清单的
externalTrafficPolicy
的作用
您可以将 externalTrafficPolicy
设置为 Local
或 Cluster
,以定义数据包如何路由到具有就绪 Pod 和服务 Pod 的节点。定义 externalTrafficPolicy
时,请考虑以下情况:
如果保留原始客户端 IP 地址,或者如果您希望在集群中没有服务 Pod 的节点数量发生变化时最大限度地减少中断,请使用
externalTrafficPolicy: Local
。如果集群中没有服务 Pod 的节点总数保持不变,但具有服务 Pod 的节点数量发生变化,请使用
externalTrafficPolicy: Cluster
。此选项不会保留原始客户端 IP 地址。
如需详细了解 externalTrafficPolicy
如何影响节点中的数据包路由,请参阅数据包处理。
GKE 子集
L4 内部负载均衡器的 GKE 子集集群级配置选项(或 GKE 子集)可更高效地将负载均衡器后端的节点端点分组,从而提高内部直通式网络负载均衡器的可伸缩性。
下图显示了启用三个节点和 GKE 子集的可用区级集群中的两个 Service。每个 Service 都有两个 Pod。GKE 会为每个 Service 创建一个 GCE_VM_IP
网络端点组 (NEG)。每个 NEG 中的端点都是包含相应 Service 的服务 Pod 的节点。
您可以在创建集群或修改现有集群时启用 GKE 子集。启用后,您便无法停用 GKE 子集。如需了解详情,请参阅 GKE 子集。
GKE 子集需要:
- GKE 版本 1.18.19-gke.1400 或更高版本,以及
- 为集群启用的
HttpLoadBalancing
插件。默认情况下,此插件处于启用状态。它允许集群管理使用后端服务的负载均衡器。
启用 GKE 子集化时的节点数注意事项
作为最佳实践,如果需要创建内部 LoadBalancer Service,您应启用 GKE 子集化。通过 GKE 子集化,您可以支持集群中的更多节点:
如果集群停用了 GKE 子集化,则创建的节点总数(总计所有节点池)不应超过 250 个。如果您在集群中创建的节点总数超过 250 个,则内部 LoadBalancer Service 可能会遇到流量分配不均匀或连接完全中断。
如果集群启用了 GKE 子集化,您可以使用
externalTrafficPolicy: Local
或externalTrafficPolicy: Cluster
,前提是至少具有一个服务 Pod 的唯一节点的数量不超过 250 个。没有任何服务 Pod 的节点无关。如果您需要的至少具有一个服务 Pod 的节点的数量超过 250 个,则必须使用externalTrafficPolicy: Cluster
。
GKE 创建的内部直通式网络负载均衡器只能向 250 个或更少的后端节点虚拟机分发数据包。存在此限制的原因是 GKE 不使用负载均衡器后端子集,并且在停用负载均衡器后端子集时内部直通式网络负载均衡器仅限于向 250 个或更少的后端分发数据包。
节点分组
Service 清单注解和(对于内部 LoadBalancer Service)GKE 子集化的状态决定了生成的 Google Cloud 负载均衡器和后端类型。Google Cloud 直通式负载均衡器的后端用于标识 GKE 节点的网络接口 (NIC),而不是特定节点或 Pod IP 地址。负载均衡器和后端的类型决定了节点如何分组到 GCE_VM_IP
NEG、实例组或目标池中。
GKE LoadBalancer Service | 生成的 Google Cloud 负载均衡器 | 节点分组方法 |
---|---|---|
在启用了 GKE 子集的集群中创建的内部 LoadBalancer Service1 | 内部直通式网络负载均衡器,其后端服务使用 GCE_VM_IP 网络端点组 (NEG) 后端 |
节点虚拟机根据 Service 的 Service 的 |
在停用 GKE 子集的集群中创建内部 LoadBalancer Service | 内部直通式网络负载均衡器,其后端服务使用可用区级非代管式实例组后端 | 所有节点虚拟机都会放入可用区级非代管式实例组中,供 GKE 用作内部直通式网络负载均衡器后端服务的后端。 Service 的 由于单个负载均衡实例组限制,相同的非代管实例组用于集群中创建的其他负载均衡器后端服务。 |
具有 cloud.google.com/l4-rbs: "enabled" 注释的外部 LoadBalancer Service2 |
基于后端服务的外部直通式网络负载均衡器,其后端服务使用可用区级非代管式实例组后端 | 所有节点虚拟机都会放入可用区级非代管式实例组中,供 GKE 用作外部直通式网络负载均衡器后端服务的后端。 Service 的 由于单个负载均衡实例组限制,相同的非代管实例组用于集群中创建的其他负载均衡器后端服务。 |
不带 cloud.google.com/l4-rbs: "enabled" 注释的外部 LoadBalancer Service3 |
基于目标池的外部直通式网络负载均衡器,其目标池包含集群的所有节点 | 目标池是一种不依赖于实例组的旧版 API。所有节点在目标池中都具有直接成员资格。 Service 的 |
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"
注解。
GCE_VM_IP
NEG 后端中的节点成员资格
为集群启用 GKE 子集后,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 个节点,用于内部 LoadBalancer Service。集群中可以存在超过 250 个节点,但是当停用内部直通式网络负载均衡器后端子集时,内部直通式网络负载均衡器仅分配给 250 个后端虚拟机。即使启用了 GKE 子集,GKE 也不会通过内部直通式网络负载均衡器后端子集配置内部直通式网络负载均衡器。如需详细了解此限制,请参阅每个内部后端服务的虚拟机实例数上限。
单个负载均衡实例组限制
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 都需要负载均衡器健康检查。负载均衡器的健康检查在集群外部实现,并且与就绪性或活跃性探测不同。
服务的 externalTrafficPolicy
定义了负载均衡器的健康检查的工作方式。在任何情况下,负载均衡器的健康检查探测器都会将数据包发送到每个节点上运行的 kube-proxy
软件。负载均衡器的健康检查是一个代理,由 kube-proxy
用于收集信息(例如 Pod 是否存在、正在运行并且已通过其就绪性探测)。LoadBalancer Service 的健康检查无法路由到服务 Pod。负载均衡器的健康检查旨在将新的 TCP 连接定向到节点。
下表介绍了健康检查的行为:
externalTrafficPolicy |
哪些节点通过了健康检查 | 使用哪个端口 |
---|---|---|
Cluster |
即使节点没有服务 Pod,集群的所有节点也都会通过健康检查。如果节点上存在一个或多个服务 Pod,则该节点会通过负载均衡器的健康检查,即使服务 Pod 终止或未通过就绪性探测也是如此。 | 负载均衡器的健康检查端口必须是 TCP 端口 10256。它无法自定义。 |
Local |
只有至少具有一个就绪、未终止服务 Pod 的节点才会通过负载均衡器的健康检查。没有服务 Pod 的节点、其服务 Pod 全部无法通过就绪性探测的节点以及服务 Pod 全部终止的节点将无法通过负载均衡器的健康检查。 在状态转换期间,节点仍会通过负载均衡器的健康检查,直到达到负载均衡器的健康状况不佳阈值。当节点上的所有服务 Pod 开始无法通过就绪性探测或节点上的所有服务 Pod 终止时,转换状态会出现。在此情况下,数据包的处理方式取决于 GKE 版本。如需了解详情,请参阅下一部分数据包处理。 |
除非您指定自定义健康检查端口,否则健康检查端口为 TCP 端口 10256。 |
数据包处理
以下部分详细介绍了负载均衡器和集群节点如何协同工作来路由为 LoadBalancer Service 接收的数据包。
直通式负载均衡
Google Cloud 直通式负载均衡器将数据包路由到 GKE 集群节点的 nic0
接口。节点接收的每个负载均衡数据包都具有以下特征:
- 数据包的目标 IP 地址与负载均衡器的转发规则 IP 地址匹配。
- 数据包的协议和目标端口与以下两项匹配:
- Service 清单的
spec.ports[]
中指定的协议和端口 - 在负载均衡器的转发规则上配置的协议和端口
- Service 清单的
节点上的目标网络地址转换
节点接收数据包后,会执行其他数据包处理。在未启用 GKE Dataplane V2 的 GKE 集群中,节点使用 iptables
处理负载均衡数据包。在启用了 GKE Dataplane V2 的 GKE 集群中,节点会改用 eBPF。节点级层数据包处理始终包含以下操作:
- 节点对数据包执行目标网络地址转换 (DNAT),将其目标 IP 地址设置为服务 Pod IP 地址。
- 节点将数据包的目标端口更改为相应 Service 的
spec.ports[]
的targetPort
。
节点上的来源网络地址转换
externalTrafficPolicy
确定节点级数据包处理是否也执行来源网络地址转换 (SNAT),以及确定数据包从节点到 Pod 的路径:
externalTrafficPolicy |
节点 SNAT 行为 | 路由行为 |
---|---|---|
Cluster |
该节点会更改负载均衡数据包的来源 IP 地址,以与从负载均衡器接收该数据包的节点的 IP 地址相匹配。 | 节点将数据包路由到任何服务 Pod。服务 Pod 不一定位于同一节点上。 如果从负载均衡器接收数据包的节点缺少就绪和服务 Pod,则该节点会将数据包路由到包含就绪 Pod 和服务 Pod 的其他节点。Pod 的响应数据包会从其节点路由回到从负载均衡器接收请求数据包的节点。然后,第一个节点使用直接服务器返回功能将响应数据包发送到原始客户端。 |
Local |
节点不会更改负载均衡数据包的来源 IP 地址。 | 在大多数情况下,节点会将数据包路由到在从负载均衡器接收数据包的节点上运行的服务 Pod。该节点使用直接服务器返回功能将响应数据包发送到原始客户端。这是此类流量政策的主要意图。 在某些情况下,即使节点缺少 Service 的已就绪、未终止的服务 Pod,也会从负载均衡器接收数据包。当负载均衡器的健康检查尚未达到其故障阈值,但之前的已就绪服务 Pod 不再就绪或正在终止(例如,执行滚动更新时)时,会出现此情况。这种情况下数据包的处理方式取决于 GKE 版本、集群是否使用 GKE Dataplane V2 以及
|
价格和配额
网络价格适用于负载均衡器处理的数据包。如需了解详情,请参阅 Cloud Load Balancing 和转发规则价格。您还可以使用 Google Cloud 价格计算器来估算结算费用。
您可以创建的转发规则数由负载均衡器配额控制:
- 内部直通式网络负载均衡器使用每项目后端服务配额、每项目健康检查配额和每虚拟私有云网络的内部直通式网络负载均衡器转发规则配额。
- 基于后端服务的外部直通式网络负载均衡器使用每项目后端服务配额、每项目健康检查配额和每项目外部直通式网络负载均衡器转发规则配额。
- 基于目标池的外部直通式网络负载均衡器使用每项目目标池配额、每项目健康检查配额和每项目外部直通式网络负载均衡器转发规则配额。