Kubernetes Service IP访问WebSocket 30秒自动断开问题求助
Kubernetes v1.18 iptables模式下WebSocket服务通过Service访问断连问题解决方案
问题根源
你的问题核心是kube-proxy iptables模式下的连接跟踪(conntrack)超时机制导致的:v1.18版本中,iptables依赖netfilter的conntrack模块跟踪连接,默认对TCP已建立连接的超时设置(部分环境为30秒)会将无数据交互的WebSocket长连接判定为空闲,主动切断连接。而直接访问Pod IP时,流量不经过kube-proxy的iptables规则,因此不受此限制。
iptables模式下访问WebSocket服务的注意事项
- 连接跟踪超时规则:必须关注conntrack模块的TCP超时参数,默认值通常不适合WebSocket这类长连接场景
- kube-proxy的连接清理逻辑:kube-proxy会定期清理conntrack表,无心跳的长连接易被误判为失效连接
- 会话保持的匹配性:若Service启用了
sessionAffinity: ClientIP,需确保会话保持的超时时间与WebSocket的存活周期匹配,避免因会话过期导致连接断开
解决配置
1. 调整节点conntrack超时参数
在集群所有节点上执行以下操作,修改TCP已建立连接的超时时间:
# 临时生效 sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=86400 # 永久生效,编辑/etc/sysctl.conf添加以下行 echo "net.netfilter.nf_conntrack_tcp_timeout_established=86400" >> /etc/sysctl.conf sysctl -p
说明:将超时时间设置为86400秒(24小时),可根据业务需求调整为合适时长
2. 修改kube-proxy配置
编辑kube-proxy的DaemonSet配置,添加conntrack相关启动参数:
kubectl edit daemonset kube-proxy -n kube-system
在args字段中添加或修改:
args: - --conntrack-tcp-timeout-established=86400 - --conntrack-max-per-core=32768 # 可选,增大单核心连接跟踪上限,避免连接数不足 - --conntrack-tcp-timeout-close-wait=60
保存后重启kube-proxy:
kubectl rollout restart daemonset kube-proxy -n kube-system
3. 配置WebSocket服务心跳
即使调整了超时参数,建议在WebSocket服务中添加定期ping/pong心跳机制,每15-20秒发送一次心跳帧,避免中间网络设备(如防火墙、负载均衡)因连接空闲而主动断开。
验证步骤
- 查看当前conntrack超时设置:
sysctl net.netfilter.nf_conntrack_tcp_timeout_established - 确认kube-proxy配置生效:
kubectl get daemonset kube-proxy -n kube-system -o yaml | grep conntrack - 查看连接跟踪状态:
conntrack -L | grep <你的Service IP>
内容的提问来源于stack exchange,提问作者nil
相关产品推荐
相关产品推荐

