创建外部负载均衡器

本文展示如何创建一个外部负载均衡器。

创建服务时,你可以选择自动创建云网络负载均衡器。 负载均衡器提供外部可访问的 IP 地址,可将流量发送到集群节点上的正确端口上 (假设集群在支持的环境中运行,并配置了正确的云负载均衡器驱动包)。

你还可以使用 Ingress 代替 Service。 更多信息,请参阅 Ingress 文档。

准备开始

你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:

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

创建服务

基于清单文件创建服务

要创建外部负载均衡器,请将以下内容添加到你的 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 参数创建服务:

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

此命令通过使用与引用资源(在上面的示例的情况下,名为 exampleDeployment) 相同的选择器来创建一个新的服务。

更多信息(包括更多的可选参数),请参阅 kubectl expose 指南

找到你的 IP 地址

你可以通过 kubectl 获取服务信息,找到为你的服务创建的 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,可以在服务的 .spec 中配置以下字段:

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

可以通过在服务的清单文件中将 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 后立即清除云服务供应商中的相关负载均衡器资源。 但是,众所周知,在删除关联的服务后,云资源被孤立的情况很多。 引入了针对服务负载均衡器的终结器保护,以防止这种情况发生。 通过使用终结器,在删除相关的负载均衡器资源之前,也不会删除服务资源。

具体来说,如果服务具有 type LoadBalancer,则服务控制器将附加一个名为 service.kubernetes.io/load-balancer-cleanup 的终结器。 仅在清除负载均衡器资源后才能删除终结器。 即使在诸如服务控制器崩溃之类的极端情况下,这也可以防止负载均衡器资源悬空。

外部负载均衡器供应商

请务必注意,此功能的数据路径由 Kubernetes 集群外部的负载均衡器提供。

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

接下来