NGINX Ingress Controller动态代理WebSocket连接异常求助
问题:Ingress动态代理WebSocket连接,消息无法到达后端Pod
我通过Ingress片段配置动态代理WebSocket连接,Ingress已接受并升级连接,但WebSocket消息始终无法到达后端Pod。怀疑是NGINX Controller自行完成了连接升级,未代理给Pod处理。
相关配置与测试信息
Ingress资源配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress annotations: nginx.org/path-regex: "case_insensitive" nginx.org/proxy-read-timeout: "86400s" nginx.org/proxy-send-timeout: "86400s" nginx.org/proxy-buffering: "False" nginx.org/server-snippets: | resolver kube-dns.kube-system.svc.cluster.local valid=30s; location ~* "^/ws/(?<username>[^/]+)$" { # Prevent malicious characters in the username if ($username ~ "[^a-zA-Z0-9_-]") { return 400; } set $service_name svc-$username; set $namespace default; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; # Forward necessary headers proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; # Upgrade HTTP to WebSocket proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; # Disable proxy buffering for WebSocket proxy_buffering off; # Bypass caching proxy_cache_bypass $http_upgrade; # Pass the WebSocket connection to the user-specific service proxy_pass http://$service_name.$namespace.svc.cluster.local; } spec: ingressClassName: nginx rules: - host: "localhost" http: paths: - path: /api/session/start/ pathType: Prefix backend: service: name: controller-service port: number: 8080
测试命令及结果
# WebSocket连接测试 wscat -c ws://localhost/ws/testuser Hello # 后端Pod日志(无连接及消息记录) kubectl logs pod/pod-testuser INFO: Started server process [1] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) <---- 此处应有连接日志,但实际无输出
后端Python WebSocket代码
# WebSocket endpoint with dynamic username path @app.websocket("/ws/{username}") async def websocket_endpoint(websocket: WebSocket, username: str): print("Waiting to accept a websocket connection...") await websocket.accept() print(f"Connected. Waiting for messages from user: {username}") while True: try: message = await websocket.receive_text() print(f"Received message from {username}: {message}") await websocket.send_text( f"Message from user: {username}." ) except WebSocketDisconnect: print(f"WebSocket connection closed for user: {username}") break
排查方向与解决方案
1. 检查后端Service端口映射
核心问题大概率是后端Service的端口未正确映射到Pod的8000端口:
Ingress配置中proxy_pass默认请求后端Service的80端口,但后端Pod的Uvicorn服务运行在8000端口。需确保对应Service的targetPort指向8000:
apiVersion: v1 kind: Service metadata: name: svc-testuser spec: selector: app: testuser ports: - name: http port: 80 targetPort: 8000
2. 清理Ingress配置中的冗余项
配置中重复设置了Upgrade和Connection头,虽不影响功能,但建议删除重复内容,优化后的server-snippets如下:
nginx.org/server-snippets: | resolver kube-dns.kube-system.svc.cluster.local valid=30s; location ~* "^/ws/(?<username>[^/]+)$" { if ($username ~ "[^a-zA-Z0-9_-]") { return 400; } set $service_name svc-$username; set $namespace default; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; 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 Origin ""; # 避免跨域相关问题 proxy_buffering off; proxy_cache_bypass $http_upgrade; proxy_pass http://$service_name.$namespace.svc.cluster.local; }
3. 验证NGINX Controller生成的配置
执行以下命令查看NGINX实际生效的配置,确认server-snippets中的location块已正确加载:
kubectl exec -it <nginx-controller-pod-name> -- cat /etc/nginx/nginx.conf
同时验证配置有效性:
kubectl exec -it <nginx-controller-pod-name> -- nginx -t
若配置有效,可重启NGINX Controller或触发配置重载。
4. 测试后端服务的可达性
在NGINX Controller Pod内执行WebSocket握手测试,确认后端服务能正常响应:
curl http://svc-testuser.default.svc.cluster.local/ws/testuser -i \ -H "Upgrade: websocket" \ -H "Connection: Upgrade" \ -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \ -H "Sec-WebSocket-Version: 13"
若后端正常,应返回101 Switching Protocols响应。
内容的提问来源于stack exchange,提问作者Francisco Aguilera
相关产品推荐
相关产品推荐

