Search code examples
google-cloud-platformwebsocketsocket.ionestjsgoogle-kubernetes-engine

Unable to connect via websocket to a backend deployed on GKE


I'm deploying NestJS and NextJS on GKE. Also, I am using GCE Ingress Controller to use managed certificate.

And I'm trying to make a real-time chat using Nest Gateway and socket.io.

The backend port number is 8080, and the websocket port also uses the same 8080. And the namespace is 'chat'.

So, The client attempts a websocket connection as shown below.

const socket = io('http://localhost:8080/chat')

It works fine in local environment.

The problem is that socket connection does not work on GKE.

Below is the contents of the ingress manifest file.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: gce
    kubernetes.io/ingress.global-static-ip-name:my-service-ip
    networking.gke.io/managed-certificates: managed-cert
    networking.gke.io/v1beta1.FrontendConfig: http-to-https-config
spec:
  rules:
  - host: dev.domain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: fontend-svc
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-svc
            port:
              number: 80
      - path: /chat
        pathType: Prefix
        backend:
          service:
            name: backend-svc
            port:
              number: 80

And below is the contents of the backend manifest file.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-api
spec:
  selector:
    matchLabels:
      app: backend-api
  template:
    metadata:
      labels:
        app: backend-api
    spec:
      containers:
      - name: backend-api-app
        image: gcr.io/<PROJECT_ID>/<DOCKER_IMAGE_NAME>:<DOCKER_IMAGE_TAG>
        ports:
        - containerPort: 8080
        envFrom:
          - secretRef:
              name: backend-api-secret
        readinessProbe:
          httpGet:
            path: /api/healthz
            port: 8080
          initialDelaySeconds: 5
        livenessProbe:
          httpGet:
            path: /api/healthz
            port: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: backend-svc
spec:
  selector:
    app: backend-api
  type: NodePort
  externalTrafficPolicy: Cluster
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: 8080

Now the client tries to connect the socket like below.

const socket = io('https://dev.domain.com/chat')

I am getting the error below in my browser.

GET https://dev.domain.com/socket.io?EIO=4&transport=polling&t=OXClghg 404

Anything I'm missing?


Solution

  • I solved it by replacing GCE Ingress Controller with Nginx Ingress Controller.

    The links below may help.

    Kubernetes Nginx Ingress and Socket.io Connection Issues