Websocket with socket.io on K8S, how to make it work?

Cluster information:

Kubernetes version: 1.29.0
Cloud being used: bare-metal
Installation method: kubeadm
Host OS: CentOS 7
CNI and version: Calico
CRI and version: Containerd

Hello everyone, I hope you are well

I’m having a problem when trying to open communication between my applications within Kubernetes. Currently client-server communicate through socket.io, but when adding it to kubernetes, I am having the following problem: server and client connect, I can know that they do from the server log, but no event exchange occurs!

I’ve searched everywhere on the internet, but the solutions I found were for GKE, and I’m running a cluster created by kubeadm, so they’re not usable. Has anyone gone through something similar to this?

Some questions I can ask:

  •  Server pod is running normally, it responds to http requests through ingress
    
  • I am using ingress-nginx v1.10.0 to expose my services
    
  • My application is: Client made in Angular and server in Spring boot, talking through socket.io.
    
  • There is nothing special in the services and deployments manifest declaration, just the basics for it to work.
    
  • My ingress manifest:
    
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: dpiot
  annotations:
    #nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/websocket-services: dpiot-back-service
spec:
  ingressClassName: nginx
  rules:
  - host: dpiotfront.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: dpiot-front-service
            port:
              number: 80
      - path: /socket.io/
        pathType: ImplementationSpecific
        backend:
          service:
            name: dpiot-back-service
            port:
              number: 80

I’ve been searching for more than hours and no results, I’m running out of options, if anyone can help me I would be very grateful. Any additional information you need for something, just ask!

Hi Joao, were you able to resolve this issue? I’m currently facing the same problem, and if you managed to fix it, your help would be greatly appreciated.

Fortunately, I was able to resolve this issue!
When the client and server are on the same DNS, when making the connection via the client, it is not necessary to indicate the path or the DNS, just as follows:

SOCKET: io();

It uses recognition, which I don’t quite understand how it works, but it recognizes that they are on the same DNS. However, if they are on different DNS, it is necessary to specify.

Hi Joao, great! By any chance, do you have an example of the .yml file you used for your socket that worked for you? I’m trying to deploy a Socket.io made in Python, but I haven’t been able to.

Of course! I dont know if you are using rewrite-target on the ingress manifest, if yes, is a lit bit more complicated. In the microservices i was working, i have one server who is made in Node.js, he can handled if the ingress rewrite, but for the others servers who is made is SpringBoot, he cant handle.
You say yours is made ind python, i dont know about it, i recommend searching about it.
But one of the ingress yml i made was:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: example.host.com
    http:
      paths:
      - path: /(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: example-front-service
            port:
              number: 12425
      - path: /anything/(.*) ##Here is the magic key
        pathType: ImplementationSpecific
        backend:
          service:
            name: example-back-service
            port:
              number: 12426


My server wait receive the url:

http://example.host.com/socket.io

So in client i change the path to:

SOCKET: io({path:“/anything/socket.io”})

Then, after pass the rewrite, the server will receive the URL it expects.

I made this way :slight_smile: i hope this help you

1 Like