创建外部负载均衡器
本页面展示了如何创建一个外部负载均衡器。
创建 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
此命令使用与引用资源相同的选择器(在上述示例中,一个名为 example
的 Deployment)创建了一个新的 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
旁边。
注意
如果你在 Minikube 上运行 Service,可以使用以下命令找到分配的 IP 地址和端口:
minikube service example-service --url
保留客户端源 IP
默认情况下,目标容器中看到的源 IP 不是客户端的原始源 IP。要启用客户端 IP 的保留,可以在 Service 的 .spec
中配置以下字段:
.spec.externalTrafficPolicy
- 指示此 Service 是否希望将外部流量路由到节点本地或集群范围的端点。有两个可用选项:Cluster
(默认)和Local
。Cluster
会模糊客户端源 IP,并可能导致流量跳转到另一个节点,但通常具有良好的负载分发效果。Local
保留客户端源 IP,并避免 LoadBalancer 和 NodePort 类型 Service 的二次跳转,但可能存在流量分布不均的风险。.spec.healthCheckNodePort
- 指定 Service 的健康检查节点端口(数字端口号)。如果你未指定healthCheckNodePort
,则服务控制器会从集群的 NodePort 范围分配一个端口。
你可以通过设置 API 服务器命令行选项--service-node-port-range
来配置该范围。如果 Service 的type
设置为 LoadBalancer 且externalTrafficPolicy
设置为Local
,Service 将使用用户指定的healthCheckNodePort
值(如果指定)。
在 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 << NumNodes
或 NumServicePods >> NumNodes
时,即使没有权重,也会看到一个相当接近的均匀分布。
内部 Pod 到 Pod 的流量应该与 ClusterIP 服务类似,所有 Pod 具有相等的概率。
垃圾回收负载均衡器
通常情况下,在删除 LoadBalancer 类型的 Service 后,云提供商中相关的负载均衡器资源应立即被清理。但已知存在各种极端情况,导致相关 Service 被删除后云资源被孤立。为了防止这种情况发生,引入了 Service 负载均衡器的 Finalizer 保护机制。通过使用 Finalizer,Service 资源在相关负载均衡器资源也被删除之前永远不会被删除。
具体来说,如果一个 Service 的 type
是 LoadBalancer,Service 控制器会附加一个名为 service.kubernetes.io/load-balancer-cleanup
的终结器。该终结器只会在负载均衡器资源被清理后才会被移除。这可以防止即使在 Service 控制器崩溃等极端情况下出现悬空负载均衡器资源。
外部负载均衡器提供商
重要的是要注意,此功能的数据路径由 Kubernetes 集群外部的负载均衡器提供。
当 Service 的 type
设置为 LoadBalancer 时,Kubernetes 为集群内的 Pods 提供与 type
等于 ClusterIP 相同的功能,并通过对(Kubernetes 外部的)负载均衡器进行编程来扩展此功能,使其包含托管相关 Kubernetes Pods 的节点的条目。Kubernetes 控制平面自动化外部负载均衡器的创建、健康检查(如果需要)和包过滤规则(如果需要)。一旦云提供商为负载均衡器分配了 IP 地址,控制平面就会查找该外部 IP 地址并将其填充到 Service 对象中。
下一步
- 请参阅使用 Service 连接应用程序教程
- 了解 Service
- 了解 Ingress