Error in implementing WebSocket in Kubernetes

9/18/2019

We are trying to implement WebSocket in Kubernetes by following steps given in GCP document "https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#support_for_websocket" & "https://cloud.google.com/kubernetes-engine/docs/how-to/configure-backend-service" . but we are getting "Error during WebSocket handshake: Unexpected response code: 502”.

Error Message : “WebSocket connection to 'wss://..../backend-channeladaptor-web/socket.io/?EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 502”.

I have also attached Files created for gke implementation:

  1. Backend-channeladaptor-web.yaml

    • Deployment content

    • Service content

    • Backendconfig content

  2. Converse-ingress.yaml (It has details of other services as well you can ignore that except backend-channeladaptor-web).

Converse-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: converse-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: $Static-Ip-Name
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: $SSL-certificate
  rules:
  - host: $HostName
    http:
      paths:
      - path: /*
        backend:
          serviceName: frontend-chat-client
          servicePort: 3040
      - path: /socket-io/*
        backend:
          serviceName: backend-channeladaptor-engineerportal
          servicePort: 11009          
      - path: /login/*
        backend:
          serviceName: frontend-engineeringportal
          servicePort: 3021
      - path: /frontend-engineeringportal/*
        backend:
          serviceName: frontend-engineeringportal
          servicePort: 3021
      - path: /backend-channeladaptor-web/*
        backend:
          serviceName: backend-channeladaptor-web
          servicePort: 11006

Backend-channeladaptor-web.yaml

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  name: backend-channeladaptor-web-backendconfig
spec:
  timeoutSec: 3600
  connectionDraining:
    drainingTimeoutSec: 3600

---
apiVersion: v1
kind: Service
metadata:
  name: backend-channeladaptor-web
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"8081":"backend-channeladaptor-web-backendconfig"}}'
spec:
  type: NodePort
  ports:
    - port: 8081
      targetPort: 11006
      protocol: TCP
      nodePort: 30078
      name: http
  selector:
    app: backend-channeladaptor-web

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: backend-channeladaptor-web
spec:
  selector:
    matchLabels:
      app: backend-channeladaptor-web
  replicas: 1
  template:
    metadata:
      labels:
        app: backend-channeladaptor-web
    spec:
      containers:
        - image: gcr.io/acn-careful-granite-240620/backend-channeladaptor-web:0.2
          name: backend-channeladaptor-web
          ports:
           - name: http
             containerPort: 11006
             hostPort: 11006
          env:
            - name: NODE_ENV
              value: dev

I expect the response status code 101 but getting 502 Bad Gateway

-- Shashank
google-kubernetes-engine
kubernetes
socket.io
websocket

1 Answer

9/23/2019

It looks like your ingress has the URI /backend-channeladaptor-web/* pointed to the Service backend-channeladaptor-web and is expecting the Service to be listening in 11006. However, the NodePort configuration is listening in 8081.

The confusion might come from the targetPort directive, pointing to 11006 in the actual backend (the Deployment).

This is causing 502's, meaning that althought you're reaching an intermediary (the load balancer in your case), it is unable to reach the backend (the Deployment, served by the NodePort Service).

You can change the ingress definition to point to 8081 instead, matching the current NodePort configuration.

-- yyyyahir
Source: StackOverflow