通过NGINX Ingress连接EMQX的WSS请求失败求助
问题:Kubernetes环境中Vue.js SPA通过wss://连接Ingress后的EMQX失败
问题概述
通过wss://ui-dev.url.com/mqtt连接NGINX Ingress后的EMQX MQTT Broker时,WebSocket连接失败。
环境配置
- NGINX Ingress启用TLS终止,通过
tls.secretName配置证书 - 使用自签名证书(已在浏览器中接受“不安全”提示)
- EMQX以Service形式运行在同一K8s集群
- 本地
/etc/hosts配置了ui-dev.url.com域名解析(未使用公共DNS) - 未部署cert-manager或使用Let’s Encrypt证书
正常表现
- EMQX集群内部运行正常
- 通过
ws://无TLS连接EMQX完全正常,但不符合安全需求
异常表现
wss://请求长期挂起,尝试6-7次后静默失败(状态码0)- 最终偶尔会返回101状态码,但耗时约60秒
- NGINX Ingress日志无明显错误
- 浏览器仅显示请求停滞,无TLS握手失败或WebSocket握手错误提示
已排查操作
- 验证EMQX支持WebSocket连接(ws://正常)
- 调整Ingress注解:设置
nginx.ingress.kubernetes.io/backend-protocol为HTTPS/HTTP;配置proxy-read-timeout: 3600 - 切换自签名证书为mkcert生成的证书,问题依旧
- 确认证书Secret已正确挂载,Ingress的tls块域名配置正确
排查方向建议
补全WebSocket转发所需的Ingress注解
NGINX转发WebSocket请求需要特定的头信息配置,添加以下注解:nginx.ingress.kubernetes.io/proxy-set-header: "Upgrade $http_upgrade" nginx.ingress.kubernetes.io/proxy-set-header: "Connection $connection_upgrade" nginx.ingress.kubernetes.io/upgrade-insecure-requests: "true"缺失这些注解会导致握手阶段超时,请求长期挂起。
确认EMQX的WSS监听端口配置
- EMQX默认WSS端口为8084,WS端口为8083,检查Ingress是否转发到了正确的端口(需指向EMQX的WSS端口)
- 在EMQX Pod内执行
netstat -tulpn,确认0.0.0.0:8084处于监听状态
深度验证TLS握手过程
- 用
openssl s_client -connect ui-dev.url.com:443测试本地到Ingress的TLS握手,查看是否存在证书不匹配、超时或握手失败细节 - 确认证书的CN或SAN字段包含
ui-dev.url.com,避免域名校验隐性失败
- 用
开启NGINX详细日志排查
- 修改NGINX Ingress Controller的启动参数,添加
--v=3开启详细日志,查看WebSocket握手阶段的上游交互细节 - 重点关注日志中是否有
upstream timed out或proxy_connect_timeout相关报错
- 修改NGINX Ingress Controller的启动参数,添加
绕过Ingress直接测试EMQX WSS
- 通过端口转发直接访问EMQX:
kubectl port-forward <emqx-pod-name> 8084:8084 - 在浏览器中尝试
wss://localhost:8084/mqtt,如果连接正常,说明问题出在Ingress配置
- 通过端口转发直接访问EMQX:
检查浏览器请求头传递情况
- 在浏览器开发者工具的Network标签中,查看wss请求的Request Headers,确认
Upgrade: websocket和Connection: Upgrade是否存在 - 如果这些头缺失,说明Ingress未正确传递请求头,导致EMQX无法触发WebSocket握手
- 在浏览器开发者工具的Network标签中,查看wss请求的Request Headers,确认
内容的提问来源于stack exchange,提问作者Onur Ulusoy
相关产品推荐
相关产品推荐

