Kubernetes Ingress 404 错误排查:Host 规则与 TLS 配置实战
快速答案
- 核心结论:Kubernetes Ingress 返回 404 错误,绝大多数情况下是 Host 规则不匹配或 TLS Secret 配置错误导致,而非后端服务本身故障。
- 第一检查项:执行
kubectl describe ingress <ingress-name> -n <namespace>,查看 Events 和 Rules 部分是否有default backend: 404或no matching host提示。 - 最小修复命令:确认 Ingress 的
spec.rules[].host与客户端请求域名完全一致(含子域名),并确保spec.tls[].secretName引用的 Secret 存在于同一命名空间且包含有效的tls.crt和tls.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 资源状态
BASHkubectl describe ingress <ingress-name> -n <namespace>
重点关注输出中的以下部分:
- Rules:检查
Host字段是否与客户端请求的域名完全匹配(包括子域名,如api.example.com与example.com不同)。 - Events:查看是否有
Warning或Error事件,例如secret "myapp-tls-secret" not found。 - Default backend:如果显示
default backend: 404,说明没有匹配到任何规则,且未配置默认后端。
2. 验证 TLS Secret
BASHkubectl get secret <secret-name> -n <namespace> -o yaml
检查要点:
- Secret 必须与 Ingress 位于同一个命名空间。
- 数据字段必须包含
tls.crt和tls.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 控制器日志
BASHkubectl logs -n ingress-nginx deploy/ingress-nginx-controller --tail=100
搜索关键词:404、no host、secret not found、SSL。日志中通常会包含更详细的错误原因,例如:
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 连通性
BASHkubectl 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 found | TLS Secret 不存在或命名空间错误 | kubectl get secret xxx -n <namespace> 确认存在 |
no matching host | Host 规则冲突或未定义 | 检查是否有多个 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. 安全建议
YAMLapiVersion: 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 配置外,还有其他常见原因:
- 后端 Service 问题:检查
kubectl get endpoints <service-name>是否返回了 Pod IP。如果为空,说明 Service 的标签选择器没有匹配到任何 Pod。 - Pod 未就绪:检查 Pod 的
readinessProbe是否通过。如果 Pod 未就绪,Ingress 控制器不会将流量路由到它。 - Ingress 控制器问题:确认 Ingress 控制器 Pod 正在运行,并且没有资源限制或崩溃循环。
- 路径匹配问题:检查
pathType和path是否与客户端请求的路径匹配。例如,pathType: Exact要求路径完全匹配。 - 网络策略:检查是否有 NetworkPolicy 阻止了 Ingress 控制器到后端 Pod 的流量。
Q: 如何为多个域名配置同一个 Ingress?
A: 可以在 Ingress 的 spec.rules 下定义多个 host 条目,每个 host 下可以有不同的路径和后端。示例:
YAMLspec: 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 映射)是通用的,但具体命令和细节会有所不同:
- Ingress 类名:AWS ALB 使用
kubernetes.io/ingress.class: alb或spec.ingressClassName: alb。 - TLS 配置:AWS ALB 通常通过
alb.ingress.kubernetes.io/certificate-arn注解引用 AWS Certificate Manager (ACM) 的证书 ARN,而不是 Kubernetes Secret。 - 调试命令:使用
kubectl describe ingress仍然有效,但查看 ALB 控制器日志的命令是kubectl logs -n kube-system deploy/aws-load-balancer-controller。 - 后端服务:AWS ALB 要求后端 Service 类型为
NodePort或LoadBalancer。
建议始终查阅特定 Ingress 控制器的官方文档。
官方参考
相关深度解决方案
在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Kubernetes 探针配置实战:从入门到生产级自愈方案。
在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Kubernetes CrashLoopBackOff 排查实战:从症状到根因的完整路径。