创建外部负载均衡器

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

说明: 此功能仅适用于支持外部负载均衡器的云提供商或环境。

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

有关如何配置和使用 Ingress 资源为服务提供外部可访问的 URL、负载均衡流量、终止 SSL 等功能, 请查看 Ingress 文档。

准备开始

  • 你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 如果你还没有集群,你可以通过 Minikube 构建一 个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:

    要获知版本信息,请输入 kubectl version.

配置文件

要创建外部负载均衡器,请将以下内容添加到 服务配置文件

    type: LoadBalancer

你的配置文件可能会如下所示:

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

使用 kubectl

你也可以使用 kubectl expose 命令及其 --type=LoadBalancer 参数创建服务:

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

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

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

找到你的 IP 地址

你可以通过 kubectl 获取服务信息,找到为你的服务创建的 IP 地址:

kubectl describe services example-service

这将获得如下输出:

    Name:                   example-service
    Namespace:              default
    Labels:                 <none>
    Annotations:            <none>
    Selector:               app=example
    Type:                   LoadBalancer
    IP:                     10.67.252.103
    LoadBalancer Ingress:   192.0.2.89
    Port:                   <unnamed> 80/TCP
    NodePort:               <unnamed> 32445/TCP
    Endpoints:              10.64.0.4:80,10.64.1.5:80,10.64.2.4:80
    Session Affinity:       None
    Events:                 <none>

IP 地址列在 LoadBalancer Ingress 旁边。

说明:

如果你在 Minikube 上运行服务,你可以通过以下命令找到分配的 IP 地址和端口:

minikube service example-service --url

保留客户端源 IP

由于此功能的实现,目标容器中看到的源 IP 将 不是客户端的原始源 IP。 要启用保留客户端 IP,可以在服务的 spec 中配置以下字段(支持 GCE/Google Kubernetes Engine 环境):

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

可以通过在服务的配置文件中将 externalTrafficPolicy 设置为 Local 来激活此功能。

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

回收负载均衡器

在通常情况下,应在删除 LoadBalancer 类型服务后立即清除云提供商中的相关负载均衡器资源。 但是,众所周知,在删除关联的服务后,云资源被孤立的情况很多。 引入了针对服务负载均衡器的终结器保护,以防止这种情况发生。 通过使用终结器,在删除相关的负载均衡器资源之前,也不会删除服务资源。

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

外部负载均衡器提供商

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

当服务 type 设置为 LoadBalancer 时,Kubernetes 向集群中的 Pod 提供的功能等同于 type 等于 ClusterIP,并通过使用 Kubernetes pod 的条目对负载均衡器(从外部到 Kubernetes) 进行编程来扩展它。 Kubernetes 服务控制器自动创建外部负载均衡器、健康检查(如果需要)、防火墙规则(如果需要), 并获取云提供商分配的外部 IP 并将其填充到服务对象中。

保留源 IP 时的注意事项和限制

GCE/AWS 负载均衡器不为其目标池提供权重。 对于旧的 LB kube-proxy 规则来说,这不是一个问题,它可以在所有端点之间正确平衡。

使用新功能,外部流量不会在 pod 之间平均负载,而是在节点级别平均负载 (因为 GCE/AWS 和其他外部 LB 实现无法指定每个节点的权重, 因此它们的平衡跨所有目标节点,并忽略每个节点上的 Pod 数量)。

但是,我们可以声明,对于 NumServicePods << NumNodesNumServicePods >> NumNodes 时, 即使没有权重,也会看到接近相等的分布。

一旦外部负载平衡器提供权重,就可以将此功能添加到 LB 编程路径中。 未来工作:1.4 版本不提供权重支持,但可能会在将来版本中添加

内部 Pod 到 Pod 的流量应该与 ClusterIP 服务类似,所有 Pod 的概率相同。

最后修改 August 16, 2020 at 11:05 AM PST : [zh] Tidy up and fix links in tasks section (8/10) (c2aae6890)