Kubernetes 和 Socket.io 404 错误 - 在本地工作但在应用到 kubernetes 后不工作
Kubernetes and Socket.io 404 error - works locally but not after applying to kubernetes
提前为这么长的问题道歉,我只是想确保我涵盖了所有内容...
我有一个反应应用程序,它应该连接到我已部署到 kubernetes 的服务中 运行 的套接字。服务 运行s 并且工作正常。我可以毫无问题地发出请求,但我无法连接到同一服务中的 websocket 运行ning。
当我在本地 运行 服务并使用 locahost uri 时,我能够连接到 websocket。
我的快递服务的 server.ts 文件如下所示:
import "dotenv/config";
import * as packageJson from "./package.json"
import service from "./lib/service";
const io = require("socket.io");
const PORT = process.env.PORT;
const server = service.listen(PORT, () => {
console.info(`Server up and running on ${PORT}...`);
console.info(`Environment = ${process.env.NODE_ENV}...`);
console.info(`Service Version = ${packageJson.version}...`);
});
export const socket = io(server, {
cors: {
origin: process.env.ACCESS_CONTROL_ALLOW_ORIGIN,
methods: ["GET", "POST"]
}
});
socket.on('connection', function(skt) {
console.log('User Socket Connected');
socket.on("disconnect", () => console.log(`${skt.id} User disconnected.`));
});
export default service;
当我运行这个的时候,PORT
设置为8088,access-control-allow-origin设置为*
。请注意,我正在使用部署到 Kubernetes 的 rabbitmq 集群,当我在本地 运行 时,它与 rabbit 连接的 uri 相同。 Rabbitmq 没有 运行 在我的本地机器上运行,所以我知道这不是我的 rabbit 部署的问题,一定是我在连接套接字时做错了。
当我在本地 运行 服务时,我可以通过以下方式在 React 应用程序中进行连接:
const io = require("socket.io-client");
const socket = io("ws://localhost:8088", { path: "/socket.io" });
我看到了“用户套接字已连接”消息,一切都如我所料。
不过,当我将服务部署到 Kubernetes 时,我在确定如何连接到套接字时遇到了一些问题。
我的 Kubernetes 服务:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8088
selector:
app: my-service
我的部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service
spec:
replicas: 2
selector:
matchLabels:
app: my-service
template:
metadata:
labels:
app: my-service
spec:
containers:
- name: project
image: my-private-registry.com
ports:
- containerPort: 8088
imagePullSecrets:
- name: mySecret
最后,我的入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-service-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/enable-cors: "true" // Just added this to see if it helped
nginx.ingress.kubernetes.io/cors-allow-origin: "*" // Just added this to see if it helped
nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, OPTIONS, DELETE, PATCH // Just added this to see if it helped
spec:
tls:
- hosts:
- my.host.com
secretName: my-service-tls
rules:
- host: "my.host.com"
http:
paths:
- pathType: Prefix
path: "/project"
backend:
service:
name: my-service
port:
number: 80
我可以很好地连接到服务并获取数据,post 数据等。但是我无法连接到 websocket,我收到 404 或 cors 错误。
由于服务在 my.host.com/project 上 运行ning,我假设套接字位于相同的 uri。所以我尝试连接:
const socket = io("ws://my.host.com", { path: "/project/socket.io" });
并且还使用 wss://
const socket = io("wss://my.host.com", { path: "/project/socket.io" });
我在控制台中记录了一个错误:
socket.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});
两者都导致
polling-xhr.js?d33e:198 GET https://my.host.com/project/?EIO=4&transport=polling&t=NjWQ8Tc 404
websocket.ts?25e3:14 connect_error due to xhr poll error
我已经尝试了以下所有方法并且 none 有效:
const socket = io("ws://my.host.com", { path: "/socket.io" });
const socket = io("wss://my.host.com", { path: "/socket.io" });
const socket = io("ws://my.host.com", { path: "/project" });
const socket = io("wss://my.host.com", { path: "/project" });
const socket = io("ws://my.host.com", { path: "/" });
const socket = io("wss://my.host.com", { path: "/" });
const socket = io("ws://my.host.com");
const socket = io("wss://my.host.com");
同样,这在本地服务 运行 时有效,所以我一定是遗漏了什么,非常感谢任何帮助。
有没有办法在 Kubernetes pod 上找到 rabbit 被广播到的位置?
万一以后有人偶然发现这个问题并想知道如何解决它,事实证明这对我来说是一个非常愚蠢的错误..
在:
export const socket = io(server, {
cors: {
origin: process.env.ACCESS_CONTROL_ALLOW_ORIGIN,
methods: ["GET", "POST"]
},
});
我只需要在套接字选项中添加 path: "/project/socket.io"
,这是有道理的。
然后,如果有人碰巧 运行 进入随后的问题,我在 post 到 websocket 轮询时收到 400 错误,所以我在 transports: [ "websocket" ]
中设置 socket.io-客户端选项,这似乎解决了它。插座现在可以工作了,我终于可以继续前进了!
提前为这么长的问题道歉,我只是想确保我涵盖了所有内容...
我有一个反应应用程序,它应该连接到我已部署到 kubernetes 的服务中 运行 的套接字。服务 运行s 并且工作正常。我可以毫无问题地发出请求,但我无法连接到同一服务中的 websocket 运行ning。
当我在本地 运行 服务并使用 locahost uri 时,我能够连接到 websocket。
我的快递服务的 server.ts 文件如下所示:
import "dotenv/config";
import * as packageJson from "./package.json"
import service from "./lib/service";
const io = require("socket.io");
const PORT = process.env.PORT;
const server = service.listen(PORT, () => {
console.info(`Server up and running on ${PORT}...`);
console.info(`Environment = ${process.env.NODE_ENV}...`);
console.info(`Service Version = ${packageJson.version}...`);
});
export const socket = io(server, {
cors: {
origin: process.env.ACCESS_CONTROL_ALLOW_ORIGIN,
methods: ["GET", "POST"]
}
});
socket.on('connection', function(skt) {
console.log('User Socket Connected');
socket.on("disconnect", () => console.log(`${skt.id} User disconnected.`));
});
export default service;
当我运行这个的时候,PORT
设置为8088,access-control-allow-origin设置为*
。请注意,我正在使用部署到 Kubernetes 的 rabbitmq 集群,当我在本地 运行 时,它与 rabbit 连接的 uri 相同。 Rabbitmq 没有 运行 在我的本地机器上运行,所以我知道这不是我的 rabbit 部署的问题,一定是我在连接套接字时做错了。
当我在本地 运行 服务时,我可以通过以下方式在 React 应用程序中进行连接:
const io = require("socket.io-client");
const socket = io("ws://localhost:8088", { path: "/socket.io" });
我看到了“用户套接字已连接”消息,一切都如我所料。
不过,当我将服务部署到 Kubernetes 时,我在确定如何连接到套接字时遇到了一些问题。
我的 Kubernetes 服务:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8088
selector:
app: my-service
我的部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service
spec:
replicas: 2
selector:
matchLabels:
app: my-service
template:
metadata:
labels:
app: my-service
spec:
containers:
- name: project
image: my-private-registry.com
ports:
- containerPort: 8088
imagePullSecrets:
- name: mySecret
最后,我的入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-service-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/enable-cors: "true" // Just added this to see if it helped
nginx.ingress.kubernetes.io/cors-allow-origin: "*" // Just added this to see if it helped
nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, OPTIONS, DELETE, PATCH // Just added this to see if it helped
spec:
tls:
- hosts:
- my.host.com
secretName: my-service-tls
rules:
- host: "my.host.com"
http:
paths:
- pathType: Prefix
path: "/project"
backend:
service:
name: my-service
port:
number: 80
我可以很好地连接到服务并获取数据,post 数据等。但是我无法连接到 websocket,我收到 404 或 cors 错误。
由于服务在 my.host.com/project 上 运行ning,我假设套接字位于相同的 uri。所以我尝试连接:
const socket = io("ws://my.host.com", { path: "/project/socket.io" });
并且还使用 wss://
const socket = io("wss://my.host.com", { path: "/project/socket.io" });
我在控制台中记录了一个错误:
socket.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});
两者都导致
polling-xhr.js?d33e:198 GET https://my.host.com/project/?EIO=4&transport=polling&t=NjWQ8Tc 404
websocket.ts?25e3:14 connect_error due to xhr poll error
我已经尝试了以下所有方法并且 none 有效:
const socket = io("ws://my.host.com", { path: "/socket.io" });
const socket = io("wss://my.host.com", { path: "/socket.io" });
const socket = io("ws://my.host.com", { path: "/project" });
const socket = io("wss://my.host.com", { path: "/project" });
const socket = io("ws://my.host.com", { path: "/" });
const socket = io("wss://my.host.com", { path: "/" });
const socket = io("ws://my.host.com");
const socket = io("wss://my.host.com");
同样,这在本地服务 运行 时有效,所以我一定是遗漏了什么,非常感谢任何帮助。
有没有办法在 Kubernetes pod 上找到 rabbit 被广播到的位置?
万一以后有人偶然发现这个问题并想知道如何解决它,事实证明这对我来说是一个非常愚蠢的错误..
在:
export const socket = io(server, {
cors: {
origin: process.env.ACCESS_CONTROL_ALLOW_ORIGIN,
methods: ["GET", "POST"]
},
});
我只需要在套接字选项中添加 path: "/project/socket.io"
,这是有道理的。
然后,如果有人碰巧 运行 进入随后的问题,我在 post 到 websocket 轮询时收到 400 错误,所以我在 transports: [ "websocket" ]
中设置 socket.io-客户端选项,这似乎解决了它。插座现在可以工作了,我终于可以继续前进了!