Using socket.io on GKE with nginx ingress

12/13/2018

I'm trying to integrate socket.io into an application deployed on Google Kubernetes Engine. Developing locally, everything works great. But once deployed, I am continuously getting the dreaded 400 response when my sockets try to connect on. I've been searching on SO and other sites for a few days now and I haven't found anything that fixes my issue.

Unfortunately this architecture was set up by a developer who is no longer at our company, and I'm certainly not a Kubernetes or GKE expert, so I'm definitely not sure I've got everything set up correctly.

Here's out setup:

  • we have 5 app pods that serve our application distributed across 5 cloud nodes (GCE vm instances)

  • we are using the nginx ingress controller (https://github.com/kubernetes/ingress-nginx) to create a load balancer to distribute traffic between our nodes

Here's what I've tried so far:

  • adding the following annotations to the ingress:

nginx.ingress.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/session-cookie-hash: "sha1" nginx.ingress.kubernetes.io/session-cookie-name: "route"

  • adding sessionAffinity: ClientIP to the backend service referenced by the ingress

These measures don't seem to have made any difference, I'm still getting a 400 response. If anyone has handled a similar situation or has any advice to point me in the right direction I'd be very, very appreciative!

-- Josh Newsom
google-kubernetes-engine
kubernetes
nginx
socket.io

2 Answers

5/1/2019

I'm guessing you have probably found the answer by now, but you have to add an annotation to your ingress to specify which service will provide websocket upgrades. It looks something like this:

# web socket support
nginx.org/websocket-services: "(your-websocket-service)"
-- tsimon
Source: StackOverflow

5/1/2019

I just setup ngin ingress with same config where we are using socket.io.

here is my ingress config

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: core-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.org/websocket-services : "app-test"
    nginx.ingress.kubernetes.io/rewrite-target: /
    certmanager.k8s.io/cluster-issuer: core-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/secure-backends: "true"
    nginx.ingress.kubernetes.io/websocket-services : "socket-service"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"

spec:
  tls:
  - hosts:
    - <domain>
    secretName: core-prod
  rules:
  - host: <domain>
    http:
      paths:
      - backend:
          serviceName: service-name
          servicePort: 80

i was also facing same issue so added proxy-send-timeout and proxy-read-timeout.

-- Harsh Manvar
Source: StackOverflow