处理 Kubernetes Pod 业务流量长连接负载不均衡问题
解决Kubernetes APIServer流量不均衡问题 问题扩展,业务 Pod 长连接处理不均衡问题解决
负载不均衡常见场景
滚动更新负载不均
在连接数比较固定或波动不大
的情况下,滚动更新时,旧 Pod 上的连接逐渐断掉,重连到新启动的 Pod 上,越先启动的 Pod 所接收到的连接数越多,造成负载不均
rr (round-robin) 策略负载不均
长连接服务的不同连接的保持时长差异很大,而 ipvs 转发
时默认是 rr 策略
转发,如果某些后端 Pod “运气较差”,它们上面的连接保持时间比较较长,而由于是 rr 转发,它们身上累计的连接数就可能较多,节点上通过 ipvsadm -Ln -t CLUSTER-IP:PORT
查看某个 service
的转发情况:
$ ipvsadm -Ln -t 10.0.1.96:50001
-> 10.0.10.214:50001 Masg 1 1 104
-> 10.0.10.222:50001 Masg 1 7 98
-> 10.0.15.11:50001 Masg 1 17 120
-> 10.0.15.151:50001 Masg 1 9 96
...
部分 Pod 连接数高,意味着相比连接数低的 Pod 要同时处理更多的连接,着消耗的资源也就相对更多,从而造成负载不均。
将 kube-proxy
的 ipvs 转发
模式设置为 lc (Least-Connection)
,即倾向转发给连接数少的 Pod,可能会有所缓解,但也不一定,因为 ipvs 的负载均衡状态
是分散在各个节点的,并没有收敛到一个地方,也就无法在全局层面感知哪个 Pod 上的连接数少,并不能真正做到 lc。可以尝试设置为 sh (Source Hashing)
,并且这样可以保证即便负载均衡状态没有收敛到同一个地方,也能在全局尽量保持负载均衡
。
扩容失效
在连接数比较固定或波动不大的情况下,工作负载在 HPA
自动扩容时,由于是场链接,连接数又比较固定,所有连接都 “固化” 在之前的 Pod 上,新扩出的 Pod 几乎没有连接,造成之前的 Pod 高负载,而扩出来的 Pod 又无法分担压力,导致扩容失效:
解决方式
-
- 服务注册发现,
周期性定时重连
可用后端PodIP
或者 一个连接中处理的请求数达到阈值后自动重连
;
- 服务注册发现,
-
- 通过
ingress provider
七层代理访问:Nginx ingress 转发 gRPC 请求
; 参考:Nginx ingress 转发 gRPC 请求
- 通过
-
- kube-proxy 的 ipvs 转发策略设置为 sh (
--ipvs-scheduler=sh
);
- kube-proxy 的 ipvs 转发策略设置为 sh (
「如果这篇文章对你有用,请随意打赏」
FEATURED TAGS
agent
apiserver
application
bandwidth-limit
cgo
cgroupfs
ci/cd
client-go
cloudnative
cncf
cni
community
container
container-network-interface
containerd
controller
coredns
crd
custom-controller
deployment
docker
docker-build
docker-image
drop
ebpf
ecology
egress
etcd
gitee
github
gitlab
golang
governance
hpa
http2
image
ingress
iptables
jobs
kata
kata-runtime
kernel
kind
kubelet
kubenetes
kubernetes
library
linux-os
logging
loki
metrics
monitor
namespace
network
network-troubleshooting
node
nodeport
pingmesh
pod
prestop
prometheus
proxyless
pvc
rollingupdate
schedule
scheduler
serverless
sidecar
sigtrem
systemd
throttling
timeout
tools
traceroute