Socket.io Kubernetes上的Ingress控制器(无法建立连接)

5f0d552i  于 2023-11-17  发布在  Kubernetes
关注(0)|答案(2)|浏览(130)

我有一个简单的Node.js聊天示例,它使用socket.io。我已经在本地使用Docker容器测试了这个部署,并且Web客户端成功连接到WebSocket(socket.io)。当我尝试将其部署在具有ingress Controller的Kubernetes集群上时,问题出现了。
我的问题是,在使用入口控制器时,socket.io有什么特别的要求吗?

我得到的错误信息是<<browser name>> Can't estabilish a connection to the server at ws://<<address>>/socket.io/EIO=3&transport=websocket

下面是服务器端的简单实现

var io = socket(server);
io.on('connection', (socket)=>{
    console.log('made socket connection')
    socket.on('chat', (message)=>{
        message:message.value
    })

字符串
下面是客户端:

var socket = io.connect("http://localhost:3002", {
    upgrade: false,
    transports: ['websocket'],
    secure: True
});


我的ingressyaml文件看起来像这样

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ws-ingress
  namespace: websocket-ns
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/websocket-services: "ws-service"
    nginx.ingress.kubernetes.io/proxy-read-timeout: '3600'
    nginx.ingress.kubernetes.io/proxy-send-timeout: '3600'
    nginx.ingress.kubernetes.io/server-snippet: |
      http {
        server {
            listen 3002;
          location = / {
              proxy_set_header Upgrade "websocket";
              proxy_http_version 1.1;
              proxy_set_header X-Forwarded-Host $http_host;
              proxy_set_header X-Forwarded-Proto $scheme;
              proxy_set_header X-Forwarded-For $remote_addr;
              proxy_set_header Host $host;
              proxy_set_header Connection "upgrade";
              proxy_cache_bypass $http_upgrade;
            }
          upstream nodes {
              hash $remote_addr consistent;
              server app01:3002;
            }
      }
spec:
  rules:
    - host: "$host_address"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: ws-service
                port:
                  number: 80


服务热线:

apiVersion: v1
kind: Service
metadata:
  name: ws-service
  namespace: websocket-ns
  labels:
    app: ws-service
spec:
  type: LoadBalancer
  selector:
    app: ws-app
  ports:
    - port: 80
      protocol: TCP
      targetPort: 3002


服务器部署文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ws-app
  namespace: websocket-ns
  labels:
    app: ws-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ws-app
  template:
    metadata:
      labels:
        app: ws-app
    spec:
      containers:
        - name: ws-app
          image: themuchy/socketexample
          ports:
            - containerPort: 3002
              name: ws-app

oxcyiej7

oxcyiej71#

这一个正在和一个

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    certmanager.k8s.io/cluster-issuer: core-prod
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/secure-backends: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/websocket-services: ws-service
    nginx.org/websocket-services: ws-service
  name: core-ingress
spec:
  rules:
  - host: test.io
    http:
      paths:
      - backend:
          serviceName: ws-service
          servicePort: 80
  tls:
  - hosts:
    - test.io
    secretName: core-prod

字符串
Nginx本身会升级HTTP请求并将其转换为WebSocket。您不必添加任何相同的注解。
DeploymentserviceYAML配置看起来不错,但是尝试删除注解server-snippet

LB > ingress (Connection upgrade) > service > pods

drnojrws

drnojrws2#

我一整天都在撞墙!发现注解中的一行解决了这个问题!我通过将副本减少到1来解决这个问题,然后它工作了,很快就很明显,整个问题就是会话粘滞!see socket io multiple nodes
强大的行是:nginx.ingress.kubernetes.io/upstream-hash-by:“$client_ip”
下面是我入口规则

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nodejs-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/use-regex: "true"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    ##### solved ws socket.io session stickness #####
    nginx.ingress.kubernetes.io/upstream-hash-by: "$client_ip"
spec:
  ingressClassName: "nginx"
  tls:
  - hosts:
    - example.com
    - www.example.com
    secretName: example-tls
  rules:
  - host: example.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: nodejs
            port:
              number: 5000
  - host: www.example.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: nodejs
            port:
              number: 5000

字符串

相关问题