一、为什么我的Ingress总是返回404?
最近在帮朋友排查一个Kubernetes集群的问题,他的服务通过Ingress暴露后,客户端访问总是返回404错误。这让我想起刚接触Kubernetes时踩过的坑,今天就和大家聊聊这个常见问题的排查思路。
首先我们要明白,Ingress本质上是个"智能路由器",它需要三个关键部件协同工作:
- Ingress Controller(实际处理流量的组件)
- Ingress资源(路由规则定义)
- 后端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没起来。检查流程应该是:
- 检查Service的selector是否匹配Pod标签:
kubectl describe service/my-service
- 检查Pod是否正常运行:
kubectl get pods -l app=my-app
- 检查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错误。排查过程如下:
- 首先检查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已被删除
- 检查Service状态:
kubectl get svc product-service-v2
确认该Service确实不存在。
- 解决方案是回滚到之前的版本:
kubectl apply -f ingress-backup.yaml
五、预防措施与最佳实践
- 始终进行预检:
kubectl apply --dry-run=client -f ingress.yaml
kubectl get ingress --show-labels
使用Helm/Kustomize等工具管理配置,避免手动修改。
设置资源配额和健康检查:
resources:
limits:
cpu: "1"
memory: 512Mi
requests:
cpu: "0.5"
memory: 256Mi
livenessProbe:
httpGet:
path: /healthz
port: 8080
- 监控关键指标:
kubectl top pods -n ingress-nginx
六、总结与思考
通过这次排查,我总结了Ingress 404问题的"四步诊断法":
- 查Controller:是否安装且运行正常
- 查Ingress:规则是否正确,特别是host/path/service的对应关系
- 查Service:selector是否匹配Pod,端口是否正确
- 查Pod:是否运行正常,是否监听正确端口
记住,Kubernetes是个复杂的系统,但只要我们掌握正确的排查方法,就能快速定位问题。就像老医生看病,通过望闻问切就能知道问题所在。
评论