You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes Ingress是否支持同路径多端口的WebSocket转发?

问题解答

这种完全相同的路径(/socket.io)+ 相同的Prefix路径类型的Ingress配置是不可行的。

Ingress控制器会按照paths列表的顺序进行请求匹配,第一个匹配到/socket.io前缀的规则会直接处理请求,后续同路径的规则会被忽略,所以你添加的第二个WebSocket服务永远接收不到请求,看起来就像被"覆盖"了一样。

可行的解决方案

方案1:给两个服务分配不同的子路径

这是最简单直接的方式,给每个WebSocket服务分配不同的子路径前缀,修改Ingress配置如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ .Values.name }}
  labels:
    name: {{ .Values.name }}
spec:
  rules:
  - host: {{ .Values.host }}
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: {{ .Values.name }}-service
            port:
              number: {{ .Values.service.port }}
      - path: /socket.io/spectrogram
        pathType: Prefix
        backend:
          service:
            name: spectrogram-ms-backend-service
            port:
              number: 8080
      - path: /socket.io/anomaly
        pathType: Prefix
        backend:
          service:
            name: anomaly-detection-microservice-service
            port:
              number: 5000

然后修改Angular前端的WebSocket连接地址,分别指向:

  • wss://{{ .Values.host }}/socket.io/spectrogram
  • wss://{{ .Values.host }}/socket.io/anomaly

方案2:基于请求头的路由(需要Ingress控制器支持,如NGINX Ingress)

如果必须保持/socket.io路径不变,可以让前端在WebSocket握手请求中携带自定义请求头(比如X-Service),然后通过Ingress的配置片段根据请求头转发到对应服务。

修改Ingress配置,添加NGINX专属的annotation,同时只保留一个/socket.io路径规则:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ .Values.name }}
  labels:
    name: {{ .Values.name }}
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      # 根据自定义请求头转发到对应服务
      if ($http_x_service = "spectrogram") {
        proxy_pass http://spectrogram-ms-backend-service:8080;
      }
      if ($http_x_service = "anomaly") {
        proxy_pass http://anomaly-detection-microservice-service:5000;
      }
    # 确保WebSocket连接保持稳定
    nginx.ingress.kubernetes.io/websocket-services: "spectrogram-ms-backend-service,anomaly-detection-microservice-service"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
spec:
  rules:
  - host: {{ .Values.host }}
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: {{ .Values.name }}-service
            port:
              number: {{ .Values.service.port }}
      - path: /socket.io
        pathType: Prefix
        # 填任意一个服务作为默认,实际会被snippet规则覆盖
        backend:
          service:
            name: spectrogram-ms-backend-service
            port:
              number: 8080

前端连接时,需要在WebSocket的握手请求中加入X-Service头,比如在Angular中配置:

// 连接频谱服务
const spectrogramSocket = io('wss://{{ .Values.host }}/socket.io', {
  extraHeaders: {
    'X-Service': 'spectrogram'
  }
});

// 连接异常检测服务
const anomalySocket = io('wss://{{ .Values.host }}/socket.io', {
  extraHeaders: {
    'X-Service': 'anomaly'
  }
});

方案3:中间代理层(复杂度较高)

如果以上两种方案都不适用,可以在Ingress后面部署一个轻量的反向代理服务(比如Envoy、Nginx),统一接收/socket.io的请求,再根据请求参数(如query、Header)转发到对应的微服务。这种方式需要额外维护代理服务,适合有特殊路由需求的场景。


内容的提问来源于stack exchange,提问作者Ben Whitely

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 23:12:35