Kubernetes Pod间通过主机名连接WebSocket服务遭拒绝
我几乎查遍了所有相关答案,咨询了多位同事,仍无法排查出配置问题。
WebSocket服务器代码
// additional fastify websocket set-up - key point, is its running on 5000 const start = async () => { try { await fastify.listen({ port: 5000 }); console.log( `Market data websocket listening on ws://localhost:5000` ); } catch (err) { fastify.log.error(err); process.exit(1); } }; start();
本地验证服务正常
使用wscat测试,连接完全正常:
wscat -c "ws://localhost:5000"
Deployment配置文件
apiVersion: apps/v1 kind: Deployment metadata: name: test spec: replicas: 1 selector: matchLabels: app: test strategy: type: Recreate template: metadata: labels: app: market-data-ws spec: containers: - name: market-data-ws image: eu.gcr.io/test-repo/market-data-ws envFrom: - secretRef: name: market-data-ws-env resources: limits: memory: '0.5' cpu: '0.25' ports: - containerPort: 5000 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5
Service配置文件
apiVersion: v1 kind: Service metadata: name: market-data-ws spec: type: ClusterIP selector: app: market-data-ws ports: - port: 80 targetPort: 5000
问题详情
尝试从另一Pod连接该服务(无需通过Ingress暴露),但遇到以下异常:
- 存活探针异常:Pod存活探针检测失败,但进入Pod内部调用
curl http://localhost:5000/healthz可正常返回{"hello":"im alive"}。 - 通过主机名连接被拒绝:在其他Pod中执行
curl http://market-data-ws/healthz,提示连接拒绝。 - 通过IP连接被拒绝:执行
curl 10.104.1.61:80/healthz,同样提示连接拒绝。 - 访问错误端口超时:执行
curl 10.104.1.61:5000/healthz,出现超时。 - 本地端口转发正常:执行
kubectl port-forward service/market-data-ws 5000:5000后,本地用wscat可正常连接。
已尝试的排查动作
- 进入
market-data-wsPod,用wscat验证服务运行正常。 - 反复核对containerPort/targetPort配置,同事确认无误。
- 尝试过
NodePort和ClusterIP类型的Service。 - 尝试将WebSocket服务器运行在80端口并暴露。
其他信息
- 使用GCP GKE环境
kubectl describe service market-data-ws输出内容翻译如下:名称: market-data-ws
命名空间: default
标签: <无>
注解: <无>
选择器: app=market-data-ws
类型: ClusterIP
IP协议策略: 单栈
IP版本: IPv4
IP: 10.104.1.61
IP列表: 10.104.1.61
端口: <未设置> 80/TCP
目标端口: 5000/TCP
端点: 10.48.0.19:5000
会话亲和性: 无
事件: <无>
问题排查与解决方案
1. 存活探针端口不匹配
Deployment中存活探针配置的port: 8080,但实际服务监听的是5000端口,且/healthz接口部署在5000端口上,直接导致探针检测失败,Pod反复重启影响Service后端可用性。
修复: 修改存活探针端口为5000:
livenessProbe: httpGet: path: /healthz port: 5000 initialDelaySeconds: 5
2. Deployment与Service标签不匹配
Deployment的spec.selector.matchLabels.app设为test,但Pod模板标签和Service选择器均为app=market-data-ws,会导致Service无法正确关联到Pod,出现Pod运行但未被纳入Service后端的情况。
修复: 统一Deployment选择器标签为market-data-ws:
spec: selector: matchLabels: app: market-data-ws
3. 服务绑定地址限制
Fastify默认仅绑定localhost(127.0.0.1),导致服务仅能在Pod内部访问,集群内其他节点或Service无法通过Pod的集群IP连接。需修改监听地址为0.0.0.0,允许所有来源访问:
await fastify.listen({ port: 5000, host: '0.0.0.0' });
验证步骤
- 应用修改后的配置:
kubectl apply -f deployment.yaml kubectl apply -f service.yaml
- 检查Pod状态及探针健康度:
kubectl get pods kubectl describe pod <pod-name> | grep Liveness
- 在其他Pod中测试HTTP接口:
curl http://market-data-ws/healthz
- 测试WebSocket连接:
wscat -c "ws://market-data-ws"
内容的提问来源于stack exchange,提问作者Daniel Cooke

