express + socket.io + kubernetes Access-Control-Allow-Origin' header

9/1/2019

I'm setting up kubernetes cluster with node.js app. I have created all deployments, services and ingress and only thing that is not working are websockets. On app that I'm running locally I'm getting that request has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. When I tried to port forward myself to that pod, sockets started to work.

I tried adding the following to server side code:

let server = require('http').createServer(app, {origins: '*:*'});
app.all('/', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    next();
});
const io = sio(server);
io.origins('*:*');

My pod yaml file

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
  labels:
    name: app
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
        - name: app
          image: XXXXX:1.1
      restartPolicy: Always

Service api yaml file

apiVersion: v1
kind: Service
metadata:
  labels:
    app: api-service
  name: api-service
spec:
  type: NodePort
  selector:
    app: app
  ports:
  - port: 8000
    targetPort: 8000
    name: api

Service ws yaml file

apiVersion: v1
kind: Service
metadata:
  labels:
    app: ws-service
  name: ws-service
spec:
  type: NodePort
  selector:
    app: app
  ports:
  - port: 8001
    targetPort: 8001
    name: ws

Ingress yaml file

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: vhost-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: static-ip
    nginx.org/websocket-services: "ws-service"
spec:
  rules:
    - host: api.com
      http:
        paths:
          - backend:
              serviceName: app-service
              servicePort: 8000
    - host: ws.com
      http:
        paths:
          - backend:
              serviceName: ws-service
              servicePort: 8001

As you can see, I have one deployment which has 2 ports exposed. On port 8000 is part of the code that handles API requests (api-service) and 8001 that should handle WS (ws-service). API part works perfectly and app is running without any errors. When trying to connect to ws.com I'm getting CORS error. The part which doesn't work are websockets.

-- D1plomat
google-cloud-platform
kubernetes
node.js

2 Answers

9/2/2019

Can you include

sessionAffinity: ClientIP

in your service ws yaml and try?

-- Bimal
Source: StackOverflow

9/2/2019

Is not stated and the question is tagged as GCP but in case you're using Nginx ingress with a GCP Network Load Balancer:

Nginx-ingress has an specific annotation to allow CORS into the ingress, with different options:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: vhost-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: static-ip
    nginx.org/websocket-services: "ws-service"
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://admin.example.com"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
-- yyyyahir
Source: StackOverflow