如何在 GCP 中的 kubernetes 负载均衡器上通过客户端 IP 启用会话亲和力

How can I enable session affinity by client IP on a kubernetes loadbalancer in GCP

我必须在 GCP Kubernetes 集群中设置一个 FTP 服务器,并且不知道如何路由客户端,以便从同一 IP 到不同端口的多个请求被路由到同一个 Kubernetes pod。

在(被动)FTP协议中,服务器端开辟一个新端口,并将端口号发送给客户端。然后客户端创建到该端口的新连接。因此,我需要确保第二个请求被路由到同一个 pod,因为只有那个 pod 上的服务器正在等待新连接。

我尝试了一个最小样本,工作负载为两个 pods,什么都不做,并且暴露了端口 21 和 30000-30098。然后,我如下设置 LoadBalancer 类型的服务(减少到相关部分):

kind: Service
spec:
    type: LoadBalancer
    sessionAffinity: ClientIP
    loadBalancerIP: IP_OF_LB
    ports:
    - name: ftp-control
      port: 21
      protocol: TCP
      targetPort: 21
    - name: pasv-30000
      port: 30000
      protocol: TCP
      targetPort: 30000
      # and so on for the remaining ports up to 30098

现在我用 shell 登录每个 pods,然后我开始手动监听一个端口,如下所示:

netcat -l -p 30001

然后,我从我的工作站使用 telnet 连接到负载均衡器的 IP 地址。

telnet IP_OF_LB 30001

这样,我就可以看到哪个 pod 收到了传入的连接请求。

对于单个端口,负载均衡器始终将我的请求转发到同一个 pod。

但是,当我尝试多个端口时,我可以看到后续请求被路由到不同的 pods,即使会话关联设置为 ClientIP

有没有我遗漏的设置?我假设,客户端 IP 的会话亲和力只会使用客户端的 IP 来确定目标 pod。但是,它看起来好像正在使用 IP 和端口。

有谁知道是否有更多设置可以让我尝试获得所需的行为?

我可以看到你将服务配置为LoadBalancer 类型,但是在其上配置session affinity 会很麻烦。因此,我实际上建议执行以下操作:

Backend config -> Nodeport service -> Ingress

请使用 client IP affinity and Backend Configs 查看更多信息。

我在 Google 上发布了错误报告,他们说这是预期的行为: bug report

我假设如果我定义了一个负载均衡器类型的 Kubernetes 服务,那么负载就会在 pod 级进行均衡。相反,负载平衡器会在 VM 的基础上平衡流量。

很明显,流量平衡了两次。首先,负载均衡器将流量分配给虚拟机,然后 Kubernetes 将该流量均衡到不同的 pods.

这意味着,会话亲和力不适用于 Google Kubernetes 引擎中的负载均衡器和 Kubernetes。