一、为什么我的Ingress总是返回404?

最近在帮朋友排查一个Kubernetes集群的问题,他的服务通过Ingress暴露后,客户端访问总是返回404错误。这让我想起刚接触Kubernetes时踩过的坑,今天就和大家聊聊这个常见问题的排查思路。

首先我们要明白,Ingress本质上是个"智能路由器",它需要三个关键部件协同工作:

  1. Ingress Controller(实际处理流量的组件)
  2. Ingress资源(路由规则定义)
  3. 后端Service(实际处理请求的Pod)

当出现404时,通常意味着这个链条的某个环节断了。就像快递送错了地址,我们需要沿着物流路线一个个检查。

二、典型故障场景与排查步骤

场景1:Ingress Controller未正确安装

这是新手最容易犯的错误。很多人以为创建了Ingress资源就完事了,其实还需要先安装Ingress Controller。

检查方法很简单:

kubectl get pods -n ingress-nginx  # 检查Nginx Ingress Controller是否运行

如果没有运行,可以这样安装(以Nginx Ingress为例):

# 使用Helm安装
helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace

场景2:Ingress规则配置错误

这是404错误最常见的原因。来看个典型错误示例:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: faulty-ingress
spec:
  rules:
  - host: "myapp.example.com"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: non-existent-service  # 这里引用了不存在的Service
            port:
              number: 80

正确的配置应该是:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: correct-ingress
spec:
  rules:
  - host: "myapp.example.com"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: actual-backend-service  # 确保Service存在
            port:
              number: 80

场景3:Service与Pod选择器不匹配

有时候Ingress和Service都配置正确,但Service背后的Pod没起来。检查流程应该是:

  1. 检查Service的selector是否匹配Pod标签:
kubectl describe service/my-service
  1. 检查Pod是否正常运行:
kubectl get pods -l app=my-app
  1. 检查Pod是否注册了正确的端口:
kubectl get endpoints my-service

三、高级调试技巧

方法1:直接访问Service

绕过Ingress直接测试Service:

# 获取ClusterIP
kubectl get service/my-service

# 在集群内测试
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- curl http://<cluster-ip>:80

方法2:检查Ingress Controller日志

查看Nginx Ingress的实时日志:

kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=50 -f

方法3:使用Ingress的调试注解

Nginx Ingress支持调试注解:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      set $debug_header "Debug info: $host$request_uri";
      add_header X-Debug $debug_header;

然后在响应头中就能看到调试信息。

四、实际案例解析

最近遇到的一个真实案例:某电商网站在促销期间突然出现404错误。排查过程如下:

  1. 首先检查Ingress规则:
kubectl get ingress -o yaml

发现配置看似正常,但进一步检查发现:

spec:
  rules:
  - host: store.example.com
    http:
      paths:
      - path: /api/v1/products
        backend:
          service:
            name: product-service-v2  # 实际上这个Service已被删除
  1. 检查Service状态:
kubectl get svc product-service-v2

确认该Service确实不存在。

  1. 解决方案是回滚到之前的版本:
kubectl apply -f ingress-backup.yaml

五、预防措施与最佳实践

  1. 始终进行预检:
kubectl apply --dry-run=client -f ingress.yaml
kubectl get ingress --show-labels
  1. 使用Helm/Kustomize等工具管理配置,避免手动修改。

  2. 设置资源配额和健康检查:

resources:
  limits:
    cpu: "1"
    memory: 512Mi
  requests:
    cpu: "0.5"
    memory: 256Mi
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  1. 监控关键指标:
kubectl top pods -n ingress-nginx

六、总结与思考

通过这次排查,我总结了Ingress 404问题的"四步诊断法":

  1. 查Controller:是否安装且运行正常
  2. 查Ingress:规则是否正确,特别是host/path/service的对应关系
  3. 查Service:selector是否匹配Pod,端口是否正确
  4. 查Pod:是否运行正常,是否监听正确端口

记住,Kubernetes是个复杂的系统,但只要我们掌握正确的排查方法,就能快速定位问题。就像老医生看病,通过望闻问切就能知道问题所在。