Kubernetes 如何负载平衡外部持久 tcp 连接?

Kubernetes how to load balance EXTERNAL persistent tcp connections?

我在与我的 kubernetes 副本的负载平衡持久 tcp 连接方面遇到问题。

我在 kubernetes 集群之外有 Unity3D 客户端。

我的集群是一个安装了 metallb 的裸机集群,由 3 个节点组成:1 个主节点和 2 个工作节点。

据我所知,有两种方法:

1) 客户端连接到所有副本,每次它需要发送请求时,它将在它之前建立的那些随机连接上执行此操作。它会定期刷新连接(以防发生自动缩放或某些持久连接死亡)。

这里的问题是,我不确定如何从外部访问所有副本,headless services 不能暴露在外部。

2) 服务网格?我隐约 read/understood 他们可能会代表您建立持久的 tcp。所以像这样:

unity3d客户端<----持久连接--->控制器<---持久连接---->副本

但是,我不确定如何完成此操作,并且我不确定如果控制器本身出现故障会发生什么情况,所有客户端的连接都会断开吗?正如我所看到的,它会归结为与 1) 中的问题相同的问题,它允许客户端使用持久的 TCP 连接同时连接到多个不同的副本。

部分问题是对此的补充:https://learnk8s.io/kubernetes-long-lived-connections

为了启用到集群的外部流量,您需要一个 Ingress Gateway。您的入口网关可以是 the standard nginx Ingress, a gateway provided by a mesh like the Istio Gateway or a more specialized edge gateway like ambassador, traefik、kong、gloo 等

至少有两种方式可以在K8s中进行负载均衡:

  1. 使用 Service 资源,它只是一组由 kube-proxy 进程管理的 iptables 规则。这只是 L4 负载平衡。不支持 HTTP2 或 gRPC 等 L7 应用程序协议。根据您的情况,这种类型的 LB 可能不适合长期连接,因为连接很少会关闭。

  2. 使用任何 ingress controllers 提供的 L7 负载平衡将跳过 iptables 路由(使用无头服务)并允许更高级的负载平衡算法。

为了从后一种情况中受益,您仍然需要确保连接最终终止,这通常是从客户端到代理完成的(同时重用从代理到上游的连接)。我不熟悉 Unity3D 连接,但如果终止它们不是一个选项,那么你将无法进行太多负载平衡。

当控制器出现故障时,连接将被断开,您的客户端可能会优雅地重新尝试连接或出现恐慌。这取决于你如何编码。