云环境K8s集群WebSocket连接失败解决方案

发布于:2025-08-03 ⋅ 阅读:(6) ⋅ 点赞:(0)

云环境K8s集群WebSocket连接失败解决方案

一、问题描述

在云环境(如华为云)的K8s集群中部署WebSocket服务(Java后端+Vue前端+Python客户端)时,遇到**无法连接或握手失败(400 Bad Request)**问题,具体表现为:

  • Python客户端日志显示:Handshake status 400
  • Java后端日志无WebSocket连接记录;
  • 浏览器开发者工具显示:WebSocket请求未升级为101状态(仍为HTTP 400)。

二、核心问题分析

WebSocket连接需要特殊的协议升级流程(从HTTP到WebSocket),而云环境中的Nginx-Ingress(K8s ingress controller)和**云负载均衡器(ELB)**默认未配置这些流程,导致:

  1. 协议头未传递UpgradeConnection头未从客户端转发到后端服务;
  2. 超时时间过短:Nginx-Ingress默认60秒超时,断开长连接;
  3. 跨域限制:后端服务未允许客户端的Origin(如https://example.com)。

三、分步解决方案

1. K8s Ingress配置:解决Nginx转发问题

需要的知识

  • Ingress是K8s的“智能路由”,本质是Nginx集群;
  • WebSocket需要UpgradeConnection头传递。

修改ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-service-name
  namespace: example-auto
  annotations:
    # 1. WebSocket必需:转发Upgrade和Connection头
    nginx.ingress.kubernetes.io/proxy-set-header: |
      Upgrade $http_upgrade;
      Connection $connection_upgrade;
    # 2. WebSocket必需:HTTP/1.1(之前已修正)
    nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
    # 3. 超时设置(WebSocket长连接需要)
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    # 4. 路径重写:将/gcyiams/ws转发到Java服务的/ws端点(因context-path=/gcyiams,实际后端路径是/gcyiams/