创建外部负载均衡器

本页面展示如何创建外部负载均衡器。

创建 Service 时,你可以选择自动创建云负载均衡器。这提供了一个外部可访问的 IP 地址,可将流量发送到集群节点的正确端口,*前提是你的集群运行在受支持的环境中,并且配置了正确的云负载均衡器提供商包*。

你也可以使用 Ingress 来代替 Service。更多信息请查看 Ingress 文档。

准备工作

你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具需要配置为与你的集群通信。建议在至少有两个非控制平面主机节点的集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者使用以下 Kubernetes 演练场之一:

你的集群必须运行在已经支持配置外部负载均衡器的云或其他环境中。

创建 Service

从清单文件创建 Service

要创建外部负载均衡器,请在你的 Service 清单中添加以下行:

    type: LoadBalancer

你的清单文件可能看起来像这样:

apiVersion: v1
kind: Service
metadata:
  name: example-service
spec:
  selector:
    app: example
  ports:
    - port: 8765
      targetPort: 9376
  type: LoadBalancer

使用 kubectl 创建 Service

你也可以使用 kubectl expose 命令及其 --type=LoadBalancer 标志来创建 Service:

kubectl expose deployment example --port=8765 --target-port=9376 \
        --name=example-service --type=LoadBalancer

该命令使用与引用资源(在上例中是一个名为 exampleDeployment)相同的选择器创建新的 Service。

有关更多信息,包括可选标志,请参阅 kubectl expose 参考

查找你的 IP 地址

你可以通过 kubectl 获取 Service 信息来查找为你的 Service 创建的 IP 地址:

kubectl describe services example-service

输出应类似于:

Name:                     example-service
Namespace:                default
Labels:                   app=example
Annotations:              <none>
Selector:                 app=example
Type:                     LoadBalancer
IP Families:              <none>
IP:                       10.3.22.96
IPs:                      10.3.22.96
LoadBalancer Ingress:     192.0.2.89
Port:                     <unset>  8765/TCP
TargetPort:               9376/TCP
NodePort:                 <unset>  30593/TCP
Endpoints:                172.17.0.3:9376
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

负载均衡器的 IP 地址列在 LoadBalancer Ingress 旁边。

保留客户端源 IP

默认情况下,在目标容器中看到的源 IP *不是*客户端的*原始源 IP*。要启用客户端 IP 的保留,可以在 Service 的 .spec 中配置以下字段:

  • .spec.externalTrafficPolicy - 表示此 Service 是否希望将外部流量路由到节点本地或集群范围的端点。有两个可用选项:Cluster(默认)和 LocalCluster 会模糊客户端源 IP 并可能导致跳到另一个节点的二次跳转,但应具有良好的整体负载分摊。Local 保留客户端源 IP 并避免 LoadBalancer 和 NodePort 类型 Service 的二次跳转,但存在潜在的流量分配不均衡的风险。
  • .spec.healthCheckNodePort - 指定 Service 的健康检查节点端口(数字端口号)。如果你未指定 healthCheckNodePort,则 Service 控制器会从集群的 NodePort 范围分配一个端口。
    你可以通过设置 API 服务器命令行选项 --service-node-port-range 来配置该范围。如果你指定了 healthCheckNodePort,Service 将使用用户指定的值,前提是 Service 的 type 设置为 LoadBalancer 并且 externalTrafficPolicy 设置为 Local

在 Service 清单中将 externalTrafficPolicy 设置为 Local 会激活此功能。例如:

apiVersion: v1
kind: Service
metadata:
  name: example-service
spec:
  selector:
    app: example
  ports:
    - port: 8765
      targetPort: 9376
  externalTrafficPolicy: Local
  type: LoadBalancer

保留源 IP 时的注意和限制

某些云提供商的负载均衡服务不允许你为每个目标配置不同的权重。

在向节点发送流量方面,如果每个目标的权重相等,那么外部流量在不同 Pod 之间的负载均衡就不均等。外部负载均衡器不知道每个节点上有多少 Pod 被用作目标。

如果 NumServicePods << NumNodesNumServicePods >> NumNodes,即使没有权重,也会看到相当接近均匀的分布。

内部 Pod 到 Pod 的流量应类似于 ClusterIP 服务,在所有 Pod 之间具有相同的概率。

负载均衡器的垃圾回收

特性状态: Kubernetes v1.17 [stable]

通常情况下,云提供商中的关联负载均衡器资源应在 LoadBalancer 类型 Service 删除后立即清理。但已知存在各种极端情况,其中云资源在关联 Service 删除后成为孤立资源。引入 Service LoadBalancer 的 Finalizer 保护是为了防止这种情况发生。通过使用 Finalizer,Service 资源在关联负载均衡器资源也被删除之前,永远不会被删除。

具体来说,如果 Service 的 type 为 LoadBalancer,则 Service 控制器会附加一个名为 service.kubernetes.io/load-balancer-cleanup 的 Finalizer。该 Finalizer 仅在负载均衡器资源被清理后移除。即使在 Service 控制器崩溃等极端情况下,这也能防止出现悬空的负载均衡器资源。

外部负载均衡器提供商

重要的是要注意,此功能的网络路径由 Kubernetes 集群外部的负载均衡器提供。

当 Service 的 type 设置为 LoadBalancer 时,Kubernetes 为集群内的 Pod 提供等同于 type 为 ClusterIP 的功能,并通过编程(Kubernetes 外部的)负载均衡器,为其添加托管相关 Kubernetes Pod 的节点条目来扩展此功能。Kubernetes 控制平面自动化创建外部负载均衡器、健康检查(如果需要)和包过滤规则(如果需要)。一旦云提供商为负载均衡器分配了 IP 地址,控制平面会查找该外部 IP 地址并将其填充到 Service 对象中。

下一步

最后修改于 太平洋标准时间 2023 年 10 月 22 日下午 6:49:修复了页面 “创建外部负载均衡器” 上的一个错别字 (28c7a312af)