问题分析
表现形式
websocket链接 报错 200
1 | Copy WebSocket connection to 'ws://*********' faile Error during WebSocket handshake: Unexpected response code: 200 |
猜测引起原因以及应对方式
-
后端服务某些filter或者interceptor不兼容ws协议
排查后端服务的filter 或者interceptor 代码
实在不行 将websocket地址给放开限制 -
流量入口没有兼容ws协议访问 如nginx未配置ws协议支持
nginx反向代理要配置一些参数 来达到转发 websocket请求1 2 3 4 5
Copy location /websocket地址 { proxy_pass http://websocket服务; proxy_set_header Upgrade "websocket"; proxy_set_header Connection "Upgrade"; }
解决方案
由于k8s集群入口是通过边缘路由(ingress)来管理的 会存在如下的坑
- 额外的配置 只能配置在 ingress的 metadata中 这样在一个ingress中会全部生效
那么这个时候有两种方案 来解决
1: ingress转发tcp 内部增加一个nginx 进行分发
略。。。 因为这个方案 为认为是回避了k8s的原则 不使用此方案 理论上 这个方案是很好做的 就是有点违背k8s的玩法
2: 配置一个新的单独为所有websocket服务服务的ingress
参考文档: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#configuration-snippet
新增一个配置如下的ingress 文件名为 websocket-ingress.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Copy apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress名称 namespace: ingress所属命名空间 annotations: #ingress使用那种软件 kubernetes.io/ingress.class: nginx #配置websocket 需要的配置 nginx.ingress.kubernetes.io/configuration-snippet: | proxy_set_header Upgrade "websocket"; proxy_set_header Connection "Upgrade"; spec: rules: - host: 识别的域名 http: paths: #代理websocket服务 - path: /websocket地址 backend: serviceName: websocket服务名称 servicePort: websocket服务端口 |
启动该ingress
1 | Copy kubectl apply -f websocket-ingress.yaml |