WebSocket handshake: Unexpected response code: 400 in kubernetes-ingress

我的未来我决定 提交于 2020-01-03 17:25:50

问题


Facing this issue if I am connecting to ingress for web socket service failed: Error during WebSocket handshake: Unexpected response code: 400

Ingress YAML

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: websocket-producer-cdph
spec:
  rules:
    host: some.domain.com
      http:
        paths:
          path: "/"
          backend:
            serviceName: websocket-producer-cdph
            servicePort: 8183
status:
loadBalancer:
ingress:
{}

Service YAML

kind: Service
apiVersion: v1
metadata:
  name: websocket-producer-cdph
spec:
  ports:    
    name: ws
    protocol: TCP
    port: 8183
    targetPort: 8183
selector:
  app: websocket-producer-cdph
clusterIP: 10.100.254.99
type: ClusterIP
sessionAffinity: None
status:
loadBalancer:
{}

When I try to listen ws://some.domain.com/ws it's showing Error during WebSocket handshake: Unexpected response code: 400

/ws is the path

But if go and update spec type in service to LoadBalancer, it'll generate an IP 192.168.1.17:8183 and listening to that ws://192.168.1.17:8183/ws its working but I need to expose the URL using ingress so it can be used outside of the network.

I am using the following image for ingress controller:

quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.19.0

How can I create ingress for a web-socket service?


回答1:


You want to add the nginx.org/websocket-services annotation to your ingress resource definition. That, in turn, tells nginx to support websockets (which I believe has to do with the Upgrade/Connection headers?).

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: websocket-producer-cdph
  annotations:
    nginx.org/websocket-services: "websocket-producer-cdph"
spec:
  rules:
  - host: some.domain.com
    http:
      paths:
      - path: /
        backend:
          serviceName: websocket-producer-cdph
          servicePort: 8183



回答2:


As stated in the nginx-ingress documentation, to proxy WebSocket traffic you should use annotation with the name of websocket service. Don't forget to use quotes:

nginx.org/websocket-services: "service1[,service2,...]"

In this example from the documentation, WebSocket is enabled only for one of three services (ws-svc):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress
  annotations:
    nginx.org/websocket-services: "ws-svc"
spec:
  rules:
  - host: cafe.example.com
    http:
      paths:
      - path: /tea
        backend:
          serviceName: tea-svc
          servicePort: 80
      - path: /coffee
        backend:
          serviceName: coffee-svc
          servicePort: 80
      - path: /ws
        backend:
          serviceName: ws-svc
          servicePort: 8008



回答3:


try add annotationnginx.ingress.kubernetes.io/upstream-hash-by: "$arg_token"

https://github.com/kubernetes/ingress-nginx/issues/2097



来源:https://stackoverflow.com/questions/52514108/websocket-handshake-unexpected-response-code-400-in-kubernetes-ingress

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!