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

如何在Kubernetes中配置Nginx以实现WS与WSS正常运行?

解决Kubernetes中Nginx Pod的WSS握手错误问题

我之前也踩过这个一模一样的坑——独立服务器上WS和WSS都好好的,一部署到K8s的Nginx Pod里,WSS就开始握手失败。结合你的配置和场景,我来帮你梳理问题根源,一步步搞定它。

问题根源分析

你的default.conf目前只配置了80端口的HTTP/WS代理逻辑,但WSS本质是WebSocket over SSL/TLS,默认走443端口。你说独立服务器上WSS不用证书也能工作,大概率是因为客户端和服务器在同一个信任网络,或者有其他前置代理帮你处理了SSL层;但K8s的NodePort环境下,流量从客户端到Pod的路径更长,必须明确处理SSL或者适配外部的SSL终结逻辑。

解决方案分两种场景

场景1:让Nginx Pod直接处理SSL(用自签证书快速验证)

如果你的场景不需要正式域名证书,用自签证书就能解决问题:

  1. 给Nginx Pod添加SSL证书
    你可以在构建Nginx镜像时生成自签证书,或者用ConfigMap挂载证书文件。比如在Dockerfile里加这段命令:
    # 创建证书目录并生成自签证书
    RUN mkdir -p /etc/nginx/ssl && \
        openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
        -keyout /etc/nginx/ssl/nginx.key \
        -out /etc/nginx/ssl/nginx.crt \
        -subj "/CN=localhost"
    
  2. 修改Nginx配置,添加443端口的WSS代理
    更新你的default.conf,新增443端口的server块:
    server {
        listen 80;
        location / {
            proxy_pass http://ip:8080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header Host $host;
        }
    }
    
    server {
        listen 443 ssl;
        # 指定证书路径
        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;
    
        location / {
            proxy_pass http://ip:8080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header Host $host;
            # 转发SSL相关的头部,让后端服务识别请求协议
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }
    
  3. 更新Kubernetes Service,暴露443端口
    修改你的Service配置,把443端口也映射为NodePort:
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-ws-service
    spec:
      type: NodePort
      ports:
        - port: 80
          targetPort: 80
          nodePort: 30080 # 可选,自定义端口
        - port: 443
          targetPort: 443
          nodePort: 30443 # 可选,自定义端口
      selector:
        app: nginx-ws-pod # 替换成你的Pod标签
    

场景2:外部已有SSL终结(比如Ingress/负载均衡器处理SSL)

如果你的K8s集群已经有Ingress或者外部负载均衡器处理了SSL,客户端的WSS请求会被转为HTTP的WS请求发给Nginx Pod。这时候需要调整配置,适配代理后的流量:

  1. 修改Nginx的http块和server块
    更新default.conf,添加map指令处理Connection头部,并完善代理配置:
    http {
        # 动态设置Connection头部,非WebSocket请求时用close
        map $http_upgrade $connection_upgrade {
            default upgrade;
            '' close;
        }
    
        server {
            listen 80;
            location / {
                proxy_pass http://ip:8080;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                # 使用动态的Connection头部值
                proxy_set_header Connection $connection_upgrade;
                proxy_set_header Host $host;
                # 转发外部的SSL协议标识
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-For $remote_addr;
            }
        }
    }
    
    这个配置的核心是用map指令动态判断是否需要Upgrade,避免在非WebSocket请求时发送错误的Connection头部。

验证步骤

  1. 重新部署Nginx Pod,或者在Pod里重载配置:
    kubectl exec <你的Pod名称> -- nginx -s reload
    
  2. 用wscat工具测试WSS连接:
    • 场景1测试命令:wscat -wss wss://<Node节点IP>:30443/
    • 场景2测试命令:wscat -wss wss://<你的域名>/(确保域名指向Ingress/负载均衡器)

内容的提问来源于stack exchange,提问作者AATHITH RAJENDRAN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:15:53