WebSocket 握手期间出错:意外的响应代码:带有 Ingress 的 Minikube 上的 502

Error during WebSocket handshake: Unexpected response code: 502 on Minikube with Ingress

尝试在带有入口的 minikube 上创建一个简单的 websocket 服务器。 连接 ws://192.168.99.119/ 时出现以下错误。

与 'ws://192.168.99.119/' 的 WebSocket 连接失败:WebSocket 握手期间出错:意外的响应代码:502

请帮我解决这个问题。下面提供了实施的细节。

Websocket Server implementation

import * as express from 'express';
import * as http from 'http';
import * as WebSocket from 'ws';

interface ExtWebSocket extends WebSocket {
    id: string; // your custom property
    isAlive: boolean
}
const PORT = parseInt(process.env.NODE_PORT) || 8010;

const app = express();

//initialize a simple http server
const server = http.createServer(app);

//initialize the WebSocket server instance
const wss = new WebSocket.Server({ server });

wss.on('connection', (ws: ExtWebSocket) => {

    //connection is up, let's add a simple simple event
    ws.on('message', (message: string) => {

        //log the received message and send it back to the client
        console.log('received: %s', message);

        const broadcastRegex = /^broadcast\:/;

        ws.isAlive = true;

        ws.on('pong', () => {
            ws.isAlive = true;
        });

        if (broadcastRegex.test(message)) {
            message = message.replace(broadcastRegex, '');

            //send back the message to the other clients
            wss.clients
                .forEach(client => {
                    if (client != ws) {
                        client.send(`Hello, broadcast message -> ${message}`);
                    }
                });

        } else {
            ws.send(`Hello, you sent -> ${message}`);
        }
    });

    //send immediatly a feedback to the incoming connection
    ws.send('Hi there, I am a WebSocket server');
});

setInterval(() => {
    wss.clients.forEach((ws: ExtWebSocket) => {

        if (!ws.isAlive) return ws.terminate();

        ws.isAlive = false;
        ws.ping(null, false);
    });
}, 10000);

//start our server
server.listen(PORT, () => {
    console.log(`Server started on port ${JSON.stringify(server.address())}`);
});

Dockerfile


FROM node:alpine
WORKDIR /app
COPY package*.json /app/
RUN npm install

COPY ./ /app/
RUN npm run build

CMD ["node","./dist/server.js"]

EXPOSE 8010

Websocket service yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: socketserver
spec:
  replicas: 1
  selector:
    matchLabels:
      app: socketserver
  template:
    metadata:
      labels:
        app: socketserver
    spec:
      containers:
      - name: socketserver
        image: kireeti123/socketserver:1.0.2
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 8010
          name: wsport
---
apiVersion: v1
kind: Service
metadata:
  name: socketserver-svc
spec:
  selector:
    app: socketserver
  ports:
  - port: 8010
    targetPort: 80
---

Ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: demo-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/websocket-services: socketserver-svc
    nginx.org/websocket-services: socketserver-svc
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: socketserver-svc
          servicePort: 80

为什么将 targetPort 设置为 80Pod 公开端口 8010 ?不行。

在您的 Service 定义中切换端口号,使其看起来像下面的示例:

apiVersion: v1
kind: Service
metadata:
  name: socketserver-svc
spec:
  selector:
    app: socketserver
  ports:
  - port: 80
    targetPort: 8010

希望对您有所帮助。