☰
Ingress 404 与 503 分别意味着什么:3 层转发里的失败点
2026/10/25 1:52:05 网站建设 项目流程

我不会起名字322· 后端 / 算法 / 数据库

📘 技术栈 | 🧩 力扣 Hot100 | 🐹 Go 项目 | 🟥 Redis | 🐬 MySQL

文章目录

  • Ingress 404 与 503 分别意味着什么:3 层转发里的失败点
    • 一、先把转发链路画出来
    • 二、404:规则没匹配上
      • 原因 1:host 不匹配
      • 原因 2:path 匹配规则和你想的不一样
      • 原因 3:IngressClass 不匹配
      • 原因 4:多个 Ingress 冲突 / 规则没被加载
    • 三、503:没有可用的后端
      • 第一步永远是看 Endpoint
      • 原因 1:selector 和 Pod 标签对不上
      • 原因 2:Pod 没有 Ready
      • 原因 3:端口对不上
      • 原因 4:全部后端被摘除(滚动发布期间)
    • 四、502:连上了但连接失败
    • 五、一个完整的排查流程
    • 六、带走物

Ingress 404 与 503 分别意味着什么:3 层转发里的失败点

一、先把转发链路画出来

Ingress 不是"一个组件",它至少跨三层:

外部流量 ↓ ① Ingress Controller(Nginx / Traefik / ALB) ↓ 按 host + path 匹配 Ingress 规则 ② Service(ClusterIP) ↓ 按 selector 找 Endpoint ③ Pod

404 和 503 分别对应这条链路上不同的失败位置,这是排查的第一分水岭。

状态码失败位置含义
404① Ingress 层规则根本没匹配上,流量没离开 Controller
503② Service 层规则匹配上了,但后端没有可用 Endpoint
502③ Pod 层连上了 Pod 但连接失败/被提前关闭

记住这个映射,排查时能省一半时间。

二、404:规则没匹配上

404 说明 Ingress Controller收到了请求,但找不到要转发给谁。它压根没往后走。

原因 1:host 不匹配

spec:rules:-host:api.example.com# 只认这个 hosthttp:paths:-path:/pathType:Prefixbackend:service:name:api-svcport:{number:8080}

如果你用curl http://<IP>/直接打 IP(不带 Host 头),host 是空的,不匹配任何规则 →404。

验证:

# 不带 Host → 404curl-ihttp://<ingress-ip>/# 带 Host → 正常curl-i-H"Host: api.example.com"http://<ingress-ip>/

原因 2:path 匹配规则和你想的不一样

pathType有三个取值,行为差别很大:

pathType行为
Exact完全相等才匹配
Prefix按路径前缀匹配(逐段,不是字符串前缀)
ImplementationSpecific取决于 Controller 实现(Nginx 下是正则)

Prefix是按/分段匹配的,不是字符串前缀:

path: /api Prefix ✅ /api 匹配 ✅ /api/v1 匹配 ❌ /apiary 不匹配(不是完整的一段)

这一点经常导致"路径看着像前缀但就是 404"。

原因 3:IngressClass 不匹配

集群里有多个 Ingress Controller 时,必须指定 class:

metadata:annotations:kubernetes.io/ingress.class:nginx# 旧写法spec:ingressClassName:nginx# 新写法(推荐)

没写或者写错了,这个 Ingress 会被 Controller 忽略,表现就是 404。

kubectl get ingressclass kubectl get ingress<name>-oyaml|grep-iclass

原因 4:多个 Ingress 冲突 / 规则没被加载

# 看 Ingress 有没有被 Controller 认领(看 ADDRESS 字段有没有值)kubectl get ingress-A# 看 Controller 日志里的 reloadkubectl logs-ningress-nginx deploy/ingress-nginx-controller|grep-i"reload\|error"

三、503:没有可用的后端

503 说明规则匹配上了,但Controller 找不到可用的 Pod 来转发。

第一步永远是看 Endpoint

