6

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
  • Did you ever solve this? Commented Dec 19, 2018 at 11:30

3 Answers 3

6

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
Sign up to request clarification or add additional context in comments.

4 Comments

This repo provides an implementation of an Ingress controller for NGINX and NGINX Plus. This implementation is different from the NGINX Ingress controller in kubernetes/ingress-nginx repo. See this doc to find out about the key differences. [github.com/nginxinc/kubernetes-ingress/blob/master/docs/… I am using kubernetes/ingress-nginx repo [github.com/kubernetes/ingress-nginx] In [github.com/nginxinc/kubernetes-ingress] , readme.md they CLEARLY stated, BOTH CONTROLLER ARE DIFFERENT.
Thank you for information. Your links were very helpful. Could you check your ingress-controller /etc/nginx.conf content for the presence of the following lines in the service location? <proxy_set_header Upgrade $http_upgrade;> and < proxy_set_header Connection $connection_upgrade;> I believe they should be present to enable WebSocket functionality for the backend.
# Pass the extracted client certificate to the backend # Allow websocket connections proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header X-Request-ID $req_id; proxy_set_header X-Real-IP $the_real_ip; I checked its there
Can't say more without seeing the whole nginx.conf from your ingress-controller. Could you upload it on github and provide a link?
1

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

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

Comments

-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

1 Comment

` kind: Ingress apiVersion: extensions/v1beta1 metadata: name: websocket-producer-3tlb namespace: dpqa annotations: nginx.org/websocket-services: websocket-producer-3tlb spec: rules: - host: some.domain.com http: paths: - path: "/" backend: serviceName: websocket-producer-3tlb servicePort: 8183 status: loadBalancer: ingress: - {} ` Tried this still not able to listen, same handshake exception is coming And this annotation is for nginx-ingress and i am using kubernetes-ingress

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.