如何在 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。
我必须在 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。