kubectl get endpoints<service-name>-n<ns># 或者kubectl get endpointslices-n<ns>
NAME ENDPOINTS api-svc <none> ← 空的就是问题所在

ENDPOINTS为空 = Service 没有选中任何健康 Pod = 503。

原因 1:selector 和 Pod 标签对不上

# Service 选什么kubectl get svc api-svc-ojsonpath='{.spec.selector}'# Pod 实际有什么标签kubectl get pod-lapp=api --show-labels

最常见的就是app: api和app: api-server这种一字之差。

原因 2:Pod 没有 Ready

Endpoint 只收Ready的 Pod。Pod Running 但 NotReady 不会被加入。

kubectl get pod-lapp=api# NAME READY STATUS RESTARTS# api-0 0/1 Running 0 ← Running 但 0/1,NotReady

原因通常是readinessProbe 失败:

kubectl describe pod api-0|grep-A5Readiness# Readiness probe failed: HTTP probe failed with statuscode: 500

注意:readiness 失败不会重启 Pod,只会把它从 Service 摘掉。所以现象是"Pod 看着在跑,但访问 503"。

原因 3:端口对不上

# Servicespec:ports:-port:80targetPort:8080# 要和应用实际监听的端口一致

targetPort写错时,Endpoint 会有 IP 但端口不通。这种情况通常表现为 502 或连接超时,但部分 Controller 也会报 503。

# 确认 Pod 实际监听的端口kubectlexec<pod>-- ss-lntp

原因 4:全部后端被摘除(滚动发布期间)

滚动更新时旧 Pod 被终止、新 Pod 还没 Ready,会出现短暂的 503。

解法是配置优雅停机 + preStop,让旧 Pod 在退出前先等一会儿,等 endpoint 同步完成:

lifecycle:preStop:exec:command:["sh","-c","sleep 10"]# 给 endpoint 摘除留出时间terminationGracePeriodSeconds:40

关于这个时间差的完整机制在滚动更新那篇里详细讲过。

四、502:连上了但连接失败

502 说明 Controller 找到了 Pod 并尝试连接,但连接层面失败:

  • Pod 内的进程没监听那个端口;
  • 应用启动时就把连接关了;
  • keepalive 连接被复用但已被关闭。

排查重点是从 Controller 到 Pod 这一段:

# 直接打 Pod IP(绕过 Service,确认应用本身是否正常)kubectl get pod-owide# 拿到 Pod IPkubectl run-it--rmcurl--image=curlimages/curl--restart=Never --\curl-ihttp://<pod-ip>:8080/healthz
  • Pod IP 直接访问正常 → 问题在 Service/Endpoint 层;
  • Pod IP 也不通 → 问题在应用本身(端口、启动、崩溃)。

五、一个完整的排查流程

# 1. 看状态码,判断失败位置# 404 → Controller 层;503 → Service/Endpoint 层;502 → Pod 连接层# 2. 404:查规则kubectl get ingress<name>-oyaml# host / path / pathType / ingressClassNamecurl-i-H"Host: <host>"http://<ip>/# 带 Host 再试一次kubectl logs-ningress-nginx deploy/ingress-nginx-controller--tail=50# 3. 503:查 Endpointkubectl get endpoints<svc>kubectl get svc<svc>-ojsonpath='{.spec.selector}'kubectl get pod-l<selector>--show-labels kubectl describe pod<pod>|grep-A5Readiness# 4. 502:绕过 Service 直连 Podcurlhttp://<pod-ip>:<port>/healthz kubectlexec<pod>-- ss-lntp

六、带走物

状态码一句话定位第一个要看的命令
404Ingress 规则没匹配上(host / path / class)kubectl get ingress -o yaml
503规则匹配了但 Service 没有可用 Endpointkubectl get endpoints
502找到 Pod 但连接失败直连 Pod IP 验证
504Pod 连上了但响应超时查应用耗时

一句话结论:404 是"不知道往哪转",503 是"知道往哪转但没人接",502 是"有人但连不上"——状态码已经告诉你失败在第几层了,顺着那一层查就行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询