使用 Ingress 对 Kubernetes 中的 websocketconnections 进行基于 url 的负载平衡

Jen*_*ens 7 routing load-balancing websocket kubernetes nginx-ingress

我想nginx.ingress.kubernetes.io/upstream-hash-by用于多个客户端的 websocket 连接,其中相关客户端(基于 URL)应该坚持到同一个服务器。

当副本数量发生变化时,Ingress-nginx 似乎会重新平衡流量(pod 出现故障并将被新的自动替换,或者数量随着运行时规模而增加)。

重新平衡的问题在于它不会终止现有连接。因此,已经存在的 websocket 连接(对于已经散列的 URL)留在 pod A 上,而到同一 URL 的新连接突然分配到新生成的 pod B。

这是我的入口定义:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: websocket-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/upstream-hash-by: "$1"
spec:
  rules:
  - http:
      paths:
      - path: /socket-service/?clients/(.*)/.*
        backend:
          serviceName: websocket-test
          servicePort: 80
Run Code Online (Sandbox Code Playgroud)

是否有一种配置可以通过关闭“重新平衡”或自动终止现有连接来以某种方式控制这种行为?

Vit*_*Vit 0

我认为在这种情况下你可以看看EnvoyIstio 的方向。

\n\n

您可能对LoadBalancerSettings.ConsistentHashLB标志感兴趣:

\n\n
\n

基于一致哈希的负载平衡可用于提供基于 HTTP 标头、cookie 或其他属性的软\n 会话关联。\n 此负载平衡策略仅适用于 HTTP 连接。\n 与特定目标主机的关联将是当从目标服务添加/删除一台或多台主机时丢失。

\n
\n\n

来自Envoy 支持的负载均衡器 - 环哈希文档

\n\n
\n

环/模哈希负载均衡器对上游主机实施一致的哈希。每个主机通过散列其地址映射到一个圆(\xe2\x80\x9cring\xe2\x80\x9d);然后,通过散列请求的某些属性,并沿环顺时针方向找到最近的对应主机,将每个请求路由到主机。此技术通常也称为\n\n\n\xe2\x80\x9cKetama\xe2\x80\x9d 散列,并且与所有基于散列的负载均衡器一样,\n 仅当使用指定值的协议路由\n 时才有效\n散列。

\n\n

每个主机都经过哈希处理并按与其权重成正比的次数放置在环上。例如,如果主机 A 的权重为 1\n,主机 B 的权重为 2,则环上可能存在三个条目:一个用于主机 A,两个用于主机 B。这不会\xe2\x80然而,实际上并没有提供所需的 2:1 圆分区,因为计算出的哈希值可能巧合地彼此非常接近;因此,有必要乘以每个主机的哈希数\xe2\x80\x94例如\n 在主机 A 的环上插入 100 个条目,在主机 B\n B\xe2\x80\x94 的环上插入 200 个条目,以更好地近似所需的值分配。最佳实践是显式设置minimum_ring_size和maximum_ring_size,并监视min_hashes_per_host和max_hashes_per_host量表以确保良好的分布。通过适当地划分环,从一组 N 个主机中添加或删除一个主机将仅影响 1/N\n 个请求。

\n\n

当使用基于优先级的负载平衡时,优先级也是通过哈希选择的,因此当后端集稳定时,选择的端点仍然是一致的。

\n
\n