部署在Kubernetes上的Streamlit应用每30秒自动重载求助
Streamlit应用在Kubernetes Nginx Ingress下每30秒自动重载问题排查与解决思路
问题背景
部署在Kubernetes环境中的Streamlit数据下载UI,通过端口转发访问完全正常,但通过Nginx Ingress访问时,应用每30秒会自动重载。浏览器开发者工具网络面板显示WebSocket连接约30秒超时,曾尝试添加Nginx连接排空注解、修改Streamlit源码中Tornado的websocket_ping_timeout参数并重新构建镜像,均未解决问题。
解决思路
1. 修正Nginx Ingress的WebSocket转发配置
Streamlit依赖WebSocket维持实时交互,Nginx默认配置可能未正确处理WebSocket连接,需在Ingress注解中添加以下配置:
nginx.ingress.kubernetes.io/websocket-services: "streamlit-service" nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600" nginx.ingress.kubernetes.io/proxy-set-header: "Upgrade $http_upgrade" nginx.ingress.kubernetes.io/proxy-set-header: "Connection \"upgrade\""
这些配置确保Nginx正确识别并转发WebSocket升级请求,同时延长代理超时时间,避免因连接提前断开触发Streamlit重载。
2. 适配Ingress子路径配置
当前Ingress使用了路径重写规则/webapp(/|$)(.*)和rewrite-target: /$2,可能导致WebSocket请求路径不匹配。解决方案:
- 启动Streamlit时添加
--server.baseUrlPath /webapp参数,让应用知晓自身运行在子路径下,自动调整WebSocket请求路径 - 若无需子路径,可临时将Ingress路径改为根路径
/测试,确认是否为重写规则导致的问题
3. 调整Service会话亲和性
虽然当前为单副本,但开启会话亲和性可避免后续扩容时WebSocket连接被分发到不同Pod:
spec: sessionAffinity: ClientIP
4. 正确配置Streamlit的WebSocket超时
无需修改源码,通过启动参数或配置文件即可调整超时时间:
- 启动命令添加参数:
streamlit run app.py --server.websocketPingTimeout 300(设置为300秒) - 或在应用目录创建
.streamlit/config.toml:
[server] websocketPingTimeout = 300
确保容器启动时加载该配置文件。
5. 排查集群网络限制
- 检查Kubernetes网络策略,是否存在限制WebSocket连接时长的规则
- 确认Nginx Ingress Controller的全局配置,是否有全局超时设置覆盖了Ingress注解的配置
内容的提问来源于stack exchange,提问作者fuubarbaz
相关产品推荐
相关产品推荐

