You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes中Nginx代理WebSocket超时50秒问题求助

问题描述

客户端应用通过Nginx代理(用于校验请求头)连接SSL加密的WebSocket应用,该WebSocket在正常使用时运行正常。本地环境下,空闲状态的WebSocket连接可通过Nginx的proxy_read_timeout维持正常连接;但部署到Kubernetes后,WebSocket连接会在约50.29±0.05秒时被强制断开。

环境信息

  • Kubernetes版本:
version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.16", GitCommit:"51e33fadff13065ae5518db94e84598293965939", GitTreeState:"clean", BuildDate:"2023-07-19T12:19:24Z", GoVersion:"go1.20.6", Compiler:"gc", Platform:"linux/amd64"}
  • 非公有云(如Google/AWS)环境
  • Ingress控制器:registry.k8s.io/ingress-nginx/controller:v1.9.3
  • 使用Octavia负载均衡器

已尝试的配置

Nginx配置片段

upstream myUpstream {
    server myUpstream:443;
    keepalive 32;
}

location /ws {
        proxy_http_version 1.1;
        proxy_pass_request_headers on;

        proxy_set_header Connection 'Upgrade';
        proxy_set_header Upgrade $http_upgrade;

        proxy_read_timeout 1800s;
        proxy_connect_timeout 1800s;
        proxy_send_timeout 1800s;
        send_timeout 1800s;

        proxy_pass http://myUpstream/ws;
}

Ingress资源注解

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "16m"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
    nginx.ingress.kubernetes.io/proxy-buffer-size: "256k"
  name: url-routing

测试时将proxy_read_timeout调低至30秒,连接会在30.29±0.05秒正常断开;同命名空间内另一个通过Nginx代理的WebSocket服务无此断开问题。

需明确:是什么因素强制触发了50秒的默认超时?如何在不添加WebSocket心跳的前提下解决该问题?


问题分析与解决方案

50秒超时的根源

这个50秒的超时大概率来自Octavia负载均衡器的默认空闲超时设置。Octavia的默认空闲连接超时就是50秒,当连接处于空闲状态时,负载均衡器会主动断开连接,这和你观察到的50.29±0.05秒的断开时间高度吻合。

同命名空间的另一个WebSocket服务无问题,可能是该服务本身存在隐性心跳机制(比如业务层定时发送小数据包),或者其关联的Octavia负载均衡器超时配置被单独修改过。

无心跳前提下的解决办法

1. 修改Octavia负载均衡器的空闲超时配置

通过OpenStack控制台或CLI工具,找到关联当前Ingress的Octavia负载均衡器,定位到对应的HTTP/HTTPS listener,将其**空闲超时(idle timeout)**设置为目标时长(比如和Nginx一致的1800秒)。具体操作需参考你的OpenStack环境文档:

  • 找到与Ingress绑定的Octavia负载均衡器实例
  • 进入对应的listener配置页面
  • 更新idle timeout参数为所需值

2. 配置Nginx发送TCP保活包

在Nginx的/ws location块中添加TCP保活相关参数,让Nginx主动发送保活探测包,避免Octavia判定连接空闲:

location /ws {
    # 原有配置保留
    proxy_http_version 1.1;
    proxy_pass_request_headers on;
    proxy_set_header Connection 'Upgrade';
    proxy_set_header Upgrade $http_upgrade;
    proxy_read_timeout 1800s;
    proxy_connect_timeout 1800s;
    proxy_send_timeout 1800s;
    send_timeout 1800s;

    # 添加TCP保活配置
    proxy_socket_keepalive on;
    tcp_keepalive_time 30s;
    tcp_keepalive_intvl 30s;
    tcp_keepalive_probes 3;

    proxy_pass http://myUpstream/ws;
}

这些参数会让Nginx每隔30秒发送一次TCP保活包,确保Octavia认为连接处于活跃状态,不会触发50秒的空闲超时。

3. 确认Ingress控制器的超时配置生效

检查Ingress控制器生成的实际Nginx配置,确保你的注解已正确覆盖默认值:

  • 进入Ingress控制器Pod:kubectl exec -it <ingress-controller-pod-name> -n <ingress-namespace> -- /bin/bash
  • 查看生成的配置文件:cat /etc/nginx/nginx.conf
  • 搜索/ws对应的location块,确认proxy_read_timeout等参数是否为1800秒

若配置未生效,需检查Ingress资源注解是否有误,或重启Ingress控制器Pod让配置重载。


内容的提问来源于stack exchange,提问作者Laurent Erignoux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 06:06:02