Kubernetes部署Nginx访问localhost:9090提示连接被拒问题咨询
问题环境
- 操作系统:Windows 10
- 预装运行环境:Kubernetes、Docker Desktop
故障复现过程
- 自定义镜像准备
- 启动官方Nginx容器验证运行正常后,修改默认index.html添加个人标识,构建自定义镜像
rk_nginx_base,本地运行验证正常 - 将镜像内Nginx服务默认监听端口从80修改为9090
- 启动官方Nginx容器验证运行正常后,修改默认index.html添加个人标识,构建自定义镜像
- Docker直连验证
通过Docker Desktop UI直接运行该自定义镜像,服务状态正常,浏览器访问http://localhost:9090可稳定加载页面,多次刷新无异常,Docker UI也提供可直接跳转的浏览器访问入口。 - K8s部署操作
编写Deployment资源YAML如下:
执行部署命令:apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: rk_nginx_base ports: - containerPort: 9090
部署后Docker UI中可看到对应工作负载处于启动状态。kubectl apply -f .\nginx-deployment.yaml
故障现象
首次访问http://localhost:9090可正常加载(判定为之前Docker直连运行时遗留的浏览器缓存),后续在Brave、Chrome、Edge浏览器刷新均访问失败,报错:
This site can’t be reached localhost refused to connect.
已尝试无效方案
- 在
containerPort配置项下方添加hostPort: 9090配置 - 创建NodePort类型Service暴露服务
- 执行
kubectl expose -f .\nginx-deployment.yaml命令暴露服务
排查步骤与解决方案
按从底层到上层的顺序逐一排查,不要跳过基础检查:
- 修复Deployment YAML语法错误
你当前使用的YAML存在缩进错误:spec.selector.matchLabels下的app: nginx和matchLabels字段同级,没有缩进,会导致Deployment的标签选择器失效,后续创建的Service也无法匹配到后端Pod,这是首要问题。修正后的selector段配置如下:
修改后重新执行selector: matchLabels: app: nginxkubectl apply命令部署。 - 校验Pod运行状态
执行以下命令查看Pod状态:kubectl get pods- 如果Pod状态不是
Running,执行kubectl describe pod <pod名称>查看事件报错。Windows Docker Desktop自带的K8s集群默认和本地Docker构建的镜像上下文不互通,本地build的rk_nginx_base镜像K8s无法拉取,会导致镜像拉取失败、Pod反复重启。这种情况需要在Docker Desktop的K8s设置中开启「将本地Docker镜像暴露给K8s集群」选项,重建镜像后重新部署。 - 如果Pod状态为
Running,执行端口转发命令直接绕过Service、kube-proxy链路,验证Pod内服务是否正常:
保持命令窗口不关闭,访问kubectl port-forward deployment/my-nginx 9090:9090http://localhost:9090,如果可以正常打开,说明Pod内Nginx服务运行正常,问题出在服务暴露链路;如果还是无法访问,进入Pod内部校验Nginx配置:
确认Nginx是否监听kubectl exec -it <pod名称> -- /bin/bash # 容器内执行以下命令 curl localhost:9090 netstat -tulpn | grep nginx0.0.0.0:9090,如果只监听127.0.0.1或者端口配置错误,修改Nginx配置后重建镜像即可。
- 如果Pod状态不是
- 排查服务暴露链路问题
你之前配置hostPort、创建NodePort Service无效,核心原因是Windows上Docker Desktop的K8s运行在虚拟化层内部,hostPort绑定的是虚拟机内部节点的端口,不是Windows物理主机的localhost端口,直接访问localhost自然会被拒绝。
校验Service配置时执行以下命令:kubectl get svc kubectl describe svc <service名称>- 确认Service的selector正确匹配到Pod标签,
targetPort配置为9090和容器内Nginx监听端口一致 - 如果是ClusterIP类型Service,本身无法直接从Windows主机访问,必须通过port-forward或者Ingress转发
- 如果是NodePort类型Service,注意NodePort默认端口范围是30000-32767,无法直接指定9090作为NodePort,需要访问
节点IP:分配的NodePort,但由于Docker Desktop的网络隔离,该IP通常也无法直接从Windows主机访问,本地开发场景不推荐用这种方式。
- 确认Service的selector正确匹配到Pod标签,
- 本地开发场景最快可用方案
不需要折腾复杂的网络配置,直接使用kubectl port-forward做流量转发即可稳定访问,执行命令后保持窗口运行,就可以通过http://localhost:9090正常访问服务:
如果需要长期本地访问,可以部署Ingress Controller配合本地hosts配置做流量转发,适配多服务开发场景。kubectl port-forward deployment/my-nginx 9090:9090
内容的提问来源于stack exchange,提问作者Richard Keene
相关产品推荐
相关产品推荐

