Administrator
Administrator
发布于 2026-10-28 / 0 阅读
0
0

Kubernetes 故障排查(12):Ingress 返回 404、502 或 503:先找到响应来自哪一层

面向初级运维,使用 Linux 节点和稳定 Kubernetes API。命令按 Bash 编写。本文为教学故障场景,日志及结果为示意,不冒充生产实测;执行前确认 context、命名空间和权限。

一、遭遇情况:Service 内部正常,域名访问却报错

应用通过集群内部 Service 能访问,外部入口却返回 404、502 或 503。有人马上回滚应用,也有人只盯着 Ingress YAML 的语法。

本篇主案例是直接访问入口 IP,没有携带规则要求的 Host,因此请求没有匹配预期虚拟主机。其他状态还可能来自入口控制器、外部负载均衡或应用本身,不能把所有 503 都等同于“Pod 不健康”。

二、原因分析:Ingress 资源本身不转发请求

Ingress 需要实际控制器读取规则并实施转发。资源创建成功,不代表有控制器接管;控制器接管,也不代表域名、证书和后端都正确。

Ingress 请求从入口到后端的排查顺序

不同控制器对默认路由、无后端和连接失败的状态码处理可能不同。本文维护已有 Ingress,不安装或推荐某个控制器;使用组织当前维护的控制器与对应版本文档。

三、排查思路:先确认谁返回了错误

kubectl get ingressclass
kubectl get ingress -n 目标命名空间 -o wide
kubectl describe ingress 目标入口 -n 目标命名空间
kubectl get service 目标后端 -n 目标命名空间 -o yaml
kubectl get endpointslice -n 目标命名空间 -l kubernetes.io/service-name=目标后端 -o yaml

核对入口地址是否是预期的负载均衡地址;IngressClass 是否存在并被实际控制器处理;Host 与 path 是否匹配;backend 引用的是 Service 的端口,而不是直接把容器端口填进去。

通过响应头、响应体、请求时间与控制器/应用访问日志定位哪一层响应。头部只能提供线索,不能单凭一个 Server 字段就断言根因。

四、实践:使用测试集群里已有的入口控制器

本实验要求控制器已安装并能访问,不会帮你安装集群组件。先获取实际 IngressClass,将下列 example-class 替换为已有且经过确认的 class 名。

保存 kt12-ingress.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: kt12
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: kt12
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:stable-alpine
          readinessProbe:
            httpGet:
              path: /
              port: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web
  namespace: kt12
spec:
  selector:
    app: web
  ports:
    - name: http
      port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web
  namespace: kt12
spec:
  ingressClassName: example-class
  rules:
    - host: app.example.test
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web
                port:
                  number: 80
kubectl apply -f kt12-ingress.yaml
kubectl rollout status deployment/web -n kt12 --timeout=120s
kubectl describe ingress web -n kt12

示例域名是保留测试名称,不要求公开 DNS。若控制器不支持或未配置 HTTP 入口,应按现有测试环境调整,不能假设创建资源就会自动出现公网负载均衡。

五、修复实践:让请求带上正确 Host

把下面的文档示例 IP 替换为真实、获准访问的测试入口 IP:

ingress_ip=192.0.2.10
curl -i --connect-timeout 3 --max-time 5 "http://$ingress_ip/"
curl -i --connect-timeout 3 --max-time 5 -H 'Host: app.example.test' "http://$ingress_ip/"

若已接管规则且后端正常,第二条应命中演示服务;第一条可能落到默认路由,常见为 404,但具体响应取决于控制器配置。修复是对齐请求域名与规则,不是给应用首页改状态码。

真实域名访问错误时,还要核对 DNS 是否解析到同一入口。HTTPS 需要同时考虑 SNI、证书与 Host,仅修改 HTTP Host 头不完整;可以在已有正确证书和 TLS 配置的前提下,用 curl 的 --resolve 保持正确域名进行定向测试,而不是关闭证书验证。

六、如果 Host 正确但仍然失败

回到 Service 与 EndpointSlice,检查就绪后端、Service port 与 targetPort。内部客户端访问后端也失败时,先修后端;内部正常而入口失败时,查控制器到后端的网络、策略和协议配置。

不要随便复制某控制器的 rewrite 注解。路径改写、上游 HTTPS 等能力属于具体实现,注解能被 API 接收不等于当前控制器会识别它。

七、验证与总结

在真实预期入口验证正确 Host、路径和业务响应,再核对错误 Host 不会误入该服务。TLS 场景还要验证证书信任与名称匹配,不能仅看页面能打开。

Ingress 的排查闭环是:响应来自哪里 → 谁接管规则 → 请求是否匹配 → Service 是否指向可用后端 → 控制器到应用是否畅通。状态码是起点,链路证据才决定修复位置。

官方参考


上一篇 · 系列目录 · 下一篇


评论