【问题标题】:Websocket connection fails for internal communication within a Kubernetes containerKubernetes 容器内的内部通信的 Websocket 连接失败
【发布时间】:2020-10-22 20:21:04
【问题描述】:

我正在使用 Kubernetes 来部署我的 React 应用程序。由于数据库,我正在使用(RethinkDB)。我必须在我的 React 应用程序和代理到数据库实例的 Node.js 服务器之间启动 WebSocket 连接。当我在本地机器上部署数据库实例、后端节点服务器和反应应用程序时,连接按预期工作。但是,当我在 Kubernetes 中部署应用程序时,我收到了错误

WebSocket connection to 'ws://localhost:8015/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

在我的反应应用程序中。

为了进一步调试,我在容器中执行了一个终端,并对连接到数据库的服务运行 curl 命令并且没有收到任何错误。我还运行了后端节点服务器以查看它是否连接到远程数据库并且没有发现任何问题。最后,我测试了后端服务器是否使用 wscat 按预期启动 WebSocket 并且 WebSocket 连接正常。由于应用程序在我的本地机器上运行良好,这让我相信 React 应用程序连接到 WebSocket 的问题可能是由 Kubernetes 处理 Websocket 连接的方式引起的。非常感谢您对此问题的任何澄清。

附言

我已经添加了后端服务器代码、连接到 WebSocket 的 React 应用程序中的代码以及我的 React+Backend 部署的 YAML 文件。如果需要更多文件,请随时发表评论

后端节点服务器

const http = require('http');
var rethinkdbWebsocketServer = require('rethinkdb-websocket-server');

const httpServer = http.createServer();
rethinkdbWebsocketServer.listen({
    httpServer: httpServer,
    httpPath: '/',
    dbHost: remoteDB_IP,
    dbPort: 28015,
    unsafelyAllowAnyQuery: true
});

httpServer.listen(8015);

连接到 Websocket 的 React 代码

ReactRethinkdb.DefaultSession.connect({
  host: 'localhost',          // the websocket server
  port: process.env.REACT_APP_WEBSOCKET_PORT,
  path: '/',
  secure: false,
  autoReconnectDelayMs: 2000, // when disconnected, millis to wait before reconnect
});

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dashboard
  labels:
    app: dashboard
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dashboard
  template:
    metadata:
      labels:
        app: dashboard
    spec:
      containers:
      - name: dashboard
        image: myrepor/dashbaord
        imagePullPolicy: Always
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: dashboard
spec:
  selector:
    app: dashboard
  ports:
    - port: 3000
      targetPort: 3000
  type: LoadBalancer

【问题讨论】:

  • 数据库部署在kubernetes哪里?不在同一个 Pod 中?
  • 它被部署为另一个 kubernetes pod,并使用负载均衡器公开
  • 但是数据库的地址是不是 localhost

标签: node.js reactjs docker kubernetes websocket


【解决方案1】:

所以 kubernetes 的想法就是在单独的 pod 中运行每个应用程序。

并通过服务连接它们。

通过这种方式,您可以在不停机的情况下单独部署每一层 - 服务路由到旧 pod,直到新 pod 启动并运行。 (更重要的是单独扩大规模) Kubernetes 在每个 k8s 集群内部进行某种名称解析。不确定这是否是完整的 dns

所以我会推荐

  • 将您的节点服务器分成一个 pod。并使用您的 ws 端口 (8015) 为其部署服务。
  • 您的 react 应用程序将 pod 与自己的服务分开,并将节点服务器服务名称定义为 WS 的端点。

原因很简单——甚至不确定 localhost 会在 pod 中正确解析。

【讨论】:

  • 我通过在自己的 pod 上部署应用程序和后端来实现您的解决方案,但无济于事。但是,在我的第一次尝试中,我通过将 WebSocket 公开为 ClusterIP 来做到这一点。在我的第二次尝试中,我采用了相同的方法,但使用 LoadBalancer 将我的 WebSocket 暴露给外部流量,并且该方法有效。我不完全知道它为什么起作用,所以我暂时不回答这个问题,让有更好理解的人回答这个问题
猜你喜欢
  • 2020-03-12
  • 2018-12-22
  • 1970-01-01
  • 2014-01-24
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多