404错误说明请求抵达Ingress-NGINX Controller但未匹配路由规则;需依次验证Controller Pod状态、Service端口可达性、Ingress资源是否被识别(检查ingressClassName)、Host头是否送达、host/pathType精确匹配及Service端口一致性。

当你在Kubernetes集群外访问Ingress暴露的服务时,浏览器或curl返回“404 Not Found nginx/1.18.0 (ubuntu)”这类响应,说明请求已抵达Ingress-NGINX Controller进程,但Controller内部未匹配到任何有效路由规则——它不是网络不通,而是路由配置断在了最前端。
确认Ingress-Controller Pod是否真实运行
执行kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx,观察输出中Pod状态是否为Running且READY列为1/1。若出现CrashLoopBackOff或Pending,说明Controller根本没起来,后续所有排查都无意义。
如果Pod处于Running但READY为0/1,大概率是健康探针失败。此时必须立刻执行kubectl logs -n ingress-nginx ,重点查找controller.go:132或failed to list *v1.Ingress类报错——这往往意味着RBAC权限缺失或API Server连接异常。
验证Ingress-Controller Service端口可达性
先查Service暴露方式:kubectl get svc -n ingress-nginx ingress-nginx。若TYPE为NodePort,记下PORT(S)列中80:的值(如30677)。
在集群任意节点上执行curl -I http://localhost:。如果返回HTTP/1.1 200 OK,说明Controller监听正常;若返回Connection refused,证明Controller进程虽在运行,但未成功绑定端口——常见于容器内Nginx主进程崩溃后子进程残留,需删Pod强制重建。
【关键前提】此步骤必须在节点本地执行,不能用curl http://跨机器测试,否则可能受主机防火墙或云厂商安全组拦截干扰判断。
检查Ingress资源是否被Controller识别
执行kubectl get ingress -A,确认目标Ingress资源存在且命名空间正确。再运行kubectl get ingress ,观察ADDRESS列是否为空。若为空,代表Controller压根没处理该资源——90%是因为ingressClassName字段不匹配。
打开你的Ingress YAML,检查spec.ingressClassName值(如nginx)是否与Ingress-Controller部署时指定的--ingress-class-name参数或ingressclass资源名完全一致。Kubernetes 1.20+版本严格按此字段绑定,旧版注解kubernetes.io/ingress.class: nginx已失效。
若你用的是社区标准部署清单(如main/deploy/static/provider/cloud/deploy.yaml),默认IngressClass名为nginx。但若手动修改过部署文件却忘了同步更新Ingress定义,就会出现“资源存在却隐身”的现象。
抓包确认Host头是否送达Controller
方法一:进入Controller容器直接测试
执行kubectl exec -it -n ingress-nginx deploy/ingress-nginx-controller -- sh,进入后运行curl -H "Host: your-host.example.com" http://localhost/。若返回后端服务内容,证明Ingress规则本身有效,问题出在外部请求未携带正确Host头。
方法二:用tcpdump捕获真实流量
先给Controller Pod加临时权限(仅调试):kubectl patch deploy -n ingress-nginx ingress-nginx-controller --type=json -p='[{"op":"remove","path":"/spec/template/spec/securityContext/runAsUser"}]',再执行kubectl exec -n ingress-nginx ,然后从外部发起请求。若抓包结果里没有Host: your-host.example.com,说明前置LB或DNS解析层剥离了Host头——这时必须在Nginx反代配置中补上proxy_set_header Host $http_host;。
注意:tcpdump命令需容器内已安装,Alpine镜像默认不含此工具,可先用kubectl cp上传静态二进制或改用busybox:latest临时容器注入。
逐级验证Ingress规则匹配逻辑
第一步:确认host字段精确匹配
Ingress规则中的rules[].host必须与curl请求的-H "Host: xxx"或浏览器地址栏域名**完全一致**,包括大小写和末尾点号。例如example.com无法匹配www.example.com。
第二步:检查path路径类型与实际请求是否对齐
查看Ingress中pathType字段:若为Prefix,则path: /api会匹配/api/users和/api/,但不会匹配/apis;若为Exact,则只匹配/api字面量。v1.12.0+版本对pathType强制要求,留空将导致整个Ingress被Controller忽略。
第三步:验证backend service端口映射
执行kubectl get svc ,确认PORT列的端口号(如80)与Ingress中service.port.number值严格相等。常见错误是Service暴露端口为8080,而Ingress写成80,导致Controller尝试转发到不存在的端口,最终回退到默认404页。











