背景与问题场景

在 Kubernetes 集群中,Traefik 作为反向代理网关,承担着统一接收外部 HTTPS 流量并转发到内部 Service 的重要职责。然而,当某个 Service 提供 WebSocket 服务时,经过 Traefik 的转发后,WebSocket 连接可能意外失效。这种现象通常表现为客户端无法建立持久化连接或连接频繁中断。

问题原因分析

WebSocket 协议依赖 HTTP 的 Upgrade 机制完成握手,而反向代理的某些配置可能导致以下问题:

协议头丢失 :后端服务无法感知原始请求的 HTTPS 协议,误以为使用 HTTP
连接不保持 :代理层未正确处理 Connection: Upgrade 标头
证书不匹配 :代理与后端服务的协议不一致导致安全策略冲突

解决方案核心原理

通过为 Traefik 添加中间件(Middleware) ,强制注入 X-Forwarded-Proto: https 请求头,明确告知后端服务原始请求的协议类型。该头信息将覆盖代理层的默认行为,确保 WebSocket 握手过程完整传递 HTTPS 上下文。

详细配置实现

步骤 1:创建自定义中间件

# custom-header-middleware.yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: custom-request-headers-to-https
spec:
  headers:
    customRequestHeaders:
      X-Forwarded-Proto: "https"  # 强制声明原始协议为HTTPS

关键参数说明 :

  • X-Forwarded-Proto:覆盖代理层协议标识
  • X-Forwarded-Port:补充端口信息增强上下文
  • 使用 Helm 注解确保中间件与 Helm Release 关联

步骤 2:配置 IngressRoute 绑定中间件

# websocket-ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: ingress-tianji
spec:
  entryPoints:
    - websecure   # 指定HTTPS入口点
  routes:
    - match: Host(`xxx.abc.com`)  # 域名匹配规则
      kind: Rule
      services:
        - name: tianji
          port: 12345     # 后端服务端口
      middlewares:
        - name: custom-request-headers-to-https  # 应用中间件
  tls:
    secretName: wildcard-tls-certificate  # TLS证书配置

流量路径解析 :

客户端(HTTPS) → Traefik → 中间件处理 → Service(Pod)
           ↑          添加X-Forwarded头           ↑
      443端口监听                             WebSocket服务

技术验证与调试

测试 WebSocket 连通性

使用 wscat 工具进行实时测试:

wscat -c wss://xxx.abc.com/ws

总结

通过合理配置 Traefik 中间件,我们成功解决了 Kubernetes 环境中 WebSocket 协议透传的关键问题。这种方案不仅保证了协议升级过程的完整性,还为后续的微服务通信提供了标准化配置模板。建议在实际生产环境中结合监控系统(如 Prometheus)对 WebSocket 连接状态进行持续观察,并根据业务需求动态调整超时参数。