Kubernetes Ingress 404 错误排查:Host 规则与 TLS 配置实战

主题: kubernetes-ingress-404-path-rewrite更新于: 2026/7/28作者:AgentFactory 技术团队

快速答案

  • 核心结论:Kubernetes Ingress 返回 404 错误,绝大多数情况下是 Host 规则不匹配或 TLS Secret 配置错误导致,而非后端服务本身故障。
  • 第一检查项:执行 kubectl describe ingress <ingress-name> -n <namespace>,查看 Events 和 Rules 部分是否有 default backend: 404no matching host 提示。
  • 最小修复命令:确认 Ingress 的 spec.rules[].host 与客户端请求域名完全一致(含子域名),并确保 spec.tls[].secretName 引用的 Secret 存在于同一命名空间且包含有效的 tls.crttls.key
  • 适用环境边界:本文方法适用于所有 Kubernetes 集群(v1.19+),但具体命令和注解(如 kubernetes.io/ingress.class: nginx)依赖于 NGINX Ingress Controller。若使用 AWS ALB、Traefik 等其他控制器,需参考对应文档调整。

它解决什么问题

当你在 Kubernetes 集群中通过 Ingress 暴露服务时,可能会遇到以下场景:

  • 后端 Pod 正常运行(可通过 kubectl port-forward 直接访问),但通过 Ingress 域名访问时返回 404。
  • 配置了 TLS 证书,但 HTTPS 访问返回 404,而 HTTP 访问正常。
  • 多个 Ingress 资源定义了相同的 Host,导致路由冲突。
  • 需要快速定位 Ingress 配置错误,而不是逐一排查后端服务。

本文提供一套标准化的排查流程,聚焦于 Ingress 资源本身的 YAML 配置正确性,而非后端服务问题。

核心排查步骤

1. 检查 Ingress 资源状态

BASH
kubectl describe ingress <ingress-name> -n <namespace>

重点关注输出中的以下部分:

  • Rules:检查 Host 字段是否与客户端请求的域名完全匹配(包括子域名,如 api.example.comexample.com 不同)。
  • Events:查看是否有 WarningError 事件,例如 secret "myapp-tls-secret" not found
  • Default backend:如果显示 default backend: 404,说明没有匹配到任何规则,且未配置默认后端。

2. 验证 TLS Secret

BASH
kubectl get secret <secret-name> -n <namespace> -o yaml

检查要点:

  • Secret 必须与 Ingress 位于同一个命名空间
  • 数据字段必须包含 tls.crttls.key,且为 Base64 编码。
  • 证书是否过期:kubectl get secret <secret-name> -n <namespace> -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates
  • 如果使用 cert-manager,检查 Certificate 资源状态:kubectl describe certificate <cert-name> -n <namespace>

3. 检查 Ingress 控制器日志

BASH
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller --tail=100

搜索关键词:404no hostsecret not foundSSL。日志中通常会包含更详细的错误原因,例如:

2025/01/15 10:00:00 [error] 1234#1234: *5678 no live upstreams while connecting to upstream, client: 10.0.0.1, server: app.example.com, ...

4. 验证后端 Service 与 Pod 连通性

BASH
kubectl get endpoints <service-name> -n <namespace>

如果 Endpoints 为空,说明 Service 的标签选择器没有匹配到任何 Pod。此时需要检查:

  • Pod 标签:kubectl get pods -n <namespace> --show-labels
  • Service 选择器:kubectl describe service <service-name> -n <namespace>
  • Pod 就绪探针:kubectl describe pod <pod-name> -n <namespace>,查看 Conditions 中的 Ready 状态。

常见报错与排查

报错信息可能原因解决命令/步骤
default backend: 404无匹配的 Host 规则检查 spec.rules[].host 是否与请求域名一致
secret "xxx" not foundTLS Secret 不存在或命名空间错误kubectl get secret xxx -n <namespace> 确认存在
no matching hostHost 规则冲突或未定义检查是否有多个 Ingress 定义了相同 Host
HTTPS 返回 404,HTTP 正常TLS 配置错误或证书不匹配检查 spec.tls[].hosts 是否包含访问域名
后端 Pod 日志无请求流量未到达 Pod检查 Service Endpoints 和 Pod 就绪探针

详细解决方案

场景 1:Host 规则不匹配

BASH
# 查看当前 Ingress 的所有 Host
kubectl get ingress <ingress-name> -n <namespace> -o jsonpath='{.spec.rules[*].host}'

# 检查是否有其他 Ingress 占用相同 Host
kubectl get ingress --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.spec.rules[*].host}{"\n"}{end}' | grep <your-host>

场景 2:TLS Secret 缺失或错误

