【问题标题】:How to manage persistent connections in kubernetes如何在 Kubernetes 中管理持久连接
【发布时间】:2019-12-01 03:24:06
【问题描述】:

在 Kubernetes 中,服务通过服务 ip 相互通信。使用 iptables 或类似的东西,每个 TCP 连接都被透明地路由到可用于被调用服务的 pod 之一。如果调用服务没有关闭 TCP 连接(例如,使用 TCP keepalive 或连接池),它将连接到一个 pod,而不使用可能产生的其他 pod。

处理这种情况的正确方法是什么?


我自己不满意的想法:

每次 api 调用后关闭连接

为了将请求分发到不同的 pod,我是否让每次调用都变慢了?感觉不对。

最少连接数

我可以强制调用者打开多个连接(假设它会在这些连接之间分配请求)但是应该打开多少个?调用者(可能不应该)不知道有多少个 pod。

禁用突发

我可以限制被调用服务的资源,使其在多个请求时变慢,并且调用者将打开更多连接(希望与其他 pod)。同样,我不喜欢任意减慢请求速度的想法,这仅适用于 cpu 绑定服务。

【问题讨论】:

    标签: kubernetes kube-proxy


    【解决方案1】:

    keep-alive 行为可以通过 Keep-Alive 通用标头中指定的选项进行调整:

    例如:

    Connection: Keep-Alive
    Keep-Alive: max=10, timeout=60
    

    因此,您可以在特定超时后重新打开 tcp 连接,而不是在每个 API 请求或最大数量的 http 事务之后。

    请记住,超时和最大值无法保证。

    编辑:

    注意如果你使用k8s服务可以选择两种LB模式:

    • iptables 代理模式(默认情况下,iptables 模式下的 kube-proxy 会随机选择一个后端。)

    • 具有不同负载平衡选项的 IPVS 代理模式:

    IPVS 提供了更多用于平衡后端 Pod 流量的选项;这些是:

    rr:循环 lc:最少连接(打开连接的最少数量) dh:目标哈希 sh:源散列 sed:最短的预期延迟 nq:从不排队

    查看this link

    【讨论】:

    • 我认为这对我的情况没有帮助。仍然会有一个 pod 接收所有请求,而其他 pod 则处于空闲状态。还是我错过了什么?
    • 在 TCP 连接过期后(由于超时或最大连接),客户端会打开一个新的 TCP 连接,这一次可能会分配到另一个 pod(pod 之间概率相等)。假设您使用的是 k8s 服务。
    • 我更新了我的回复以更好地回答您的问题
    • 嗯,很有趣。但是,如果服务没有关闭连接,并且一个连接足以处理所有请求(但前提是允许突发),这对我有帮助吗?
    • 如果您使用该标头初始化连接,则连接将在超时或最大 http 请求数后关闭。
    【解决方案2】:

    执行此操作的一种机制可能是在 TCP 连接终止下方的层中进行负载平衡。例如,如果您将服务一分为二 - 一个微服务(我们称之为 frontend-svc)负责连接处理和一些身份验证,另一个单独的服务负责您的业务逻辑/处理。

    clients <---persistent connection---> frontend-svc <----GRPC----> backend-svc
    

    frontend-svc 可以以更精细的方式维护对后端的 make 调用,例如使用 GRPC,并在下层的工作人员之间实现真正的负载平衡。这意味着作为 frontend-svc 一部分的 pod 没有做太多工作并且完全无状态(因此不需要负载平衡),这意味着您也可以使用 HPA 控制它们,前提是您有一些耗尽逻辑确保您不会终止现有连接。


    这是 SSL 代理等用来处理与 LB 分开的连接终止的常用方法。

    【讨论】:

    猜你喜欢
    • 2018-10-15
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 2013-08-09
    相关资源
    最近更新 更多