这种情况通常是 Service 的 targetPort 与容器实际监听端口不一致,或者 Nginx 只监听了容器内的 127.0.0.1 导致外部无法访问。
先说结论:优先检查 Service 定义中的 targetPort 是否与容器内 Nginx 监听端口一致,并确认 Nginx 配置未绑定 localhost。
- 先确认:Pod 状态为 Running 不代表网络可达,需检查端口监听情况
- 先处理:修正 Service 端口映射或 Nginx listen 配置
- 再验证:从集群内部和外部分别测试连通性
命令速用版
# 查看 Pod 所在节点和 IP
kubectl get pod <pod-name> -o wide
# 进入容器内部检查监听端口
kubectl exec -it <pod-name> -- netstat -tunlp
# 查看 Service 端口映射
kubectl get svc <svc-name> -o yaml为什么会这样
Kubernetes 中 Pod 就绪(Ready)仅表示存活探针通过,不保证网络端口正确开放。Connection refused 通常意味着请求到达了目标 IP,但目标进程没有在该端口监听。常见原因包括 Service 的 targetPort 写错了,或者 Nginx 配置文件里写死了 listen 127.0.0.1:80,导致只接受容器内部请求,拒绝来自 Service 网桥的流量。
分步处理
1. 检查容器内实际监听端口
使用 exec 进入容器,确认 Nginx 到底监听的是哪个端口和地址。
kubectl exec <pod-name> -- cat /etc/nginx/nginx.conf | grep listen如果看到 listen 127.0.0.1:80;,需要改为 listen 80; 或 listen 0.0.0.0:80;。
2. 核对 Service 端口配置
查看 Service 的 targetPort 是否匹配容器端口。
kubectl describe svc <svc-name>关注 Port 和 TargetPort 字段。TargetPort 必须等于容器内 Nginx 监听端口。
3. 检查 Endpoint 是否关联
如果 Service 没有关联到 Pod,流量无法转发。
kubectl get endpoints <svc-name>如果 ENDPOINTS 为空,检查 Pod 的 label 是否与 Service 的 selector 匹配。
怎么验证是否生效
集群内验证:创建一个临时 busybox Pod,尝试 curl Service 名称。
kubectl run -it `--rm` debug `--image`=busybox `--restart`=Never -- curl http://<svc-name>集群外验证:如果是 NodePort 或 LoadBalancer,使用节点 IP 或外部 IP 测试。
curl -v http://<node-ip>:<node-port>如果返回 HTTP 200 或 301/302 且无 Connection refused,则修复成功。
常见坑
- 容器端口定义缺失:Deployment yaml 中 containers.ports 未定义,虽不影响运行,但会影响部分网络策略工具识别。
- readinessProbe 误判:探针配置了错误的端口或路径,导致 Pod 状态 Ready 但实际服务未启动。
- NetworkPolicy 限制:集群启用了网络策略,默认拒绝所有入站流量,需显式允许。
参考来源
- Kubernetes 官方文档 - Concepts: Services, Load Balancing, and Networking https://kubernetes.io/docs/concepts/services-networking/service/
- Kubernetes 官方文档 - Debug Services https://kubernetes.io/docs/tasks/debug/debug-application/debug-service/