【问题标题】:Cannot connect to a socket in a Docker container running on Kubernetes无法连接到在 Kubernetes 上运行的 Docker 容器中的套接字
【发布时间】:2021-11-10 20:48:54
【问题描述】:

我正在尝试连接到容器内并部署在 Kubernetes 上的套接字。 本地一切正常,但部署时会引发连接错误。我尝试了不同的选项,但没有成功。

客户端代码

const ENDPOINT = "https://traveling.dev/api/chat";  // this will go to the endpoint of service where socket is running

const chatSocket = io(ENDPOINT, {
  rejectUnauthorized: false,
  forceNew: true,
  secure: false,
});
chatSocket.on("connect_error", (err) => {
  console.log(err);
  console.log(`connect_error due to ${err.message}`);
});
console.log("CS", chatSocket);

服务器代码

const app = express();

app.set("trust proxy", true);
app.use(cors());

const server = http.createServer(app);
const io = new Server(server, {
  cors: {
    origin: "*",
    methods: ["*"],
    allowedHeaders: ["*"],
  },
});


io.on("connection", (socket) => {

  console.log("Socket succesfully connected with id: " + socket.id);

});

const start = async () => {   

  server.listen(3000, () => {
    console.log("Started");
  });
};

start();

问题是代码在这里无关紧要,因为在本地它一切正常,但我还是发布了它。 在将其容器化并将其放在 Kubernetes 上时会导致这种情况的原因是什么?

控制台日志只显示服务器错误

Error: server error
    at Socket.onPacket (socket.js:397)
    at XHR.push../node_modules/component-emitter/index.js.Emitter.emit (index.js:145)
    at XHR.onPacket (transport.js:107)
    at callback (polling.js:98)
    at Array.forEach (<anonymous>)
    at XHR.onData (polling.js:102)
    at Request.push../node_modules/component-emitter/index.js.Emitter.emit (index.js:145)
    at Request.onData (polling-xhr.js:232)
    at Request.onLoad (polling-xhr.js:283)
    at XMLHttpRequest.xhr.onreadystatechange (polling-xhr.js:187)

是否有人对可能导致此问题的原因以及如何解决此问题有任何建议? 此外,任何关于如何获取有关错误的更多信息的想法将不胜感激。

这是创建 Service 和 Pod 的 YAML 文件。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: chat-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: chat
  template:
    metadata:
      labels:
        app: chat
    spec:
      containers:
        - name: chat
          image: us.gcr.io/forward-emitter-321609/chat-service 
---
apiVersion: v1
kind: Service
metadata:
  name: chat-srv
spec:
  selector:
    app: chat
  ports:
    - name: chat
      protocol: TCP
      port: 3000
      targetPort: 3000

我在 GKE 上使用负载均衡器和 nginx,其 IP 地址映射到 travel.dev

这是我的入口路由服务配置的样子:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "Access-Control-Allow-Origin: $http_origin";
spec:
  rules:
    - host: traveling.dev
      http:
        paths:
          - path: /api/chat/?(.*)
            backend:
              serviceName: chat-srv
              servicePort: 3000
          - path: /?(.*)
            backend:
              serviceName: client-srv
              servicePort: 3000

谢谢!

【问题讨论】:

  • 没有关于 Docker 镜像的信息,也没有关于 pod 如何在 Kubernetes 中部署的信息,无法回答。
  • 啊哈,感谢您的反馈,在 Docker 和 k8s 世界中仍然是新事物。我将编辑问题。

标签: node.js docker sockets kubernetes


【解决方案1】:

Nginx Ingress 默认支持WebSocket 代理,但需要配置。 为此需要添加注解自定义配置sn-p。

您可以参考这个已回答的 stackoverflow 问题。

Nginx ingress controller websocket support

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-24
    • 2020-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    相关资源
    最近更新 更多