BASH
# 创建正确的 TLS Secret(使用现有证书)
kubectl create secret tls myapp-tls-secret \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key \
  -n <namespace>

# 验证 Secret 内容
kubectl get secret myapp-tls-secret -n <namespace> -o yaml | grep -E "tls\.(crt|key):"

场景 3:Ingress 控制器未正确选择

YAML
# 确保 Ingress 资源指定了正确的 Ingress Class
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    kubernetes.io/ingress.class: nginx  # 对于 NGINX Ingress Controller
spec:
  ingressClassName: nginx  # Kubernetes 1.18+ 推荐方式
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app-service
            port:
              number: 80

生产环境实践与注意事项

1. Ingress API 已冻结

Kubernetes 官方已推荐使用 Gateway API 替代 Ingress。虽然 Ingress 仍受支持且稳定,但不会再有新功能。对于新项目,建议评估 Gateway API。

2. Ingress 控制器依赖

不同的 Ingress 控制器对注解、功能支持和行为有差异。例如:

  • NGINX Ingress Controller:使用 kubernetes.io/ingress.class: nginx 注解。
  • AWS ALB Ingress Controller:使用 kubernetes.io/ingress.class: alb 注解,TLS 通过 alb.ingress.kubernetes.io/certificate-arn 引用 ACM 证书。
  • Traefik:使用 traefik.ingress.kubernetes.io/router.entrypoints: websecure 等注解。

3. TLS 证书管理

  • 证书过期:TLS Secret 中的证书会过期,需要自动化管理(如 cert-manager)。
  • 证书链:确保 Secret 中包含完整的证书链(包括中间证书),否则某些客户端可能报错。
  • Secret 命名空间:TLS Secret 必须与 Ingress 资源位于同一个命名空间。

4. 安全建议

YAML
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: secure-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"  # 强制 HTTPS
    nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8, 172.16.0.0/12"  # IP 白名单
spec:
  tls:
  - hosts:
    - app.example.com
    secretName: myapp-tls-secret
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app-service
            port:
              number: 80

5. 性能考虑

Ingress 控制器是集群内的关键组件,需要配置合适的资源限制和副本数:

YAML
# NGINX Ingress Controller 资源建议
resources:
  requests:
    cpu: 100m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 1Gi
replicas: 2  # 生产环境建议至少 2 个副本

常见问题 FAQ

Q: 我已经按照文档修复了 Host 和 TLS 配置,但 Ingress 仍然返回 404,可能是什么原因?

A: 除了 Host 和 TLS 配置外,还有其他常见原因:

  1. 后端 Service 问题:检查 kubectl get endpoints <service-name> 是否返回了 Pod IP。如果为空,说明 Service 的标签选择器没有匹配到任何 Pod。
  2. Pod 未就绪:检查 Pod 的 readinessProbe 是否通过。如果 Pod 未就绪,Ingress 控制器不会将流量路由到它。
  3. Ingress 控制器问题:确认 Ingress 控制器 Pod 正在运行,并且没有资源限制或崩溃循环。
  4. 路径匹配问题:检查 pathTypepath 是否与客户端请求的路径匹配。例如,pathType: Exact 要求路径完全匹配。
  5. 网络策略:检查是否有 NetworkPolicy 阻止了 Ingress 控制器到后端 Pod 的流量。

Q: 如何为多个域名配置同一个 Ingress?

A: 可以在 Ingress 的 spec.rules 下定义多个 host 条目,每个 host 下可以有不同的路径和后端。示例:

YAML
spec:
  rules:
  - host: app1.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80
  - host: app2.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app2-service
            port:
              number: 80

注意:如果使用 TLS,需要在 spec.tls 中为每个域名配置对应的 Secret。

Q: 我使用的是 AWS ALB Ingress Controller,这个排查方法还适用吗?

A: 核心排查思路(检查 Host 规则、TLS Secret、Service 映射)是通用的,但具体命令和细节会有所不同:

  1. Ingress 类名:AWS ALB 使用 kubernetes.io/ingress.class: albspec.ingressClassName: alb
  2. TLS 配置:AWS ALB 通常通过 alb.ingress.kubernetes.io/certificate-arn 注解引用 AWS Certificate Manager (ACM) 的证书 ARN,而不是 Kubernetes Secret。
  3. 调试命令:使用 kubectl describe ingress 仍然有效,但查看 ALB 控制器日志的命令是 kubectl logs -n kube-system deploy/aws-load-balancer-controller
  4. 后端服务:AWS ALB 要求后端 Service 类型为 NodePortLoadBalancer

建议始终查阅特定 Ingress 控制器的官方文档。

官方参考

相关深度解决方案

在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Kubernetes 探针配置实战:从入门到生产级自愈方案

在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Kubernetes CrashLoopBackOff 排查实战:从症状到根因的完整路径