Kubernetes本身不感知WebSocket协议,但通过正确配置Nginx Ingress(启用upgrade annotation、调大超时、使用ClusterIP Service)、Go服务监听0.0.0.0、禁用HTTP readinessProbe并确保Host头与Ingress host一致,即可稳定运行。

直接说结论:Kubernetes 本身不处理 WebSocket 协议,但只要 Ingress 正确透传 Upgrade 和 Connection 头、Service 类型选对、后端监听地址写对,Go 的 WebSocket 就能稳定跑在 K8s 上——翻车几乎全出在 Ingress 配置漏项或 readinessProbe 误用。
nginx.ingress.kubernetes.io/upgrade: "websocket" 必须显式加
Nginx Ingress Controller 默认把所有请求当普通 HTTP 处理,遇到 Upgrade: websocket 会静默丢弃或返回 400,根本进不到你的 Go 服务。这不是你代码的问题,是 Ingress 没开协议识别开关。
- 必须在 Ingress YAML 的
metadata.annotations里加上:nginx.ingress.kubernetes.io/upgrade: "websocket" - 顺手补上超时配置,避免空闲连接被默认 60s 断开:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"和nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" - 如果用 Higress,得换 annotation:
higress.io/backend-protocol: websocket,否则它按 HTTP/1.1 处理,强制发Connection: close
Service 类型只能用 ClusterIP,别碰 LoadBalancer 或 NodePort
WebSocket 是长连接,依赖七层路由能力(比如路径匹配、header 透传、TLS 终止)。LoadBalancer 直连 Pod 绕过了 Ingress,云厂商 LB(如 AWS ALB、阿里云 SLB)基本不感知 WebSocket,滚动更新时大概率触发连接重置。
- Service
type必须设为ClusterIP - 不要给 Service 配
nodePort或loadBalancerIP - Ingress 的
spec.rules[].http.paths[].backend.service.name必须指向这个 ClusterIP Service
Go 服务监听地址不能写 127.0.0.1,readinessProbe 别用 HTTP
kubelet 从节点网络发起 readiness probe,若 Go server 只监听 127.0.0.1:8080,probe 肯定失败;而用 HTTP 探针查 /healthz 更危险——WebSocket 连接期间 HTTP handler 可能阻塞或返回非 2xx,导致 Pod 被误判为 not ready 并踢出流量。
- Go 启动时必须监听
0.0.0.0:8080(或你实际端口),不是127.0.0.1 - readinessProbe 改用
exec或 TCP socket 检查端口通不通,例如:tcpSocket: port: 8080 - 后端代码里,WebSocket 路由路径要明确,比如
/ws,别挂在/上——否则 http.ServeMux 会拦截 upgrade 请求
客户端 URL 和 Host header 必须跟 Ingress 完全一致
浏览器发 WS 握手时带 Host header,Ingress 用它匹配 spec.rules[].host。不一致就 426 或 400;用 http:// 开头的 URL 也会被拒绝,必须是 ws:// 或 wss://。
- 前端 JS 创建连接时写死:
new WebSocket("wss://your-domain.com/ws") - Ingress 的
spec.rules[].host设为your-domain.com,不能是 IP 或泛域名(除非 annotation 显式支持) - 如果走自建 Nginx(非 Ingress Controller),location 块里必须手动加:
proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection "upgrade";
最容易被忽略的是 readinessProbe 类型和监听地址的组合——哪怕 Ingress 和 Service 全对,只要 probe 把活跃连接中的 Pod 判成 not ready,用户就会看到连接断开、重连失败、消息丢失。这问题不会报错日志,只表现为偶发性连接抖动。


















