Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx ingress controller websocket support

Recently I've been working on a toy app using Kubernetes. Part of the app is a web server that needs to support WebSockets. Currently, I'm using port-forwarding to access the web server and everything works just fine.

I'd like to switch to using an Ingress and IngressController to avoid using the port forwarding.

Here is my Ingress config:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/secure-backends: "true"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
spec:
  rules:
  - http:
      paths:
      - path: /app
        backend:
          serviceName: web-svc
          servicePort: 3030
      - path: /ws
        backend:
          serviceName: web-svc
          servicePort: 3030

Now accessing the app through $(minikube ip)/app works just fine, but the WebSocket requests all fail because nginx is returning a 200 and not a 101.

I've tried adding the nginx.org/websocket-services annotation but that doesn't seem to be working either.

Has anyone encountered a similar situation?

Cheers

like image 760
Kit Freddura Avatar asked Oct 18 '18 22:10

Kit Freddura


People also ask

Does ingress support Websockets?

As outlined in the Application Gateway v2 documentation - it provides native support for the WebSocket and HTTP/2 protocols. Please note, that for both Application Gateway and the Kubernetes Ingress - there is no user-configurable setting to selectively enable or disable WebSocket support.

Which protocol does nginx ingress controller handle?

TCP and UDP support means that the Ingress Controller can manage a much wider range of protocols, from DNS and Syslog (UDP) to database and other TCP‑based applications.

Is nginx an ingress controller?

The NGINX Ingress Controller is production‑grade Ingress controller (daemon) that runs alongside NGINX Open Source or NGINX Plus instances in a Kubernetes environment. The daemon monitors NGINX Ingress resources and Kubernetes Ingress resources to discover requests for services that require ingress load balancing.


2 Answers

From looking at the nginx ingress controller docs and the nginx docs you probably need something like this as an annotation on your Kubernetes Ingress:

nginx.ingress.kubernetes.io/configuration-snippet: |
   proxy_http_version 1.1;
   proxy_set_header Upgrade "websocket";
   proxy_set_header Connection "Upgrade";

Note that once you add that annotation all of your Ingress rules will have that snippet in the location block in your nginx configs. So if you want to ignore it for other rules you will have to create a separate Kubernetes Ingress.

EDIT:

As per the gist and the Nginx ingress docs 📄, it seems like this annotation fixed the problem:

nginx.ingress.kubernetes.io/proxy-read-timeout: 3600
nginx.ingress.kubernetes.io/proxy-send-timeout: 3600
like image 106
Rico Avatar answered Sep 23 '22 01:09

Rico


Theese worked for me.

It seems they added support via annotation (example in docs):

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

I tested my connection with telsocket, small tool to connect to a WS/WSS socket.

There are all sorts of different clients, this might also help finding the culprit with the connection.

Important to note: two nginx ingress controllers are available, more info here.

This answer is limited to the nginxinc version, that is different that used in the question, the accepted answer is the only solution as of right now.

like image 31
NotMyDay Avatar answered Sep 20 '22 01:09

NotMyDay